Minor changes to usages of std::condition_variable.

This commit is contained in:
Jordan Woyak 2019-04-06 17:39:25 -05:00
parent 75e74315e6
commit d34a9afe04
3 changed files with 21 additions and 3 deletions

View File

@ -19,6 +19,9 @@ AlsaSound::~AlsaSound()
{ {
m_thread_status.store(ALSAThreadStatus::STOPPING); m_thread_status.store(ALSAThreadStatus::STOPPING);
// Immediately lock and unlock mutex to prevent cv race.
std::unique_lock<std::mutex>{cv_m};
// Give the opportunity to the audio thread // Give the opportunity to the audio thread
// to realize we are stopping the emulation // to realize we are stopping the emulation
cv.notify_one(); cv.notify_one();
@ -81,7 +84,12 @@ void AlsaSound::SoundLoop()
bool AlsaSound::SetRunning(bool running) bool AlsaSound::SetRunning(bool running)
{ {
m_thread_status.store(running ? ALSAThreadStatus::RUNNING : ALSAThreadStatus::PAUSED); m_thread_status.store(running ? ALSAThreadStatus::RUNNING : ALSAThreadStatus::PAUSED);
cv.notify_one(); // Notify thread that status has changed
// Immediately lock and unlock mutex to prevent cv race.
std::unique_lock<std::mutex>{cv_m};
// Notify thread that status has changed
cv.notify_one();
return true; return true;
} }

View File

@ -31,7 +31,18 @@ public:
{ {
if (m_flag.TestAndSet()) if (m_flag.TestAndSet())
{ {
std::lock_guard<std::mutex> lk(m_mutex); // Lock and immediately unlock m_mutex.
{
// Holding the lock at any time between the change of our flag and notify call
// is sufficient to prevent a race where both of these actions
// happen between the other thread's predicate test and wait call
// which would cause wait to block until the next spurious wakeup or timeout.
// Unlocking before notification is a micro-optimization to prevent
// the notified thread from immediately blocking on the mutex.
std::lock_guard<std::mutex> lk(m_mutex);
}
m_condvar.notify_one(); m_condvar.notify_one();
} }
} }

View File

@ -15,7 +15,6 @@
#pragma once #pragma once
#include <array> #include <array>
#include <condition_variable>
#include <memory> #include <memory>
#include <mutex> #include <mutex>
#include <string> #include <string>