Boost logo

Boost :

From: williamkempf_at_[hidden]
Date: 2001-09-25 15:52:09


--- In boost_at_y..., "Peter Dimov" <pdimov_at_m...> wrote:
> From: "Alexander Terekhov" <terekhov_at_d...>
> > > POSIX says "On return from pthread_once( ), it is guaranteed
that
> > > init_routine has completed." Does "completion" imply that the
results
> are
> > > visible to all threads?
> >
> > well, it is the only way i can interpret that statement.
>
> From this post:
>
> http://groups.google.com/groups?selm=3B161CE2.A5CF0259%40compaq.com
>
> I get the impression that David Butenhof definitely thinks that
pthread_once
> should synchronize memory. We can only hope that all pthread
implementors
> agree.
>
> OK, let's say that this means that the last implementation I gave is
> correct:
>
> static boost::once_flag m_once = boost::once_init;
> static boost::mutex * pm = 0;
>
> void m_init()
> {
> pm = new boost::mutex;
> }
>
> X & X::get()
> {
> boost::call_once(&m_once, m_init);
> boost::mutex::scoped_lock lock(*pm);
> static X x;
> return x;
> }
>
> I still don't like it. Such a common pattern shouldn't be that
hard. Some
> day C++ may guarantee that a function local static is thread safe;
but then
> again, it might not, and besides, we need a stop gap solution in the
> meantime.

I'd code this differently.

static boost::once_flag m_once = boost::once_init;
static X* px = 0;

void x_init()
{
   static X x;
   px = x;
}

X & X::get()
{
   boost::call_once(m_once, &x_init);
   return *px;
}

This is only slightly more complex then the original singleton code
using the static mutex initialization. To make it even simpler I'd
provide a template to handle all of this. With some clever
programming we could even use this pattern to implement a thread safe
initializer instead of just a singleton.

Bill Kempf


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