diff options
author | Robert Adam <dev@robert-adam.de> | 2021-07-13 11:51:24 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-07-13 11:51:24 +0300 |
commit | 464fc4a36dd53bc5f7af47b09a30fe885512d9bd (patch) | |
tree | a7780fae19bc07365bfb84ac09ae766e3977b133 | |
parent | ce90876bf02866ea08ab66c940f0c73ba66d531a (diff) | |
parent | 3fec3de74d3b5d0826e40c7964769bac82075003 (diff) |
Merge PR #5183: FIX(client, audio): PulseAudio not initializing
PR #5159 removed a few seemingly unneeded waits on audio system
initialization which drastically sped up Mumble's startup. However as it
turns out for PulseAudio some waiting is actually required as the system
initializes asynchronously but we require the knowledge about the init
result.
Instead of adding an arbitrary wait time again though, this commit adds
a mechanism that waits exactly as long as necessary for the init to be
completed and then continues. That still cuts down the waiting time
tremendously when comparing with the previous (arbitrary) wait time of 1
second.
Fixes #5181
-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; |