To those of us just joining the thread (boost developers list), we are discussing the use of Myers Singleton in the Boost.Serialization code and it's ramifications for thread-safety. You can see the thread here: http://thread.gmane.org/gmane.comp.lib.boost.user/27457 On Wed, 2007-05-23 at 22:38 -0700, Robert Ramey wrote:
Sohail Somani wrote:
I can develop a patch using boost once that I think would work. Locally, I'm going to have to do this anyway. Fortunately, my test has ceased to fail so I can't test it. To make it as "pay for what you use", one can #ifdef it out if they have special knowledge of the platform/compiler.
OK - you've convinced me there could be a problem.
I don't see a magic bullet solution. I think users need a couple of options and a good explanation in the manual.
Options
a) don't use export - use explicit archive level registration instead. b) some sort of explicit type registration. Users could just put at after the main entry point and/or in the DLL loading phase
How is (b) different from (a)? Is this related to your "load/save by name?"
c) an automatic method using thread safety primitives - maybe there are some small ones. Then you have the *#ifdef ...
There is a very small one ;-) The idea is here (copied and tweaked to
protect the innocent - may not compile):
// thread-safe lazily initialized singleton
template<typename T>
struct singleton
{
public:
static T & instance()
{
boost::call_once(call_once,once_); // the magic happens here
return get_instance();
}
private:
<*structors>;
// call_once *MUST* be called before calling this function
static T & get_instance()
{
static T object;
return object;
}
static void call_once()
{
get_instance();
}
static boost::once_flag once_;
};
// guaranteed to be called before main since it uses initialization
// with a constant expression (3.6.2.1) - language lawyers help please.
// Also, what happens with dlopen'ish stuff???? This is heavily platform
// specific. Someone save us from this mess.
template<typename T>
boost::once_flag singleton<T>::once_ = BOOST_ONCE_INIT;
Then usage would be something like:
static extended_type_info *
get_instance()
{
return &(singleton
The main obstacle is that requires a detailed understandable explanation along with examples - a fair amount of work. Note that this really applies to all extended type info systems so the explanation is even more complex.
Well I would have to rely on you to tell me where we need to apply the fixes. I would be happy to add some documentation to a patch against 1.34.
And once embarks upon this kind of effort, its interesting to consider "finishing" extended type info with some missing functionality like "construct from export name".
I have no idea why the two affect each other!
It would also be interesting to investigate if there is some sort of lock free solution - At least on some compilers/ processors.
I'm not going to touch lock-free lazily initialized singletons! I'd rather have my code work ;-)
Just goes to show that no good idea goes unpunished.
:-)
SOOO I'm am positive about the idea. However, like most good ideas, its a lot bigger than it first appears.
Don't see why myself. In multi-threaded builds of serialization, we link with Boost.Thread and use boost::once.
Having written this, it would seem that this is territory well traveled by those working on a good Singleton suitable for such a purpose.
I've worked on the above singleton, tested it on a few x86 OSes and it seems to work. But I would be very happy if someone has a better solution that is tested.
(Amazingly, I don't even know if boost has such a thiing) Ideally, I would just like to use that (assuming it doesn't import everything on planet earth).
I believe that Boost has everything you need for a *correct* solution. Sohail