From c712b360822758f50d5acc20da21408ed505d1d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Wed, 7 Aug 2024 11:44:24 +0300 Subject: [PATCH] webrtcsrc: Don't hold the state lock while removing sessions Removing a session can drop its bin and during release of the bin its pads are removed, but the pad-removed handler is also taking the state lock. Part-of: --- net/webrtc/src/webrtcsrc/imp.rs | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/net/webrtc/src/webrtcsrc/imp.rs b/net/webrtc/src/webrtcsrc/imp.rs index 419b9b777..87dcc7ee9 100644 --- a/net/webrtc/src/webrtcsrc/imp.rs +++ b/net/webrtc/src/webrtcsrc/imp.rs @@ -12,6 +12,7 @@ use gst_webrtc::WebRTCDataChannel; use once_cell::sync::Lazy; use std::borrow::BorrowMut; use std::collections::{HashMap, HashSet}; +use std::mem; use std::str::FromStr; use std::sync::atomic::AtomicU16; use std::sync::atomic::Ordering; @@ -886,8 +887,13 @@ impl BaseWebRTCSrc { gst::error!(CAT, imp = self, "Error ending session : {e}"); } } - state.sessions.clear(); + + // Drop all sessions after releasing the state lock. Dropping the sessions + // can release their bin, and during release of the bin its pads are removed + // but the pad-removed handler is also taking the state lock. + let sessions = mem::take(&mut state.sessions); drop(state); + drop(sessions); self.maybe_stop_signaller(); @@ -972,9 +978,13 @@ impl BaseWebRTCSrc { ); return false; } - { - this.state.lock().unwrap().sessions.remove(session_id); - } + + // Drop session after releasing the state lock. Dropping the session can release its bin, + // and during release of the bin its pads are removed but the pad-removed handler is also + // taking the state lock. + let session = this.state.lock().unwrap().sessions.remove(session_id); + drop(session); + true } ),