Boost logo

Boost :

From: William E. Kempf (williamkempf_at_[hidden])
Date: 2002-08-07 13:15:43


----- Original Message -----
From: "Yitzhak Sapir" <yitzhaks_at_[hidden]>
> > From: William E. Kempf [mailto:williamkempf_at_[hidden]]
> > From: "Yitzhak Sapir" <yitzhaks_at_[hidden]>
> [posted from the end]
> > > Just an idea from following the discussion: Instead of
> > calling the class
> > "once", you could create an interface like this:
> > >
> > > boost::static_mutex_init -- equivalent of once_flag_type
> > > boost::static_mutex is a regular class and is implemented
> > like a mutex
> > except it uses call_once mechanisms to make sure the mutex is
> > initialized
> > once in the constructor.
> >
> > This requires, again, for the boost::static_mutex to be a POD
> > type, at which
> > point the implementation can be made much simpler on most platforms.
>
> boost::static_mutex_init is a POD type. Used something like this:
> boost::static_mutex_init smi = BOOST_STATIC_MUTEX_INITIALIZER;
> boost::static_mutex sm;
>
> static_mutex can't be a POD because it is going to have a destructor
(freeing the mutex). I can see now that it is calls to lock that are going
to need smi as a parameter, and that the constructor is basically a no op.
Inside lock, you'd do a call_once(CreateMutex, smi). Does this sound
useful?

OK, you've removed passing the POD init struct from the constructor to the
lock. At first this sounds like it should work even if the usage becomes
complicated, but if you think about it you'll realize it doesn't really.
The construction of the mutex is still not synchronized, even if the
construction of the implementation is. Even if this weren't a problem
though, I don't think users are going to care for the usage pattern
required.

> > Copyable semantics for mutex types is questionable at best. If it's
> > basically a reference copy you only remove some of the dangers of this
> > operation.
>
> It is a reference copy (a copy of the shared_ptr). My purpose was to keep
a reference count so that global client objects can access the static_mutex
after main() has finished where destruction order of global objects may be
different than what's needed for accessing the mutex. (In the first
example, there isn't any copyable semantics). Since I don't know what
dangers are involved, I'd thank you if you (or someone else) could refer me
(maybe in private mail) to some article or anything explaining those
dangers.

Copy semantics would allow something like this:

class Foo
{
public:
   Foo(const Foo&) { //... }
   // ...
private:
   boost::mutex mutex;
};

Foo f1;
Foo f2(f1);

If it's a deep copy then the semantics are non-obvious. Either the lock
state is copied which will lead to probable deadlocks or it's not really a
copy at all. If it's a shallow copy (reference semantics) then you wind up
with a single mutex appearantly being used to synchronize to seperate
objects, which is nearly gauranteed to deadlock here, and isn't what you
want in any event.

Bill Kempf


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