Boost logo

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