diff options
-rw-r--r-- | src/mumble/PulseAudio.cpp | 17 | ||||
-rw-r--r-- | src/mumble/PulseAudio.h | 7 |
2 files changed, 24 insertions, 0 deletions
diff --git a/src/mumble/PulseAudio.cpp b/src/mumble/PulseAudio.cpp index b52fd0644..521ea1e73 100644 --- a/src/mumble/PulseAudio.cpp +++ b/src/mumble/PulseAudio.cpp @@ -118,6 +118,14 @@ PulseAudioSystem::PulseAudioSystem() { m_pulseAudio.threaded_mainloop_start(pam); bRunning = true; + + std::unique_lock< std::mutex > guard(m_initLock); + if (!m_initialized) { + // The mutex is atomically released as soon as this thread starts waiting and will be + // re-acquired when waking up. + // Spurious wake-ups are avoided by checking m_initialized in the given predicate + m_initWaiter.wait(guard, [this]() { return m_initialized; }); + } } PulseAudioSystem::~PulseAudioSystem() { @@ -869,8 +877,17 @@ void PulseAudioSystem::contextCallback(pa_context *c) { qWarning("PulseAudio: Connection failure: %s", m_pulseAudio.strerror(m_pulseAudio.context_errno(c))); break; default: + // These are other status callbacks we don't care about. However we explicitly want to wait until + // one of the status flags listed above are emitted before claiming we are initialized (this callback + // will be called multiple times). return; } + + { + std::unique_lock< std::mutex > guard(m_initLock); + m_initialized = true; + } + m_initWaiter.notify_all(); } PulseAudioInputRegistrar::PulseAudioInputRegistrar() : AudioInputRegistrar(QLatin1String("PulseAudio"), 10) { diff --git a/src/mumble/PulseAudio.h b/src/mumble/PulseAudio.h index 920d4ac18..baee89713 100644 --- a/src/mumble/PulseAudio.h +++ b/src/mumble/PulseAudio.h @@ -24,6 +24,9 @@ #include <pulse/thread-mainloop.h> #include <pulse/volume.h> +#include <condition_variable> +#include <mutex> + struct PulseAttenuation { uint32_t index; QString name; @@ -119,6 +122,10 @@ private: Q_OBJECT Q_DISABLE_COPY(PulseAudioSystem) protected: + bool m_initialized = false; + std::mutex m_initLock; + std::condition_variable m_initWaiter; + void wakeup(); PulseAudio m_pulseAudio; |