Boost logo

Boost :

From: Sohail Somani (s.somani_at_[hidden])
Date: 2007-05-24 14:03:55


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<extended_type_info_typeid_1<T> >::instance());
}

> 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


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk