Boost logo

Boost :

Subject: Re: [boost] [shared_ptr] A smarter smart pointer proposal for dynamic libraries
From: Andrey Semashev (andrey.semashev_at_[hidden])
Date: 2008-12-24 13:09:46


J.D. Herron wrote:
> I have a suggestion for the shared pointer implementation to overcome a
> severe limitation it has currently regarding dynamically unloaded
> libraries.

[snip]

> The basic problem is that the shared_ptr implementation uses virtual
> functions in the sp_counted_base class that gets generated in the factory
> dll since it is a template instantiation and once that factory dll is
> unloaded the virtual function tables for all shared_ptrs it generated are
> now garbage. In my opinion the virtual function implementation in the
> template is an unnecessary design flaw that creates this limitation. I also
> think the reference counter just simply does too much. I would propose an
> alternative design that eliminated the use of virtual functions in template
> generated base classes and let the outer smart pointer class handle the
> deallocation chores and make the reference counter just a simple reference
> counter. This could eliminate the limitation illustrated in this simple and
> very common use case. Ignoring a bunch of stuff right now like custom
> deallocators, weak references, some basic members like assignment, etc.,
> here is a simple reference counted smart pointer that is able to handle this
> library unloading example without a problem just as you could do with a raw
> pointer:

[snip]

> Again the key is no VTABLE and deallocation handled by the exposed
> templates. Why shouldn't shared_ptr move to an equivalent model so it can
> be used across dynamic dll boundaries safely?

You answered this question yourself - this approach ignores custom
allocators and deleters, which cannot be supported without virtual
functions or equivalent. I would not trade these features for better
support for DLLs and I'm sure there are others who share this opinion.
So, I don't think that chopping away current (and widely used)
functionality for sake of this improvement is the right direction to go.

There are different solutions for your problem, some of them were shown
by others (like controlling DLL life time with shared_ptrs). For
example, you can use intrusive_ptr for reference counting without
virtual functions and, in fact, additional memory allocation. Or, if you
don't like the intrusive approach, you can construct shared_ptrs in the
inline functions in the factory interface:

   struct Factory
   {
     shared_ptr< Object > Create()
     {
        return shared_ptr< Object >(CreateImpl());
     }

   private:
     virtual Object* CreateImpl() = 0;
   };

But this will only save you if the calling DLL stays loaded (the factory
DLL need not to).


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk