
Dave Abrahams wrote:
On Fri, Dec 10, 2010 at 12:35 PM, Robert Ramey
wrote: In the current implementation, the various serializers are instantiated, through a singleton, at the point of use. If two classes from two different DLLs have a member of a certain type, both DLLs will instantiate singletons for serializers.
This is the behavior of all current compiler/linker combinations.
Mostly just on Windows, though Linux has its own quirks that come up when you use dlopen().
Hmmm - that is a huge surprise to me. My normal method is to develop on windows (I love the MS IDE/Debugger), then run tests with cygwin then upload to the trunk and watch the linux results. The last round of development included tests of DLLs and everything worked as expected so I had assumed that I had the correct understanding of what compilers and linkers do under linux. Also, I reasoned that since each DLL (shared library) is built and linked independently, the behavior I observed in windows where each DLL initializes it's own statics, would have to be the same for all shared library setups. I conceded this is a guessing game - but I'm not sure what else to do.
It is not addressable from within a library or application.
Well, yes and no. Given the current structure of Boost.Serialization, it's definitely a problem that only the library integrator can solve, by structuring his application appropriately.
That's my understanding as well.
However, if you were willing to change the structure of Boost.Serialization, you could have all those DLLs link to a common DLL which is where the singletons are "registered" (you could create them there for a reduction in overall code size, but I assume you want to keep that DLL as lightweight as possible). You'd have to explicitly *not* deliver that common DLL as a static library.
Just to clarify things (maybe): The serialization library fits into one library. (the wide character version fits in another but depends up the first one. As I remember, the DLL contains no static initializers and there for no singletons. The problem come when a user puts serialization code inside his own DLL. This instantiates template code which in turn provokes the creation of certain static objects which are used for things like tracking of some object types. There is a set of static objects for each execution module (dll or exe). When serialization is invoked from different modules, a "singleton" is created for each module and this can lead to ambiguities. I'm sure you know this, I'm just stating for the benefit of other which might be reading this thread. So, I see the conflict coming not from the serialization DLL but rather from conflict between the user's execution modules. I can't see how any restructuring the the serialization library could address this. My advice is that the user's DLLs should/must be structured to avoid this problem. I believe that in doing this, the users code will likely avoid repetition of other code between his modules as well (assuming he's using templated code). So likely it's a good thing anyway. My preferred solution is to: a) clarify/document the circumstances under which this can occur. b) enable code (now commented out) to trap some (or maybe all) of these conflict when a DLL is loaded. c) provide a method to suppress the traps for users who prefer to do so and, in my view, take their chances. That's the way I see it now. Robert Ramey