It seems like upgrade_mutex::try_unlock_shared_and_lock_until(const boost::chrono::time_point<Clock, Duration>& abs_time) and upgrade_mutex::try_unlock_upgrade_and_lock_until(const boost::chrono::time_point<Clock, Duration>& abs_time) can set the readers count to a wrong value.
The problem is with ++num_readers. Between reading it out of the state and then setting it again, the mutex is unlocked, so readers can unlock_shared(). This is even necessary, as the code actually waits until the readers count reaches 0.
Because of issues (https://github.com/boostorg/thread/issues/265, https://github.com/boostorg/thread/issues/361) in the default shared mutex implementation, I reviewed the code of the V2 mutex classes.
It seems like
upgrade_mutex::try_unlock_shared_and_lock_until(const boost::chrono::time_point<Clock, Duration>& abs_time)
andupgrade_mutex::try_unlock_upgrade_and_lock_until(const boost::chrono::time_point<Clock, Duration>& abs_time)
can set the readers count to a wrong value.Both functions contain the same piece of code:
The problem is with
++num_readers
. Between reading it out of the state and then setting it again, the mutex is unlocked, so readers canunlock_shared()
. This is even necessary, as the code actually waits until the readers count reaches 0.So IMHO, the line in question should read: