Pad: post STREAM_STATUS_TYPE_CREATE
authorWim Taymans <wim.taymans@collabora.co.uk>
Thu, 23 Apr 2009 15:48:08 +0000 (17:48 +0200)
committerWim Taymans <wim@metal.(none)>
Mon, 11 May 2009 22:27:10 +0000 (00:27 +0200)
Post a stream-status message indicating that a new task was created so that the
application has a chance to change the properties of the task.

Fix unit test to take into account the new ref of the message.

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

index 09b0dc6..d9398c3 100644 (file)
@@ -4878,13 +4878,32 @@ gst_pad_start_task (GstPad * pad, GstTaskFunction func, gpointer data)
     task = gst_task_create (func, data);
     gst_task_set_lock (task, GST_PAD_GET_STREAM_LOCK (pad));
     gst_task_set_thread_callbacks (task, &thr_callbacks, pad, NULL);
-    GST_PAD_TASK (pad) = task;
     GST_DEBUG_OBJECT (pad, "created task");
+    /* release lock to post the message */
+    GST_OBJECT_UNLOCK (pad);
+
+    do_stream_status (pad, GST_STREAM_STATUS_TYPE_CREATE, NULL, task);
+
+    GST_OBJECT_LOCK (pad);
+    /* nobody else is supposed to have changed the pad now */
+    if (GST_PAD_TASK (pad) != NULL)
+      goto concurrent_start;
+    GST_PAD_TASK (pad) = task;
   }
   res = gst_task_set_state (task, GST_TASK_STARTED);
   GST_OBJECT_UNLOCK (pad);
 
   return res;
+
+  /* ERRORS */
+concurrent_start:
+  {
+    g_warning ("two threads started pad %s:%s at the same time",
+        GST_DEBUG_PAD_NAME (pad));
+    GST_OBJECT_UNLOCK (pad);
+    gst_object_unref (task);
+    return FALSE;
+  }
 }
 
 /**
index 1d2c44e..d466a28 100644 (file)
@@ -301,8 +301,8 @@ GST_START_TEST (test_message_state_changed_children)
    * base_src is blocked in the push and has an extra refcount.
    * base_sink_chain has taken a refcount on the sink, and is blocked on
    * preroll
-   * The stream-status message holds another ref to the element */
-  ASSERT_OBJECT_REFCOUNT (src, "src", 3);
+   * The stream-status messages holds 2 more refs to the element */
+  ASSERT_OBJECT_REFCOUNT (src, "src", 4);
   /* refcount can be 4 if the bin is still processing the async_done message of
    * the sink. */
   ASSERT_OBJECT_REFCOUNT_BETWEEN (sink, "sink", 2, 3);