Fix problems with global locks

* Aquire the mutex before setting `m_exclusivelyOwned = false`; otherwise
  it might be set after `lock()` has checked it but before `lock()` has
  entered `wait()` leading to a deadlock
* Check state again after `wait()` because it may also be unblocked
  "spuriously" so it isn't guaranteed that the state will have actually
  changed after unblocking
This commit is contained in:
Martchus 2022-01-25 22:49:20 +01:00
parent 218dfecf56
commit d4d187463a
1 changed files with 4 additions and 2 deletions

View File

@ -32,7 +32,7 @@ private:
inline void GlobalSharedMutex::lock()
{
auto lock = std::unique_lock<std::mutex>(m_mutex);
if (m_sharedOwners || m_exclusivelyOwned) {
while (m_sharedOwners || m_exclusivelyOwned) {
m_cv.wait(lock);
}
m_exclusivelyOwned = true;
@ -50,14 +50,16 @@ inline bool GlobalSharedMutex::try_lock()
inline void GlobalSharedMutex::unlock()
{
auto lock = std::unique_lock<std::mutex>(m_mutex);
m_exclusivelyOwned = false;
lock.unlock();
m_cv.notify_one();
}
inline void GlobalSharedMutex::lock_shared()
{
auto lock = std::unique_lock<std::mutex>(m_mutex);
if (m_exclusivelyOwned) {
while (m_exclusivelyOwned) {
m_cv.wait(lock);
}
++m_sharedOwners;