Boost logo

Boost :

From: Anthony Williams (anthony_w.geo_at_[hidden])
Date: 2006-11-03 03:49:40


Roland Schwarz <roland.schwarz_at_[hidden]> writes:

> Anthony Williams wrote:
>> "Once" is more low-level. It can be used to initialize a mutex, *or any other
>> type of object*. Yes, if you have a static mutex, you can lock the mutex
>> around the initialization of another object, but that's unnecessarily complex:
>
> Sorry, but I disagree. My reasoning is that only one concept is better
> than two for the same purpose, i.e. lock, instead of two i.e. lock and once.
>
> Once you understand locking, you necessarily understand protection
> by locks. On the other hand you will need to look up what once
> exactly is about the first time you encounter it. To me at least
> its purpose was not obvious on first encounter.

OK, call it "locked initialization", or "thread-safe initialization" or
"synchronized initialization".

IMO, the concept of "once" is more fundamental than a mutex, and we should
certainly provide both.

>> You can't use a scoped_lock for this unless it has an unlock() member (which
>> IMO defeats the point of it being scoped), since otherwise you end up
>> serializing the "access x" part too.
>
> I don't think so:
>
> void f()
> {
> static mutex m;
> scoped_lock lk(m);
> static some_class x;
> m.unlock();
> // access x
> }

Surely you mean lk.unlock()? Otherwise scoped_lock will try and unlock the
mutex again. I did say "unless it has an unlock() member" above.

How is this different from using straight-forward lock() and unlock()
functions on the mutex?

> You cannot defeat the purpose of scoped_lock! In this case it is
> conditionally unlocked when the scope is left. This in the first
> place is, why Peter Dimov came up with an example that proved me
> that you need be able to do locking directly on the mutex too.

Using scoped lock here when all you really want is lock and unlock just seems
wrong to me. The lock isn't scoped, since there's an explicit unlock.

I generally feel uneasy about scoped_lock::unlock, since it makes reasoning
about code harder.

void f(mutex& m)
{
   scoped_lock lk(m);
   if(xyz())
   {
       lk.unlock();
   }
   // is lk locked or not?
}

> This also is why the scoped_lock isn't thread safe. In the destructor
> it has to check an unprotected variable that tests the current
> lock status.

I know that.

Anthony

-- 
Anthony Williams
Software Developer
Just Software Solutions Ltd
http://www.justsoftwaresolutions.co.uk

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