fix(pulse): Hanging during connection setup (#2709)
If context_state_callback is called before we call pa_threaded_mainloop_wait in the main thread, the signal is lost and we wait forever. Fixes #2707 Ref #2699 Ref #2697
This commit is contained in:
parent
efbd8e394f
commit
f653c3a738
@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
- ipc: Polybar failing to open IPC channel after another user already ran polybar, if `XDG_RUNTIME_DIR` is not set ([`#2683`](https://github.com/polybar/polybar/issues/2683), [`#2684`](https://github.com/polybar/polybar/pull/2684))
|
||||
- No overlines/underlines being drawn when using offsets ([`#2685`](https://github.com/polybar/polybar/pull/2685))
|
||||
- Update struts (`_NET_WM_STRUT_PARTIAL`) when hiding the bar ([`#2702`](https://github.com/polybar/polybar/pull/2702))
|
||||
- `internal/pulseaudio`: Hanging during startup ([`#2707`](https://github.com/polybar/polybar/issues/2707), [`#2709`](https://github.com/polybar/polybar/pull/2709))
|
||||
|
||||
## [3.6.2] - 2022-04-03
|
||||
### Fixed
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
#include <pulse/pulseaudio.h>
|
||||
|
||||
#include <atomic>
|
||||
#include <queue>
|
||||
|
||||
#include "common.hpp"
|
||||
@ -58,6 +59,11 @@ class pulseaudio {
|
||||
|
||||
const logger& m_log;
|
||||
|
||||
/**
|
||||
* Has context_state_callback signalled the mainloop during connection.
|
||||
*/
|
||||
std::atomic_bool m_state_callback_signal{false};
|
||||
|
||||
// used for temporary callback results
|
||||
int success{0};
|
||||
pa_cvolume cv{};
|
||||
|
@ -24,6 +24,8 @@ pulseaudio::pulseaudio(const logger& logger, string&& sink_name, bool max_volume
|
||||
|
||||
pa_context_set_state_callback(m_context, context_state_callback, this);
|
||||
|
||||
m_state_callback_signal = false;
|
||||
|
||||
if (pa_context_connect(m_context, nullptr, PA_CONTEXT_NOFLAGS, nullptr) < 0) {
|
||||
pa_context_disconnect(m_context);
|
||||
pa_context_unref(m_context);
|
||||
@ -42,7 +44,17 @@ pulseaudio::pulseaudio(const logger& logger, string&& sink_name, bool max_volume
|
||||
|
||||
m_log.trace("pulseaudio: started mainloop");
|
||||
|
||||
pa_threaded_mainloop_wait(m_mainloop);
|
||||
/*
|
||||
* Only wait for signal from the context state callback, if it has not
|
||||
* already signalled the mainloop since pa_context_connect was called,
|
||||
* otherwise, we would wait forever.
|
||||
*
|
||||
* The while loop ensures spurious wakeups are handled.
|
||||
*/
|
||||
while (!m_state_callback_signal) {
|
||||
pa_threaded_mainloop_wait(m_mainloop);
|
||||
}
|
||||
|
||||
if (pa_context_get_state(m_context) != PA_CONTEXT_READY) {
|
||||
pa_threaded_mainloop_unlock(m_mainloop);
|
||||
pa_threaded_mainloop_stop(m_mainloop);
|
||||
@ -310,6 +322,7 @@ void pulseaudio::context_state_callback(pa_context* context, void* userdata) {
|
||||
case PA_CONTEXT_READY:
|
||||
case PA_CONTEXT_TERMINATED:
|
||||
case PA_CONTEXT_FAILED:
|
||||
This->m_state_callback_signal = true;
|
||||
pa_threaded_mainloop_signal(This->m_mainloop, 0);
|
||||
break;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user