Re: [Boost-users] Boost serialization : concurrency

Daniel F. Savarese wrote:
... However, I think I have a workaround that I just finished testing (at least the unit tests no longer seg fault). If you're willing to waste some memory and add the equivalent of the following to oserializer
private: static oserializer & dummy;
static oserializer & _instantiate(){ static oserializer instance; return instance; } public: static oserializer & instantiate(){ return dummy; }
and to iserializer:
private: static iserializer & dummy;
static iserializer & _instantiate(){ static iserializer instance; return instance; } public: static iserializer & instantiate(){ return dummy; }
and initialize oserializer::dummy as: template<class Archive, class T> oserializer<Archive,T> & oserializer<Archive,T>::dummy = oserializer<Archive,T>::_instantiate();
and iserializer::dummy as: template<class Archive, class T> iserializer<Archive,T> & iserializer<Archive,T>::dummy = iserializer<Archive,T>::_instantiate();
then the local static will be initialized at program initialization before any threads are running without incurring the global variable initialization ordering problem. ... This is just a test hack, but I think the concept works.
Sorry, I don't think your idea works: (1) What happens if the constructor or initializer of a global or static member variable calls oserializer::instantiate(), and that variable is initialized before oserializer::dummy is initialized? E.g.: struct foo { foo() { // oserializer::dummy might not be initialized yet, // so this can return a reference to an invalid object: oserializer<x,y> os = oserializer::instantiate(); os.do_something(); // boom } }; foo g_f; (2) There exists no guarantee that multiple threads will not be running at program initialization time. Threads can be started in the constructors and initializers of global or static member variables. E.g.: void thread_func() { // oserializer::dummy might not be initialized yet, // so this can return a reference to an invalid object: oserializer<x,y> os = oserializer::instantiate(); os.do_something(); // boom again } struct bar { bar() { boost::thread t(&thread_func); } } bar g_b; (Btw, if your idea really did work, then you would have just invented a thread-safe implementation of the Singleton pattern that does not require any thread synchronization. I don't believe that's possible.) Moshe
participants (1)
-
Moshe Matitya