fix(audio_backend): never throw across the PulseAudio callback boundary
connectContext() throws std::runtime_error when pa_context_connect() fails. It was called directly from contextStateCb (the libpulse mainloop thread, running pure-C callback frames) on the PA_CONTEXT_FAILED reconnect path, so on a pipewire/pulse restart the exception unwound across the C callback boundary and triggered std::terminate/SIGABRT. Add reconnectContext() noexcept which wraps connectContext() and logs failures instead of throwing, and use it from the callback. Guard against the FAILED -> connect -> FAILED recursion/busy loop with a reentrancy flag. The constructor-time connectContext() still throws as before. Fixes #5141.
This commit is contained in:
@@ -29,10 +29,17 @@ class AudioBackend {
|
||||
static void volumeModifyCb(pa_context*, int, void*);
|
||||
static void sourceVolumeModifyCb(pa_context*, int, void*);
|
||||
void connectContext();
|
||||
// Non-throwing reconnect used from the PulseAudio callback thread. Throwing
|
||||
// across the libpulse C callback boundary calls std::terminate, so this
|
||||
// swallows any failure and reports it via the return value instead.
|
||||
bool reconnectContext() noexcept;
|
||||
|
||||
pa_threaded_mainloop* mainloop_;
|
||||
pa_mainloop_api* mainloop_api_;
|
||||
pa_context* context_;
|
||||
// Guards against the FAILED -> connect -> FAILED recursion / busy loop when a
|
||||
// reconnect attempt fails synchronously inside pa_context_connect().
|
||||
bool reconnecting_{false};
|
||||
pa_cvolume pa_volume_;
|
||||
pa_cvolume pa_source_volume_;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user