From 4a8a83f223bbc2b9d18ef91423c1ee807b297b35 Mon Sep 17 00:00:00 2001 From: Calvin Morrison Date: Fri, 15 May 2026 16:03:08 -0400 Subject: PA reconnect: recover cleanly when PulseAudio restarts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - On PA_CONTEXT_FAILED/TERMINATED, emit deviceRemoved for all devices so UI clears itself, then reconnect after 2s - Skip pa_context_disconnect and stream detach locks when PA is already dead to avoid hang in pa_threaded_mainloop_stop - Emit defaultOutputChanged(0)/defaultInputChanged(0) before deleting devices to prevent dangling pointer crash in TmixTray::setDevice - Disconnect all device signals before close() to avoid use-after-free from cross-device wiring (source→recording levelChanged bridge) - Icon: generate proper 22x22 (and 16/32/48) from source, install all sizes Co-Authored-By: Claude Sonnet 4.6 --- src/model/pulsedevice.cpp | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) (limited to 'src/model/pulsedevice.cpp') diff --git a/src/model/pulsedevice.cpp b/src/model/pulsedevice.cpp index 8bdea54..8fb8d48 100644 --- a/src/model/pulsedevice.cpp +++ b/src/model/pulsedevice.cpp @@ -45,15 +45,20 @@ void PulseDevice::setPAContext( pa_context *ctx, pa_threaded_mainloop *mainloop startMonitoring(); } -void PulseDevice::detach() +void PulseDevice::detach( bool paAlreadyDead ) { - if ( m_monitorStream && m_mainloop ) { - pa_threaded_mainloop_lock( m_mainloop ); - pa_stream_set_read_callback( m_monitorStream, 0, 0 ); - pa_stream_disconnect( m_monitorStream ); - pa_stream_unref( m_monitorStream ); + if ( m_monitorStream ) { + if ( paAlreadyDead ) { + pa_stream_set_read_callback( m_monitorStream, 0, 0 ); + pa_stream_unref( m_monitorStream ); + } else if ( m_mainloop ) { + pa_threaded_mainloop_lock( m_mainloop ); + pa_stream_set_read_callback( m_monitorStream, 0, 0 ); + pa_stream_disconnect( m_monitorStream ); + pa_stream_unref( m_monitorStream ); + pa_threaded_mainloop_unlock( m_mainloop ); + } m_monitorStream = 0; - pa_threaded_mainloop_unlock( m_mainloop ); } m_context = 0; m_mainloop = 0; -- cgit v1.2.3