|
Boost : |
From: Howard Hinnant (hinnant_at_[hidden])
Date: 2004-07-04 16:25:27
On Jun 29, 2004, at 12:30 PM, Michael Glassford wrote:
> Also, you could end up with some interesting situations like this:
>
> void f(read_write_mutex m)
> {
> read_write_mutex::read_lock r(m);
> if (...)
> {
> read_write_mutex::write_lock w(r); //lock promotion
> //...
> }
> //Point A
> }
How 'bout:
void f(read_write_mutex& m)
{
read_write_mutex::read_lock r(m);
if (...)
{
r.unlock();
read_write_mutex::write_lock w(m);
//... m is write locked
w.transfer_to_read_lock(r);
}
//Point A ... m is read locked
}
Transferring mutex ownership from a read_lock to a write_lock is always
a blocking operation. So there's no advantage to a
transfer_to_write_lock() function. You might as well manually unlock
the read_lock and manually lock the write_lock as shown above. But the
write_lock::transfer_to_read_lock() member can atomically transfer
ownership to the appointed read_lock and notify all other read_lock's
that it is time to wake up.
Summary:
1. There's only two types of locks: read_lock, write_lock.
2. Exception safety is maintained.
3. Interface is minimal and intuitive (at least to me).
4. r is always locked at Point A.
5. If the write_lock branch is taken, the code can assume that at
Point A the thread is reading what was written while the write_lock was
held. There is no chance for another thread to write.
6. There is no chance for deadlock of multiple read_locks waiting for
promotion because there is no such operation. You must unlock the
read_lock and then block for a write_lock.
-Howard
PS: I find the promotion/demotion terminology confusing.
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk