|
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