The new std::shared_timed_mutex allows for two types of locks: shared and exclusive.
If one holds a shared lock, is there any way to atomically exchange it ("upgrade it") to an exclusive lock? In other words, given the following code, how can I avoid the non-atomic drop and re-lock?
std::shared_timed_mutex m; //Guards a std::vector.
m.lock_shared();
//Read from vector. (Shared lock is sufficient.)
// ...
//Now we want to write to the vector. We need an exclusive lock.
m.unlock_shared();
// <---- Problem here: non-atomic!
m.lock();
//Write to vector.
// ...
m.unlock();
Ideally, m.unlock_shared(); m.lock();
could be replaced with something like m.upgrade_to_exclusive();
(or something like the boost::.upgrade_to_unique_lock()
).
In a similar question but for Boost's shared_mutex Dave S mentions
It is impossible to convert from a shared lock to a unique lock, or a shared lock to an upgradeable lock without releasing the shared lock first.
I'm not certain whether this applies to std::shared_mutex, though I suspect it does.
I would be happy with a reasonable work-around based on std::atomic/condition_variable or GCC's transactional memory.
Edit: Howard's answer addresses my question. His proposal N3427 contains nice descriptions of a mechanism to achieve mutex upgrading. I still welcome work-arounds based on std::atomic/condition_variable or GCC's transactional memory.