From e7bf5484c7c5fb97318cc58a0902d4ddd5ae459c Mon Sep 17 00:00:00 2001 From: =?utf8?q?Ole=20Andr=C3=A9=20Vadla=20Ravn=C3=A5s?= Date: Thu, 6 Jan 2011 18:11:31 +0100 Subject: [PATCH] base: Fix pad callbacks so they handle when parent goes away 1) We need to lock and get a strong ref to the parent, if still there. 2) If it has gone away, we need to handle that gracefully. This is necessary in order to safely modify a running pipeline. Has been observed when a streaming thread is doing a buffer_alloc() while an application thread sends an event on a pad further downstream, and from within a pad probe (holding STREAM_LOCK) carries out the pipeline plumbing while the streaming thread has its buffer_alloc() in progress. --- libs/gst/base/gstbasesink.c | 6 ++++++ libs/gst/base/gstbasetransform.c | 15 +++++++++++++-- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/libs/gst/base/gstbasesink.c b/libs/gst/base/gstbasesink.c index 01900ed..7740a77 100644 --- a/libs/gst/base/gstbasesink.c +++ b/libs/gst/base/gstbasesink.c @@ -653,6 +653,8 @@ gst_base_sink_pad_buffer_alloc (GstPad * pad, guint64 offset, guint size, GstFlowReturn result = GST_FLOW_OK; bsink = GST_BASE_SINK (gst_pad_get_parent (pad)); + if (G_UNLIKELY (bsink == NULL)) + return GST_FLOW_WRONG_STATE; bclass = GST_BASE_SINK_GET_CLASS (bsink); if (bclass->buffer_alloc) @@ -3414,6 +3416,10 @@ gst_base_sink_event (GstPad * pad, GstEvent * event) GstBaseSinkClass *bclass; basesink = GST_BASE_SINK (gst_pad_get_parent (pad)); + if (G_UNLIKELY (basesink == NULL)) { + gst_event_unref (event); + return FALSE; + } bclass = GST_BASE_SINK_GET_CLASS (basesink); diff --git a/libs/gst/base/gstbasetransform.c b/libs/gst/base/gstbasetransform.c index 8875336..4a0e24f 100644 --- a/libs/gst/base/gstbasetransform.c +++ b/libs/gst/base/gstbasetransform.c @@ -1225,8 +1225,13 @@ static gboolean gst_base_transform_query (GstPad * pad, GstQuery * query) { gboolean ret = FALSE; - GstBaseTransform *trans = GST_BASE_TRANSFORM (gst_pad_get_parent (pad)); - GstPad *otherpad = (pad == trans->srcpad) ? trans->sinkpad : trans->srcpad; + GstBaseTransform *trans; + GstPad *otherpad; + + trans = GST_BASE_TRANSFORM (gst_pad_get_parent (pad)); + if (G_UNLIKELY (trans == NULL)) + return FALSE; + otherpad = (pad == trans->srcpad) ? trans->sinkpad : trans->srcpad; switch (GST_QUERY_TYPE (query)) { case GST_QUERY_POSITION:{ @@ -1715,6 +1720,8 @@ gst_base_transform_buffer_alloc (GstPad * pad, guint64 offset, guint size, guint size_suggest; trans = GST_BASE_TRANSFORM (gst_pad_get_parent (pad)); + if (G_UNLIKELY (trans == NULL)) + return GST_FLOW_WRONG_STATE; klass = GST_BASE_TRANSFORM_GET_CLASS (trans); priv = trans->priv; @@ -1997,6 +2004,10 @@ gst_base_transform_sink_event (GstPad * pad, GstEvent * event) gboolean forward = TRUE; trans = GST_BASE_TRANSFORM (gst_pad_get_parent (pad)); + if (G_UNLIKELY (trans == NULL)) { + gst_event_unref (event); + return FALSE; + } bclass = GST_BASE_TRANSFORM_GET_CLASS (trans); if (bclass->event) -- 2.7.4