Boost logo

Boost :

From: Howard Hinnant (hinnant_at_[hidden])
Date: 2004-08-10 12:37:12


On Aug 9, 2004, at 7:08 PM, Howard Hinnant wrote:

> Ok, but what if you do the opposite:
>
> typedef scoped_lock<rw_mutex> WriteLock;
> typedef upgradable_lock<rw_mutex> ReadLock;
>
> WriteLock write_lock(m);
> ...
> if (...)
> {
> ReadLock read_lock(m, defer_lock);
> transfer_lock<ReadLock, WriteLock> lock(read_lock, write_lock);
> // here m is downgraded from write to read
> ...
> // m is upgraded from read to write before exiting scope
> }
> // here m is write locked, whether or not if-branch was taken
> ...

After playing with this some more I've realized that transfer_lock
simply doesn't work like this in the context of the proposed |= and <<=
operators. When transferring ownership from upgradable to scoped, a
generic utility such as the above will use (pseudo code):

For "lock":
     scoped_lock |= upgradable_lock
For "try lock":
     scoped_lock <<= upgradable_lock
For "unlock":
     upgradable_lock = scoped_lock

If you reverse the roles, it simply will not compile:

For "lock":
     upgradable_lock |= scoped_lock // no such operation
For "try lock":
     upgradable_lock <<= scoped_lock // no such operation
For "unlock":
     scoped_lock = upgradable_lock // no such operation

Therefore transfer_lock is really better named promote_lock. And if
you wanted a generic demote_lock then that would probably look like:

For "lock":
     upgradable_lock = scoped_lock
For "try lock":
     upgradable_lock = scoped_lock
For "unlock":
     scoped_lock |= upgradable_lock

And it would be ill-advised to try to couple a demote_lock with another
lock via a generic "lock 2" algorithm. Such a generic algorithm could
probably be set up to detect demote_lock at compile time and refuse to
compile it.

-Howard


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