[Boost-bugs] [Boost C++ Libraries] #5341: Patch to improve shared library behavior with serialization

Subject: [Boost-bugs] [Boost C++ Libraries] #5341: Patch to improve shared library behavior with serialization
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2011-03-19 00:34:51

#5341: Patch to improve shared library behavior with serialization
 Reporter: Aaron Barany <akb825@…> | Owner: ramey
     Type: Patches | Status: new
Milestone: To Be Determined | Component: serialization
  Version: Boost 1.46.0 | Severity: Problem
 Keywords: serialization shared_libraries dlls |
 There are some issues that I have come across when using serialization
 with objects across shared libraries. I have made a patch that resolves
 the issues I have encountered, and will hopefully make serialization
 finally be friendly across multiple shared libraries.

 The primary issue that I had was if there is a serializer created for an
 object, there can be some shared libraries that have a pointer serializer
 registered, and others that don't. This is actually quite common if you
 have the base class of an object declared in a separate library, since
 serializng a base class with base_object doesn't instanciate a pointer

 Here is one case where this would prove to be an issue. Let's say the
 first time you wrote out a type it had no pointer serializer registered.
 It would write in the type info that tracking is not required and write
 out the object. Later, an object of the same type is written out from
 another shared library, but in this library a pointer serializer is
 registered. In this case, it will write out the object id, followed by the
 object itself. When that file is read in, it will read that the type has
 tracking disabled with the type information, and read the first instance
 just fine. However, on the second instance it still thinks that tracking
 is disabled, and will fail to read in the object id, even though it was
 written out.

 I solved this issue by re-writing the archive serializer map to manage
 both pointer and non-pointer serializers. The map itself stores the non-
 pointer serializers in a multiset, so the serializers for all shared
 libraries are stored. When a iserializer/oserializer is constructed it is
 registered for that object type, and when it is destructed it is
 unregistered. pointer_iserializer/pointer_oserializer also register and
 unregister themselves with the map, but the behavior is different. What it
 will do is look at all non-pointer serializers of the proper type
 currently registered, and for any that don't have any pointer serializer
 registered for them it will use the pointer serializer currently being
 registered. When a pointer serializer is unregistered, it will search for
 an equivalent pointer serialier registered for another serializer for the
 same type (that was instanciated in a different library), or NULL if there
 is no such pointer serializer, and replace all instances of the pointer
 serializer being unregistered with that. Additionally, if a non-pointer
 serializer is being registered, it will look for an existing pointer
 serializer for that type to use. (it will quickly be replaced if there is
 a pointer serializer for that type instanciated in that library)

 The effect at the end of the day is that for any given serializer, either
 all libraries or no libraries will have a pointer serializer registered
 for the corresponding non-pointer serializer. Since unregistration of
 pointer serializers tries to look for an equivalent to take its place, it
 should handle dynamic loading and unloading of libraries properly. Also,
 it should add no runtime cost during the actual usage of the serializers,
 only during the registration and unregistration.

 The other issue I was having was I needed to create my own archive, but
 there was no way to export the archive serializer map symbols unless I put
 it in the boost serialization library, since it used the
 BOOST_ARCHIVE_OR_WARCHIVE_DECL() to generate the dllexport/dllimport
 declspecs. I changed it to use a technique described here.
 (http://support.microsoft.com/kb/168958) This allows customization for
 whether the symbols are imported and exported for each instantioation of
 archive_serializer_map. I also had to change all of the current archives
 to use this new method to register the archive serializer map.

 I tried to keep consistent with your coding style and techniques. Since
 both this patch and the concrete to abstract patch I submitted earlier
 modify iserializer.hpp, I have also attached a combined patch that applies

Ticket URL: <https://svn.boost.org/trac/boost/ticket/5341>
Boost C++ Libraries <http://www.boost.org/>
Boost provides free peer-reviewed portable C++ source libraries.

This archive was generated by hypermail 2.1.7 : 2017-02-16 18:50:06 UTC