
Matthew Vogt wrote:
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.
I agree. That's why I've so far only provided the Boost.Threads read/write lock try_promote() and timed_promote() methods (though you can, of course, get the latter to deadlock by using infinite times), and no promote() method. You could make a promote() method that throws if it can't promote, as you suggest below, but I don't like the idea much.
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:
[snip example]
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.
I agree. If releasing and reacquiring is good enough (and it probably is in many or even most cases), then of course you can do that, but it isn't really lock promotion.
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.
I agree. Mike