From: Wim Taymans Date: Mon, 13 Feb 2006 09:59:03 +0000 (+0000) Subject: gst/gstpad.c: Correctly check flushing and emit probes. fixes #330125 X-Git-Tag: RELEASE-0_10_4~82 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=0d8a01f59502920cc92854b55158852389df8a06;p=platform%2Fupstream%2Fgstreamer.git gst/gstpad.c: Correctly check flushing and emit probes. fixes #330125 Original commit message from CVS: * gst/gstpad.c: (gst_pad_send_event): Correctly check flushing and emit probes. fixes #330125 --- diff --git a/ChangeLog b/ChangeLog index 4165536..561f133 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2006-02-13 Wim Taymans + + * gst/gstpad.c: (gst_pad_send_event): + Correctly check flushing and emit probes. fixes #330125 + 2006-02-10 Andy Wingo * gst/gstbus.c (gst_bus_class_init): Declare our private data diff --git a/gst/gstpad.c b/gst/gstpad.c index bbc1763..b48267f 100644 --- a/gst/gstpad.c +++ b/gst/gstpad.c @@ -3632,22 +3632,40 @@ gst_pad_send_event (GstPad * pad, GstEvent * event) { gboolean result = FALSE; GstPadEventFunction eventfunc; - gboolean emit_signal, serialized; + gboolean serialized, need_unlock = FALSE; g_return_val_if_fail (GST_IS_PAD (pad), FALSE); g_return_val_if_fail (event != NULL, FALSE); GST_OBJECT_LOCK (pad); - if (GST_PAD_IS_SINK (pad) && !GST_EVENT_IS_DOWNSTREAM (event)) - goto wrong_direction; - if (GST_PAD_IS_SRC (pad) && !GST_EVENT_IS_UPSTREAM (event)) - goto wrong_direction; + if (GST_PAD_IS_SINK (pad)) { + if (G_UNLIKELY (!GST_EVENT_IS_DOWNSTREAM (event))) + goto wrong_direction; + serialized = GST_EVENT_IS_SERIALIZED (event); + } else if (GST_PAD_IS_SRC (pad)) { + if (G_UNLIKELY (!GST_EVENT_IS_UPSTREAM (event))) + goto wrong_direction; + /* events on srcpad never are serialized */ + serialized = FALSE; + } else + goto unknown_direction; - if (GST_EVENT_SRC (event) == NULL) { + if (G_UNLIKELY (GST_EVENT_SRC (event) == NULL)) { GST_LOG_OBJECT (pad, "event had no source, setting pad as event source"); GST_EVENT_SRC (event) = gst_object_ref (pad); } + /* pad signals */ + if (G_UNLIKELY (GST_PAD_DO_EVENT_SIGNALS (pad) > 0)) { + GST_OBJECT_UNLOCK (pad); + + if (!gst_pad_emit_have_data_signal (pad, GST_MINI_OBJECT_CAST (event))) + goto dropping; + + GST_OBJECT_LOCK (pad); + } + + switch (GST_EVENT_TYPE (event)) { case GST_EVENT_FLUSH_START: GST_CAT_DEBUG (GST_CAT_EVENT, @@ -3663,38 +3681,41 @@ gst_pad_send_event (GstPad * pad, GstEvent * event) case GST_EVENT_FLUSH_STOP: GST_PAD_UNSET_FLUSHING (pad); GST_CAT_DEBUG (GST_CAT_EVENT, "cleared flush flag"); + GST_OBJECT_UNLOCK (pad); + /* grab stream lock */ + GST_PAD_STREAM_LOCK (pad); + need_unlock = TRUE; + GST_OBJECT_LOCK (pad); break; default: GST_CAT_DEBUG (GST_CAT_EVENT, "have event type %s on pad %s:%s", gst_event_type_get_name (GST_EVENT_TYPE (event)), GST_DEBUG_PAD_NAME (pad)); - if (GST_PAD_IS_FLUSHING (pad)) + /* make this a little faster, no point in grabbing the lock + * if the pad is allready flushing. */ + if (G_UNLIKELY (GST_PAD_IS_FLUSHING (pad))) goto flushing; + + if (serialized) { + /* lock order: STREAM_LOCK, LOCK */ + GST_OBJECT_UNLOCK (pad); + GST_PAD_STREAM_LOCK (pad); + need_unlock = TRUE; + GST_OBJECT_LOCK (pad); + if (G_UNLIKELY (GST_PAD_IS_FLUSHING (pad))) + goto flushing; + } break; } - - if ((eventfunc = GST_PAD_EVENTFUNC (pad)) == NULL) + if (G_UNLIKELY ((eventfunc = GST_PAD_EVENTFUNC (pad)) == NULL)) goto no_function; - emit_signal = GST_PAD_DO_EVENT_SIGNALS (pad) > 0; GST_OBJECT_UNLOCK (pad); - /* have to check if it's a sink pad, because e.g. CUSTOM_BOTH is serialized - when going down but not when going up */ - serialized = GST_EVENT_IS_SERIALIZED (event) && GST_PAD_IS_SINK (pad); - - if (G_UNLIKELY (emit_signal)) { - if (!gst_pad_emit_have_data_signal (pad, GST_MINI_OBJECT (event))) - goto dropping; - } - - if (serialized) - GST_PAD_STREAM_LOCK (pad); - - result = eventfunc (GST_PAD_CAST (pad), event); + result = eventfunc (pad, event); - if (serialized) + if (need_unlock) GST_PAD_STREAM_UNLOCK (pad); return result; @@ -3708,6 +3729,13 @@ wrong_direction: gst_event_unref (event); return FALSE; } +unknown_direction: + { + g_warning ("pad %s:%s has invalid direction", GST_DEBUG_PAD_NAME (pad)); + GST_OBJECT_UNLOCK (pad); + gst_event_unref (event); + return FALSE; + } no_function: { g_warning ("pad %s:%s has no event handler, file a bug.", @@ -3719,6 +3747,8 @@ no_function: flushing: { GST_OBJECT_UNLOCK (pad); + if (need_unlock) + GST_PAD_STREAM_UNLOCK (pad); GST_CAT_INFO (GST_CAT_EVENT, "Received event on flushing pad. Discarding"); gst_event_unref (event); return FALSE;