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;
+ }
}
/**
* 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);