Boost logo

Boost :

From: Matthew Vogt (mvogt_at_[hidden])
Date: 2004-07-05 19:27:53


Howard Hinnant <hinnant <at> twcny.rr.com> writes:

> My take, depending upon how the w(r) constructor is implemented, is
> either:
>
> 1. deadlock.
> 2. one thread blocks and one thread gets the lock.
>
> Imho choice 1 is a buggy implementation of the w(r) constructor.

Yes, there's no point creating a library facility that assists you in writing
code that deadlocks.

> And choice 2 results in the assert(x==y) possibly firing.

I think that in the second case, an exception should be thrown. Typically, if
you fail to promote a rw lock from read to write, then you will have to
repeat the part of the code that was read-protected after the other thread's
write lock has been released:

bool try_sale(rw_mutex& m)
{
  read_lock rl(m);

  long balance = get_balance();
  long cost = get_total_cost();

  if (balance > cost)
  {
    write_lock wl(rl);

    set_balance(balance - cost);
    // ...
    return true;
  }
  return false
}

bool do_sale(rw_mutex& m)
{
  bool succeeded = false;
  while (true)
  {
    try {
      return try_sale(m);
    catch (rw_promotion_error&) {
      // Try the whole thing again
    }
  }
}

> I believe choice 2 is the only reasonable path. And I also believe
> that the syntax above might lull a code reader into believing that
> assert(x==y) should always be true. And therefore I think the
> following (more explicit) syntax is superior:
>
> void f(read_write_mutex m)
> {
> read_write_mutex::read_lock r(m);
>
> int y = x;
>
> if (...)
> {
> r.unlock();
> read_write_mutex::write_lock w(m);
>
> This is essentially how the w(r) ctor must be implemented, if it is to
> be implemented at all. One could try a try_lock on w if the read count
> is 1, and then fall back on the above if that doesn't work, but I'm
> unsure if that really provides a benefit.

But this doesn't achieve anything - if you release the read lock, then you
don't know that what held true while it was read-locked is still true once
you have acquired a write lock.

If you choose to have lock promotion (having only lock demotion is a viable
choice, except that there will be certain usage patterns that are more
efficient with a fail-able promotion), then it must at least preserve
known state across promotion.

Matt.


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