From 1b4547ff93ce58fb2cc7bfe1201933ab01514e65 Mon Sep 17 00:00:00 2001 From: Thibault Saunier Date: Fri, 3 Oct 2014 12:34:15 +0200 Subject: [PATCH] aggregator: Take lock to ensure set_caps is not called concurently Avoiding to be in an inconsistent state where we do not have actual negotiate caps set as srccaps and leading to point where we try to unref ->srccaps when they have already been set to NULL. https://bugzilla.gnome.org/show_bug.cgi?id=735042 --- gst-libs/gst/base/gstaggregator.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/gst-libs/gst/base/gstaggregator.c b/gst-libs/gst/base/gstaggregator.c index bc53044e65..8f535129c9 100644 --- a/gst-libs/gst/base/gstaggregator.c +++ b/gst-libs/gst/base/gstaggregator.c @@ -106,6 +106,22 @@ GST_DEBUG_CATEGORY_STATIC (aggregator_debug); g_cond_broadcast(&(((GstAggregatorPad* )pad)->priv->event_cond)); \ } +#define GST_AGGREGATOR_SETCAPS_LOCK(self) G_STMT_START { \ + GST_LOG_OBJECT (self, "Taking SETCAPS lock from thread %p", \ + g_thread_self()); \ + g_mutex_lock(&self->priv->setcaps_lock); \ + GST_LOG_OBJECT (self, "Took SETCAPS lock from thread %p", \ + g_thread_self()); \ + } G_STMT_END + +#define GST_AGGREGATOR_SETCAPS_UNLOCK(self) G_STMT_START { \ + GST_LOG_OBJECT (self, "Releasing SETCAPS lock from thread %p", \ + g_thread_self()); \ + g_mutex_unlock(&self->priv->setcaps_lock); \ + GST_LOG_OBJECT (self, "Took SETCAPS lock from thread %p", \ + g_thread_self()); \ + } G_STMT_END + struct _GstAggregatorPadPrivate { gboolean pending_flush_start; @@ -177,6 +193,9 @@ struct _GstAggregatorPrivate GstTagList *tags; gboolean tags_changed; + + /* Lock to prevent two src setcaps from happening at the same time */ + GMutex setcaps_lock; }; typedef struct @@ -347,8 +366,10 @@ _push_mandatory_events (GstAggregator * self) void gst_aggregator_set_src_caps (GstAggregator * self, GstCaps * caps) { + GST_AGGREGATOR_SETCAPS_LOCK (self); gst_caps_replace (&self->priv->srccaps, caps); _push_mandatory_events (self); + GST_AGGREGATOR_SETCAPS_UNLOCK (self); } /** @@ -1053,6 +1074,7 @@ gst_aggregator_finalize (GObject * object) GstAggregator *self = (GstAggregator *) object; g_mutex_clear (&self->priv->mcontext_lock); + g_mutex_clear (&self->priv->setcaps_lock); G_OBJECT_CLASS (aggregator_parent_class)->finalize (object); } @@ -1134,6 +1156,7 @@ gst_aggregator_init (GstAggregator * self, GstAggregatorClass * klass) gst_element_add_pad (GST_ELEMENT (self), self->srcpad); g_mutex_init (&self->priv->mcontext_lock); + g_mutex_init (&self->priv->setcaps_lock); } /* we can't use G_DEFINE_ABSTRACT_TYPE because we need the klass in the _init