webrtcbin: Fix potential deadlock on bin elements cleanup
authorEmil Ljungdahl <emillj@axis.com>
Fri, 15 Nov 2024 14:00:00 +0000 (15:00 +0100)
committerBackport Bot <gitlab-backport-bot@gstreamer-foundation.org>
Tue, 17 Dec 2024 12:04:53 +0000 (12:04 +0000)
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/8165>

subprojects/gst-plugins-bad/ext/webrtc/gstwebrtcbin.c

index dce4820a6d15742c6dedb1c3ad74013701d88391..dbd6d7580b702d246bfa2dbd2f1c847bf6b91361 100644 (file)
@@ -2586,12 +2586,11 @@ _on_data_channel_ready_state (WebRTCDataChannel * channel,
     if (found == FALSE) {
       GST_FIXME_OBJECT (webrtc, "Received close for unknown data channel");
     } else {
-      gst_element_set_locked_state (channel->src_bin, TRUE);
-      gst_element_set_state (channel->src_bin, GST_STATE_NULL);
+      /* Take an extra ref to src & sink bins so that teardown can be made outside dc_lock */
+      gst_object_ref (channel->src_bin);
       gst_bin_remove (GST_BIN (webrtc), channel->src_bin);
 
-      gst_element_set_locked_state (channel->sink_bin, TRUE);
-      gst_element_set_state (channel->sink_bin, GST_STATE_NULL);
+      gst_object_ref (channel->sink_bin);
       gst_bin_remove (GST_BIN (webrtc), channel->sink_bin);
 
       if (found_pending == FALSE) {
@@ -2599,6 +2598,17 @@ _on_data_channel_ready_state (WebRTCDataChannel * channel,
       }
     }
     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);
+    }
   }
 }