diff --git a/gst/gstpad.c b/gst/gstpad.c index 09b0dc6cf0..d9398c3442 100644 --- a/gst/gstpad.c +++ b/gst/gstpad.c @@ -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; + } } /** diff --git a/tests/check/gst/gstbin.c b/tests/check/gst/gstbin.c index 1d2c44efc6..d466a28ae0 100644 --- a/tests/check/gst/gstbin.c +++ b/tests/check/gst/gstbin.c @@ -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);