
I think that performace penalty for my solution (http://lists.boost.org/boost-users/att-28092/multireg.zip) is miserable. If type is registered only once, I see 3 thing that are not priceless:
1) operations on extended_type_info are slightly slower. If type registered only once, the price is about just checking one pointer (m_prev) for equality to zero.
2) size of extended_type_info is bigger (two additional pointers).
3) performance of basic_serializer::operator< is most inflicted, because comparison of two pointer is changed to comparison of extended_type_info. However, it is still indistinguishable in the background of streams i/o performance.
And, finally, all code for multy-registration support can be easily cutted off with #ifdef.
Unfortunately, multiple registration of types is not the only problem if serialization code is spreaded between several Dlls - there are also some problems with tracking. For example, this problem: http://lists.boost.org/boost-users/2007/08/30275.php can be directly translated to situation with multiple shared libs. Different dlls/exe in this case can be considered as different versions of serialization code. I had failed to find a cheap way to fix this issue on library level. As a temporary workaround (for MSVC only) I had developed an utility that checks symbols exported from exe/dlls and finds suspicious situations (if type serialized by pointer and by value (tracking enabled) in one module and only by value (tracking disabled) in another one), but such approach is ugly and not portable.
"Robert Ramey"
This is my concern as well.
I am interested in addressing this in a definitive way. But its not trivial to do a good job which can be proven to work while at the same time not adding a performance hit to every user of the package.
Robert Ramey
Sergey Skorniakov wrote:
Thank you for your answer. My application is mono thread and duplicated code for seralization is granted to be the same. Our code actually forbide this design. What about replacing line 74&75 of
extended_type_info.cpp : 74 assert(lookup(eti) == m_self->m_map.end()); 75 m_self->m_map.insert(eti);
by
if ( lookup(eti) == m_self->m_map.end() ) { m_self->m_map.insert(eti); }
? With this new behavior the same type_info can be registred several time.
With this modification my design work fine. I can send you a sample of code if you want to investigate the problem
This modification will just leads to hard-to-find bugs. Take a look how this information is used in the library - for example, void_caster_compare uses extended_type_info::operator< and it will works wrong (results will be similar as derived class is not registered), because same type infos will be treated as different. Comparison of extended_type_info are also used in basic_archive_impl::helper_compare, in basic_serializer::operator< and may be in some other places. Thus, to support multiple registration, you should provide such extended_type_info::operator< implementation that duplicated type infos from different libs will be equivalent. I had just added double-linked list of extended_type_info to extended_type_info and adds duplicated type infos to the tail of this list. For operator< i mplemented as comparison of lists heads (first registered type info). Also, modification of basic_serializer::operator< required because it compares addresses of type infos instead of using extended_type_info::operator<.