summaryrefslogtreecommitdiff
path: root/src/model/pulsedevice.cpp
diff options
context:
space:
mode:
authorCalvin Morrison <calvin@pobox.com>2026-05-15 16:03:08 -0400
committerCalvin Morrison <calvin@pobox.com>2026-05-15 16:03:08 -0400
commit4a8a83f223bbc2b9d18ef91423c1ee807b297b35 (patch)
tree03b89f3eac9f0796ccdcbad5fa90915587f8e3ff /src/model/pulsedevice.cpp
parente0c8fb0cdcb9c95e3efa60322c1733df0a965650 (diff)
PA reconnect: recover cleanly when PulseAudio restarts
- 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 <noreply@anthropic.com>
Diffstat (limited to 'src/model/pulsedevice.cpp')
-rw-r--r--src/model/pulsedevice.cpp19
1 files changed, 12 insertions, 7 deletions
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;