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: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1695>
This commit is contained in:
Sebastian Dröge 2024-08-07 11:44:24 +03:00 committed by GStreamer Marge Bot
parent ec38d416aa
commit 6c04b59454

View file

@ -13,6 +13,7 @@ use itertools::Itertools;
use once_cell::sync::Lazy; use once_cell::sync::Lazy;
use std::borrow::BorrowMut; use std::borrow::BorrowMut;
use std::collections::{HashMap, HashSet}; use std::collections::{HashMap, HashSet};
use std::mem;
use std::str::FromStr; use std::str::FromStr;
use std::sync::atomic::AtomicU16; use std::sync::atomic::AtomicU16;
use std::sync::atomic::Ordering; use std::sync::atomic::Ordering;
@ -897,8 +898,13 @@ impl BaseWebRTCSrc {
gst::error!(CAT, imp = self, "Error ending session : {e}"); 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(state);
drop(sessions);
self.maybe_stop_signaller(); self.maybe_stop_signaller();
@ -983,9 +989,13 @@ impl BaseWebRTCSrc {
); );
return false; 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 true
} }
), ),