[Development] QIntrusiveSharedPointer (was: Re: atomic reference counting implementation)

Philippe philwave at gmail.com
Thu Aug 8 09:29:47 CEST 2019


Looks good, except that your proposed qIntrusiveDetached()
has (apparently) the same "uncertainty" that caused shared_ptr::unique()
to be deprecated.
https://en.cppreference.com/w/cpp/memory/shared_ptr/unique

Philippe

On Wed, 07 Aug 2019 23:09:54 +0300
"Mutz, Marc via Development" <development at qt-project.org> wrote:

> On 2019-08-07 22:01, Konstantin Tokarev wrote:
> > It would be even better if it was possible to choose type of reference 
> > counting,
> > e.g. via template parameter. In many cases atomic counters are not 
> > needed
> > and just reduce performance.
> 
> On 2019-08-07 21:46, Philippe wrote:
> > On Wed, 07 Aug 2019 21:00:30 +0300
> > "Mutz, Marc" <marc at kdab.com> wrote:
> [...]
> >>> I think I'm on record saying such impl details as ref-counting for Qt 
> >>> implicitly shared classes
> >>> should not be public API. This is a perfect example of why I believe 
> >>> that to be fundamentally true.
> > 
> > +1
> 
> I have just uploaded my proposed solution for this: 
> QIntrusiveSharedPointer. Even though I didn't have a) taking Qt pimpl 
> private and b) allowing non-atomic ref counts use-cases in mind when I 
> designed it, it supports these use-cases out of the box. I think its 
> design will satisfy all the constraints, even though I'd like to see a 
> round of internal use first (5.14, or, more likely by now 5.15, make 
> public in Qt 6):
> 
> - provide a public replacement for 
> QSharedDataPointer/QExplicitlySharedDataPointer with all their (known) 
> shortcomings fixed
> 
> while at the same time:
> 
> - allow Qt to use it's own private reference counting (by having 
> qshareddatav2_p.h and the Intrusive Protocol implemented like for 
> QSharedData); I haven't implemented a QSDV2, yet, but off the top of my 
> head the ref-counting is always out-of-line, so it's possible to 
> retrofit it into already-released classes
> 
> - allow users to use a simple int as ref-count
> 
> This is an evolution of 
> https://codereview.qt-project.org/c/qt/qtbase/+/115213 and it has all 
> the benefits of QtPrivate::SharedDataPointer to, to wit:
> 
> - it's possible to have an inline move ctor:
> 
> just need to export an out-of-line overload of 
> qIntrusiveDeref(QXXXPrivate*), which can call 
> qIntrusiveDeref<QXXXPrivate>() if Private is derived from a supported 
> QSharedData-alike
> 
> - in the same way, even the dtor can be inline
> - it's even possible to have all special member functions = default'ed
> 
> by exporting qIntrusiveRef() in addition. This reduces the number of DLL 
> entry points from 4 (default, copy ctor/assignment op, dtor) to two 
> (qIntrusive(De)ref()).
> 
> - const propagating
> - explicit detach
> - proper conversion to bool (unlike QSDP, which detaches, making every 
> if (mutable d) tautological)
> 
> It also adds
> 
> - constexpr default ctor and ctor from nullptr
> - implicit ctor from nullptr (but explicit from T*)
> 
> Which means that on conforming compilers (not MSVC) a static QISP 
> init'ed to nullptr will be placed into the BSS segment and not cause 
> dynamic initialisation (even if the dtor is not trivial - the std::mutex 
> principle).
> 
> The only drawback over QtPrivate::SharedDataPointer is that you need to 
> manually declare and implement qIntrusiveRef() and qIntrusiveDeref(); we 
> can't hide it in (one) macro. But I think that's a benefit. It reduces 
> the number of DLL entry points over the static-Public-member-functions 
> design of QtP::SDP, which is probably the reason it consistently 
> produces less executable code than QSDP, QESDP and not more code than 
> QtP::SDP did (which sometimes, e.g. for QCommandLineArgument, increased 
> text size a bit).
> 
> Flame away...
> 
> Thanks,
> Marc
> _______________________________________________
> Development mailing list
> Development at qt-project.org
> https://lists.qt-project.org/listinfo/development





More information about the Development mailing list