Boost logo

Boost :

From: William E. Kempf (williamkempf_at_[hidden])
Date: 2002-08-06 10:36:18


----- Original Message -----
From: "Peter Dimov" <pdimov_at_[hidden]>
To: <boost_at_[hidden]>
Sent: Tuesday, August 06, 2002 8:21 AM
Subject: Re: [boost] Enhanced call_once()

> From: "Pete Becker" <petebecker_at_[hidden]>
> > At 05:00 PM 8/6/2002 +1000, Andrew J Bromage wrote:
> > >Is there any interest in something like this?
> > >
> > > void call_once(function0<void>& func, once_flag&);
> >
> > To paraphrase my recollection of Butenhof's discussion: back in the
olden
> > days, before POSIX had static initializers for mutexes, once functions
> were
> > essential, so that you could guarantee that a mutex had been initialized
> > before you used it. That was their primary reason for existing. Once
> static
> > initialion of mutexes was added this problem went away, and with it, the
> > primary need for once functions.
> >
> > Further, a once function won't ever be more efficient than user-written
> > code that uses a mutex and a flag, and will often be less efficient. So
as
> > long as you can statically initialize a mutex, once functions are
"merely"
> > a convenience.
> >
> > Now back to my own opinion, based on the above.
> >
> > In C++ we have automatic initialization of static objects, so there is
> even
> > less need for once functions.
>
> We have dynamic initialization of static mutex objects, but we do not have
> static initialization of mutex objects. Hello initialization order.

I've discussed this with Mr. Becker before, and since he dropped the thread
I assumed we agreed it wasn't possible to implement his interface. Now I
guess this isn't true.

True static initialization means that it occurs at compile time, not at run
time. This eliminates the initialization order problem, since any needs for
runtime thread synchronization are absent when initialized at compile time.
This type of static initialization is possible in C++, but requires POD
types. The design Mr. Becker proposes doesn't use a POD type, and thus
construction will occur at run time, and this means run time synchronization
is required. I like the design, but the current language rules don't seem
to allow for any implementation of this design. I'd love to be proved
wrong, as it would solve a lot of issues. For instance, it would allow me
to easily create a "static mutex", which would eliminate the need for
call_once entirely.

(Note: I'm still planning to add a "static mutex" to Boost.Threads, though
I'm still searching for the holy grail of implementations.)

I still like the idea of a language change to add a "synch" keyword, which
would do the lazy initialization in a thread safe manner for you.

static synch boost::mutex mutex; // Initialized on first use in a thread
safe manner

This would be as good as static initialization, and would be useful for
things other then this specific need. In other words, it would solve the
initialization order problem within the language. It does present questions
on how you specify destruction order.

> > Making them more powerful doesn't seem
> > productive, since they will rarely be needed in well-designed code.
>
> The 'powerful' once function and a statically initialized mutex are
> equivalent in expressive power; I can do either given the other.

I agree, but there is an argument for not having multiple ways to do the
same thing. If we had a clean way to create static mutexes I'd almost be in
favor of dropping call_once as a poor alternative.

Bill Kempf


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