Boost logo

Boost :

From: Robert Ramey (ramey_at_[hidden])
Date: 2005-09-05 10:09:37


martin.ecker_at_[hidden] wrote:
> Hi,
>
> <snip my comments on how to make sure all the global objects, such as
> type info and void caster objects, are always unique in a process>
>
> Robert Ramey wrote:
>> Wouldn't this require that the first DLL loaded be the last one to be
>> unloaded?
>
> No. The order of loading/unloading DLLs doesn't matter. The first time
> a DLL is loaded that contains a BOOST_CLASS_EXPORT (and with it a
> number of global objects, such as type info), the global objects that
> need to be registered with the global registries and maps are created
> for the first time. Since they are reference counted, these process-
> wide unique, global objects only get destroyed when the last reference
> to them is released - for example, when the last DLL that uses them
> gets unloaded.

What I'm worried about are the virtual function calls routed through the
base class vtable. The first object created has addresses in its vtable
which point to the DLL that loaded it. Multiple entries would have
different vtables each pointing to an address in a different DLL. If one
DLL gets unloaded but the vtable remains in memory one is going to get a
crash (if you're lucky) when makinga call through that base class instance.
Hence my view that the first DLL to be loaded would have to be the last
unloaded.

>>> then -with the current use of (effectively global) static member
>>> variables in e.g. pointer_iserializer - you _will_ get multiple
>>> objects registered in the global registries and maps. There's
>>> nothing you can do about that (at least not on Windows; I believe
>>> with the Linux loader this problem does not occur). Throwing an
>>> exception if this happens, makes using Boost.Serialization with
>>> DLLs impossible.

>>
>> This would make it an illegal detectable error to include the
> serialization
>> of a given type in different DLLS and have those DLLS simultaneously
>> loaded.
>
> But there's nothing you can do about it. As soon as serialization
> code, in particular some global objects such as type info, are in a
> header file and that header file is included in code in multiple DLLs,
> you _will_ definitely get multiple copies of these objects (on Windows
> at least).

Its not clear to me that its an unavoidable problem. Just including the
header for a serializable type won't trigger inclusion of the indicated
static variables. One has to include archive code and instantiate it for
the specific serializable type by invoking and << or >> operator on it. I
don't believe the problem would ever arise if archve headers were included
in only one DLL.

> That's why my proposal is to let these global objects only
> be some kind of smart reference and have the "real" global objects
> that need to be unique for the running process be created by the
> Boost.Serialization DLL only once. Currently they are potentially
> created multiple times in the above scenario (i.e. serialization code
> in a header file that is included by code in multiple DLLs).

I understand the proposal. I don't think it would completely address the
problem.

>>> Although its a user issue, I would think that including the same
>>> code
> in
>>> different DLLS which are to be simultaneiously loaded defeats the
>>> whole
>
>>> point of DLLS in the first place - to avoid having memory loaded
>>> with
> dead
>>> (or sleeping) code.
>
> I agree with this. But because of the way the Windows DLL loader works
> in combination with global variables declared in C++ header files that
> are included by code in multiple DLLs, you cannot prevent having
> multiple instances of global variables.

This is what I'm not so sure about. However, avoid the problem would
require some attention to code module organization which could be a problem
for some people.

Robert Ramey


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