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
serializer.
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
both.
-- 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