composition: Avoid deadlock when setting current bin to ready (on commit or seek)
authorThibault Saunier <tsaunier@gnome.org>
Sun, 13 Jul 2014 09:51:51 +0000 (11:51 +0200)
committerThibault Saunier <tsaunier@gnome.org>
Fri, 31 Oct 2014 10:58:10 +0000 (11:58 +0100)
We need to make sure that between the time we send flush_start/stop and
the time we actually set the bin to READY, no buffer got prerolled again
as it would lead to a deadlock trying to set the bin to READY (while
deactivating the pads, it needs the streaming lock, which would be
taken in that case)

Co-Authored by: Mathieu Duponchelle <mathieu.duponchelle@opencreed.com>

gnl/gnlcomposition.c

index e8e621f..c3671bd 100644 (file)
@@ -2130,11 +2130,19 @@ set_child_caps (GValue * item, GValue * ret G_GNUC_UNUSED, GnlObject * comp)
   return TRUE;
 }
 
+static GstPadProbeReturn
+_drop_all_cb (GstPad * pad G_GNUC_UNUSED,
+    GstPadProbeInfo * info, GnlComposition * comp)
+{
+  return GST_PAD_PROBE_DROP;
+}
+
 /*  Must be called with OBJECTS_LOCK taken */
 static void
 _set_current_bin_to_ready (GnlComposition * comp, gboolean flush_downstream)
 {
-  GstPad *ptarget;
+  gint probe_id = -1;
+  GstPad *ptarget = NULL;
   GnlCompositionPrivate *priv = comp->priv;
 
   if (flush_downstream) {
@@ -2143,6 +2151,16 @@ _set_current_bin_to_ready (GnlComposition * comp, gboolean flush_downstream)
     if (ptarget) {
       GstEvent *flush_event;
 
+      /* Make sure that between the flush_start/flush_stop
+       * and the time we set the current_bin to READY, no
+       * buffer can ever get prerolled which would lead to
+       * a deadlock */
+      probe_id = gst_pad_add_probe (ptarget,
+          GST_PAD_PROBE_TYPE_DATA_BOTH | GST_PAD_PROBE_TYPE_EVENT_BOTH,
+          (GstPadProbeCallback) _drop_all_cb, comp, NULL);
+
+      GST_DEBUG_OBJECT (comp, "added event probe %lu", priv->ghosteventprobe);
+
       flush_event = gst_event_new_flush_start ();
       priv->flush_seqnum = gst_event_get_seqnum (flush_event);
       GST_ERROR_OBJECT (comp, "sending flushes downstream with seqnum %d",
@@ -2159,6 +2177,9 @@ _set_current_bin_to_ready (GnlComposition * comp, gboolean flush_downstream)
 
   gst_element_set_locked_state (priv->current_bin, TRUE);
   gst_element_set_state (priv->current_bin, GST_STATE_READY);
+
+  if (ptarget)
+    gst_pad_remove_probe (ptarget, probe_id);
 }
 
 /*  Must be called with OBJECTS_LOCK taken */