mirror of
https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs.git
synced 2024-11-23 03:50:59 +00:00
net/webrtc: sink: abort stats collection before stopping the Signaller
In some rare cases, the webrtc-test entered a deadlock while executing `WebRTCSink::unprepare`. Attaching gdb to a blocked instance showed: * `gstrswebrtc::signaller:👿:Signaller::stop()` parked, waiting for a `Condvar` in `Signaller::stop()`. This was most likely awaiting for the receive task to complete while it was locked in `element.end_session()`. This code path is triggered from `unprepare` with the `State` `Mutex` locked. * `webrtcsink:👿:WebRtcSink::process_stats` waiting for a contended `Mutex`, which is also the `State` `Mutex`. This prevented completion of the signal `gst_webrtc_bin_get_stats`. This commit aborts the task in charge of periodically collecting stats and ensures any remaining iteration completes before requesting the Signaller to stop. Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1176>
This commit is contained in:
parent
2cb1fd7fc1
commit
0e6b9df932
1 changed files with 12 additions and 2 deletions
|
@ -195,6 +195,7 @@ struct State {
|
||||||
streams: HashMap<String, InputStream>,
|
streams: HashMap<String, InputStream>,
|
||||||
navigation_handler: Option<NavigationEventHandler>,
|
navigation_handler: Option<NavigationEventHandler>,
|
||||||
mids: HashMap<String, String>,
|
mids: HashMap<String, String>,
|
||||||
|
stats_collection_handle: Option<tokio::task::JoinHandle<()>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_navigation_event(sink: &super::WebRTCSink, msg: &str) {
|
fn create_navigation_event(sink: &super::WebRTCSink, msg: &str) {
|
||||||
|
@ -308,6 +309,7 @@ impl Default for State {
|
||||||
streams: HashMap::new(),
|
streams: HashMap::new(),
|
||||||
navigation_handler: None,
|
navigation_handler: None,
|
||||||
mids: HashMap::new(),
|
mids: HashMap::new(),
|
||||||
|
stats_collection_handle: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1236,6 +1238,14 @@ impl WebRTCSink {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let Some(stats_collection_handle) = state.stats_collection_handle.take() {
|
||||||
|
stats_collection_handle.abort();
|
||||||
|
// Make sure any currently running stats collection task completes
|
||||||
|
drop(state);
|
||||||
|
let _ = RUNTIME.block_on(stats_collection_handle);
|
||||||
|
state = self.state.lock().unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
state.maybe_stop_signaller(element);
|
state.maybe_stop_signaller(element);
|
||||||
|
|
||||||
state.codec_discovery_done = false;
|
state.codec_discovery_done = false;
|
||||||
|
@ -1940,7 +1950,7 @@ impl WebRTCSink {
|
||||||
|
|
||||||
let element_clone = element.downgrade();
|
let element_clone = element.downgrade();
|
||||||
let webrtcbin = session.webrtcbin.downgrade();
|
let webrtcbin = session.webrtcbin.downgrade();
|
||||||
RUNTIME.spawn(async move {
|
state.stats_collection_handle = Some(RUNTIME.spawn(async move {
|
||||||
let mut interval = tokio::time::interval(std::time::Duration::from_millis(100));
|
let mut interval = tokio::time::interval(std::time::Duration::from_millis(100));
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
|
@ -1956,7 +1966,7 @@ impl WebRTCSink {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
}));
|
||||||
|
|
||||||
if remove {
|
if remove {
|
||||||
state.finalize_session(element, &mut session, true);
|
state.finalize_session(element, &mut session, true);
|
||||||
|
|
Loading…
Reference in a new issue