
Howard Hinnant wrote:
So in:
void f(read_write_mutex m) { read_write_mutex::read_lock r(m);
int y = x;
if (...) { read_write_mutex::write_lock w(r); //lock promotion
what would happen here if two threads entered f and tried to construct w simultaneously?
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. And choice 2 results in the assert(x==y) possibly firing.
I believe choice 2 is the only reasonable path.
Both choices are buggy. 3. One thread gets the lock, the other throws lock_error. is the only reasonable implementation of this operation, if it is provided.
And I also believe that the syntax above might lull a code reader into believing that assert(x==y) should always be true.
As it will be. There is no point in having the syntax otherwise, as the statement would have no reliable postconditions.
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 syntax is already available, and it does what it's supposed to do, but it's not the same as "promotion", which is atomic. I have to admit that I'm not convinced that unconditional promotion is useful, and I have trouble coming up with use cases for conditional promotion, too.