decodebin: Protect ->source with the object lock
authorThibault Saunier <tsaunier@igalia.com>
Mon, 25 Mar 2019 22:11:54 +0000 (19:11 -0300)
committerThibault Saunier <tsaunier@gnome.org>
Tue, 9 Apr 2019 17:20:01 +0000 (17:20 +0000)
As expected by the property getter.

Basically there are cases where we can be getting the source from
any thread and in another thread bring back the element from PAUSED
to READY, which leads to a critical warning (or worse).

The only place where we use `->source` outside the property getter is
the change_state function so the current way of setting/reading it
should be safe.

gst/playback/gsturidecodebin.c

index 3d8b137..f19f69a 100644 (file)
@@ -2076,8 +2076,10 @@ remove_source (GstURIDecodeBin * bin)
       g_signal_handler_disconnect (source, bin->src_nmp_sig_id);
       bin->src_nmp_sig_id = 0;
     }
-    gst_bin_remove (GST_BIN_CAST (bin), source);
+    GST_OBJECT_LOCK (bin);
     bin->source = NULL;
+    GST_OBJECT_UNLOCK (bin);
+    gst_bin_remove (GST_BIN_CAST (bin), source);
   }
   if (bin->queue) {
     GST_DEBUG_OBJECT (bin, "removing old queue element");
@@ -2180,6 +2182,7 @@ static gboolean
 setup_source (GstURIDecodeBin * decoder)
 {
   gboolean is_raw, have_out, is_dynamic;
+  GstElement *source;
 
   GST_DEBUG_OBJECT (decoder, "setup source");
 
@@ -2189,8 +2192,14 @@ setup_source (GstURIDecodeBin * decoder)
   decoder->pending = 0;
 
   /* create and configure an element that can handle the uri */
-  if (!(decoder->source = gen_source_element (decoder)))
+  source = gen_source_element (decoder);
+  GST_OBJECT_LOCK (decoder);
+  if (!(decoder->source = source)) {
+    GST_OBJECT_UNLOCK (decoder);
+
     goto no_source;
+  }
+  GST_OBJECT_UNLOCK (decoder);
 
   /* state will be merged later - if file is not found, error will be
    * handled by the application right after. */