pad: Enforce NEED_PARENT flag also for chain
authorOlivier Crête <olivier.crete@collabora.com>
Fri, 19 Jun 2015 04:05:44 +0000 (00:05 -0400)
committerOlivier Crête <olivier.crete@collabora.com>
Fri, 3 Jul 2015 16:56:01 +0000 (12:56 -0400)
The check for the presence of the parent in the presence of
the NEED_PARENT flag was missing for the chain function. Also keep
a ref on the parent in case the pad is removed mid-chain.

gst/gstpad.c
tests/check/gst/gstbin.c

index c4e8ff2..34735a0 100644 (file)
@@ -4017,7 +4017,7 @@ gst_pad_chain_data_unchecked (GstPad * pad, GstPadProbeType type, void *data)
 
   PROBE_PUSH (pad, type, data, probe_stopped);
 
-  parent = GST_OBJECT_PARENT (pad);
+  ACQUIRE_PARENT (pad, parent, no_parent);
   GST_OBJECT_UNLOCK (pad);
 
   /* NOTE: we read the chainfunc unlocked.
@@ -4057,6 +4057,8 @@ gst_pad_chain_data_unchecked (GstPad * pad, GstPadProbeType type, void *data)
         GST_DEBUG_FUNCPTR_NAME (chainlistfunc), gst_flow_get_name (ret));
   }
 
+  RELEASE_PARENT (parent);
+
   GST_PAD_STREAM_UNLOCK (pad);
 
   return ret;
@@ -4105,8 +4107,17 @@ probe_stopped:
     }
     return ret;
   }
+no_parent:
+  {
+    GST_DEBUG_OBJECT (pad, "No parent when chaining %" GST_PTR_FORMAT, data);
+    gst_mini_object_unref (GST_MINI_OBJECT_CAST (data));
+    GST_OBJECT_UNLOCK (pad);
+    GST_PAD_STREAM_UNLOCK (pad);
+    return GST_FLOW_FLUSHING;
+  }
 no_function:
   {
+    RELEASE_PARENT (parent);
     gst_mini_object_unref (GST_MINI_OBJECT_CAST (data));
     g_critical ("chain on pad %s:%s but it has no chainfunction",
         GST_DEBUG_PAD_NAME (pad));
index 409e273..171884f 100644 (file)
@@ -462,7 +462,7 @@ GST_START_TEST (test_message_state_changed_children)
 
   ASSERT_OBJECT_REFCOUNT (bus, "bus", 2);
   ASSERT_OBJECT_REFCOUNT (src, "src", 1);
-  ASSERT_OBJECT_REFCOUNT (sink, "sink", 1);
+  ASSERT_OBJECT_REFCOUNT (sink, "sink", 2);
   ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1);
 
   /* change state to PLAYING, spawning three messages */
@@ -481,7 +481,7 @@ GST_START_TEST (test_message_state_changed_children)
    * sink might have an extra reference if it's still blocked on preroll
    * pipeline posted a new-clock message too. */
   ASSERT_OBJECT_REFCOUNT_BETWEEN (src, "src", 2, 3);
-  ASSERT_OBJECT_REFCOUNT_BETWEEN (sink, "sink", 2, 3);
+  ASSERT_OBJECT_REFCOUNT_BETWEEN (sink, "sink", 2, 4);
   ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 3);
 
   pop_messages (bus, 3);
@@ -491,7 +491,7 @@ GST_START_TEST (test_message_state_changed_children)
   /* src might have an extra reference if it's still pushing */
   ASSERT_OBJECT_REFCOUNT_BETWEEN (src, "src", 1, 2);
   /* sink might have an extra reference if it's still blocked on preroll */
-  ASSERT_OBJECT_REFCOUNT_BETWEEN (sink, "sink", 1, 2);
+  ASSERT_OBJECT_REFCOUNT_BETWEEN (sink, "sink", 1, 3);
   ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1);
 
   /* go back to READY, spawning six messages */