webrtcbin: Fix potential deadlock on bin elements cleanup

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/7900>
This commit is contained in:
Emil Ljungdahl 2024-11-15 15:00:00 +01:00
parent d09605a3ff
commit df8b8f9692

View file

@ -2630,12 +2630,11 @@ _on_data_channel_ready_state (WebRTCDataChannel * channel,
if (found == FALSE) { if (found == FALSE) {
GST_FIXME_OBJECT (webrtc, "Received close for unknown data channel"); GST_FIXME_OBJECT (webrtc, "Received close for unknown data channel");
} else { } else {
gst_element_set_locked_state (channel->src_bin, TRUE); /* Take an extra ref to src & sink bins so that teardown can be made outside dc_lock */
gst_element_set_state (channel->src_bin, GST_STATE_NULL); gst_object_ref (channel->src_bin);
gst_bin_remove (GST_BIN (webrtc), channel->src_bin); gst_bin_remove (GST_BIN (webrtc), channel->src_bin);
gst_element_set_locked_state (channel->sink_bin, TRUE); gst_object_ref (channel->sink_bin);
gst_element_set_state (channel->sink_bin, GST_STATE_NULL);
gst_bin_remove (GST_BIN (webrtc), channel->sink_bin); gst_bin_remove (GST_BIN (webrtc), channel->sink_bin);
if (found_pending == FALSE) { if (found_pending == FALSE) {
@ -2643,6 +2642,17 @@ _on_data_channel_ready_state (WebRTCDataChannel * channel,
} }
} }
DC_UNLOCK (webrtc); DC_UNLOCK (webrtc);
if (found == TRUE) {
/* Tear down bins outside dc_lock to avoid deadlocks */
gst_element_set_locked_state (channel->src_bin, TRUE);
gst_element_set_state (channel->src_bin, GST_STATE_NULL);
gst_object_unref (channel->src_bin);
gst_element_set_locked_state (channel->sink_bin, TRUE);
gst_element_set_state (channel->sink_bin, GST_STATE_NULL);
gst_object_unref (channel->sink_bin);
}
} }
} }