Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-103355

Add QIntrusiveSharedPointer as a pimpl-pointer to to rule them all

    XMLWordPrintable

Details

    • QIntrusiveSharedPointer

    Description

      We currently have two smart pointer classes which are deigned to be intrusive shared pointers: QSharedDataPointer and QExplicitlySharedDataPointer.

      They're both less than perfect:

      • QSharedDataPointer detaches too early, as in
        if (d->name == name) // detaches! (but shouldn't)
            return;
        d->name = name; // checks ref-count again (pointlessly)
        
      • In Qt 5, even this would detach already: if (d) (fixed in Qt 6)
      • it also checks the ref-count on every access
        • atomic operation bloat
          • needlessly increasing TEXT size and
          • acting as powerful optimizer firewalls
      • QExplicitlySharedDataPointer doesn't propagate constness
        • while this isn't a-priori expected from a smart pointer, it kind of is from a pimpl_ptr
        • has led to race conditions in at least QDateTime
      • both classes have a non-explicit operator bool(), which is dangerous, because it enables arithmetic and integer promotion on the result
      • both classes also use QAtomicInt's ref()/deref(), which are infamously inefficient:
        • ref() is ordered, but could be relaxed (can't be fixed, because it's documented like that)
        • deref() is ordered, but would only need an acquire fence when the count drops to zero

      Qt prides itself on its backward-compatibility, so we can't fix any of these without breaking user code (the addition of QSharedDataPointer::operator bool() to fix the detach in if (d) probably broke some users already).

      The most sensible solution, then, is to introduce a new smart pointer that does not have these problems, and slowly phase out the old classes from Qt code until they can be moved to Qt6Compat come Qt 7.

      This is what QIntrusiveSharedPointer sets out to do. An additional design goal is to enable classes that use QIntrusiveSharedPointer to = default all special member functions inline:

      • default ctor (sets d = nullptr)
      • copy/move ctors
      • copy/move assignment operators
      • dtor

      provided they implement a part of the "Intrusive Protocol" out-of-line:

      • qIntrusiveRef()
      • qIntrusiveMaybeDelete()

      mmutz already started the implementation in 2019:

      Attachments

        No reviews matched the request. Check your Options in the drop-down menu of this sections header.

        Activity

          People

            cnn Qt Core & Network
            mmutz Marc Mutz
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated:

              Gerrit Reviews

                There are no open Gerrit changes