From 31903c4b612527fa9b8fa73f0322b00a597986a9 Mon Sep 17 00:00:00 2001 From: Alex P Date: Fri, 14 Nov 2025 10:21:15 +0200 Subject: [PATCH] Fix: extend audio mutex to prevent concurrent initialization crashes Previous fix protected WriteMessage() but missed Connect() calls. During session transfers, multiple goroutines could simultaneously initialize the audio playback system, causing SIGABRT crashes in jetkvm_audio_playback_init. Extended inputSourceMutex to serialize both Connect() and WriteMessage() operations, ensuring atomic state transitions and preventing concurrent C library initialization. --- audio.go | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/audio.go b/audio.go index c5265fd4..9bf83330 100644 --- a/audio.go +++ b/audio.go @@ -14,7 +14,7 @@ import ( var ( audioMutex sync.Mutex setAudioTrackMutex sync.Mutex // Prevents concurrent setAudioTrack() calls - inputSourceMutex sync.Mutex // Serializes WriteMessage() calls to input source + inputSourceMutex sync.Mutex // Serializes Connect() and WriteMessage() calls to input source outputSource audio.AudioSource inputSource atomic.Pointer[audio.AudioSource] outputRelay *audio.OutputRelay @@ -132,7 +132,6 @@ func onWebRTCDisconnect() { } func setAudioTrack(audioTrack *webrtc.TrackLocalStaticSample) { - // Prevent concurrent calls to avoid creating multiple relays setAudioTrackMutex.Lock() defer setAudioTrackMutex.Unlock() @@ -264,18 +263,20 @@ func handleInputTrackForSession(track *webrtc.TrackRemote) { continue // No relay, drop frame but keep reading } + inputSourceMutex.Lock() + if !(*source).IsConnected() { if err := (*source).Connect(); err != nil { + inputSourceMutex.Unlock() continue } } - // Serialize WriteMessage() to prevent concurrent session handlers from corrupting Opus decoder - inputSourceMutex.Lock() if err := (*source).WriteMessage(0, opusData); err != nil { audioLogger.Warn().Err(err).Msg("failed to write audio message") (*source).Disconnect() } + inputSourceMutex.Unlock() } }