$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
From: bill_kempf (williamkempf_at_[hidden])
Date: 2002-03-04 07:59:23
--- In boost_at_y..., "Yitzhak Sapir" <ysapir_at_y...> wrote:
> I want to initialize a "singleton" type object. To do this, I use
> call_once.
>
> void f()
> {
> call_once(inited, init_singleton);
> }
>
> basically. Now, after I init it, I want to use it in some way. So
then
> I have:
>
> void f()
> {
> call_once(inited, init_singleton);
> use_singleton();
> }
>
> Now, I was thinking that call_once may be called in a different
thread
> already by the time I get to use_singleton, but the singleton has
not
> been inited yet. So I added a mutex:
>
> void f()
> {
> call_once(inited, init_singleton);
> scoped_lock(singleton_mutex);
> use_singleton();
> }
>
> init_singleton()
> {
> scoped_lock(singleton_mutex);
> // do initialization
> }
>
> (I look at this now and am thinking this only reduces the possible
race
> condition but may, depending on the implementation of call_once, not
> eliminate it entirely). Now I want to call f() in a global
variable:
>
> struct some_global
> {
> some_global() { f(); }
> };
>
> some_global a_global;
>
> Now I have a worse condition, in which case the mutex, which is also
> global, may be constructed after the global. In this case, during
> call_once() in the call to f(), I'd end up waiting on a mutex that
> hasn't been constructed inside the scoped_lock. I could use
call_once
> to initialize the mutex, but I'd have to know what guarantees are
made
> regarding call_once to know if it solves the problem.
Particularly, I
> need to know, not only that "flag != once_init" is a postcondition
of
> call_once, but also that func() has completed execution. So, given
that
> I still have a race condition in the previous step, and given this
issue
> of unclear order of global initializations, how would it be best to
> solve this problem, or does call_once indeed guarantee this
> postcondition ("func() has executed at least one time.")?
The gaurantee is that "func() has been executed exactly once". It
must have been run before call_once() will return, and it will only
run once. As you note, any other gaurantees are not useful. I
thought the documentation was explicit about this, but I'll look at
it while I'm reworking the documentation.
> Btw, this may be the time to point out that the docs at
> http://www.boost.org/libs/thread/doc/call_once.html specify a const
> once_flag once_init, whereas the actual thing to document is: const
> once_flag BOOST_ONCE_INIT;
This is something that changed at one point, and I thought I had
gotten the documentation up to date with the code. I'll have to fix
this as well.
Thanks,
Bill Kempf