From c67b93578f6d84a458e8f30e8d377569d8611c84 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 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- 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() } }