From b35d54dcd1afb11dd70356e67f4d95441be6d74d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Tue, 19 Apr 2011 13:05:53 +0100 Subject: [PATCH] baseparse: don't deadlock when setting external index Protect index with its own lock. gst_index_get_writer_id() may take the object lock internally (the default resolver, GST_INDEX_RESOLVER_PATH, will anyway), so if we're using that to protect the index as well, we'll deadlock. https://bugzilla.gnome.org/show_bug.cgi?id=646811 --- libs/gst/base/gstbaseparse.c | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/libs/gst/base/gstbaseparse.c b/libs/gst/base/gstbaseparse.c index 5776c1941f..1cd0a7ff51 100644 --- a/libs/gst/base/gstbaseparse.c +++ b/libs/gst/base/gstbaseparse.c @@ -276,6 +276,8 @@ struct _GstBaseParsePrivate GstIndex *index; gint index_id; gboolean own_index; + GStaticMutex index_lock; + /* seek table entries only maintained if upstream is BYTE seekable */ gboolean upstream_seekable; gboolean upstream_has_duration; @@ -450,6 +452,8 @@ gst_base_parse_finalize (GObject * object) parse->priv->index = NULL; } + g_static_mutex_free (&parse->priv->index_lock); + gst_base_parse_clear_queues (parse); G_OBJECT_CLASS (parent_class)->finalize (object); @@ -531,6 +535,8 @@ gst_base_parse_init (GstBaseParse * parse, GstBaseParseClass * bclass) parse->priv->pad_mode = GST_ACTIVATE_NONE; + g_static_mutex_init (&parse->priv->index_lock); + /* init state */ gst_base_parse_reset (parse); GST_DEBUG_OBJECT (parse, "init ok"); @@ -1416,11 +1422,11 @@ gst_base_parse_add_index_entry (GstBaseParse * parse, guint64 offset, associations[1].value = offset; /* index might change on-the-fly, although that would be nutty app ... */ - GST_OBJECT_LOCK (parse); + g_static_mutex_lock (&parse->priv->index_lock); gst_index_add_associationv (parse->priv->index, parse->priv->index_id, (key) ? GST_ASSOCIATION_FLAG_KEY_UNIT : GST_ASSOCIATION_FLAG_DELTA_UNIT, 2, (const GstIndexAssociation *) &associations); - GST_OBJECT_UNLOCK (parse); + g_static_mutex_unlock (&parse->priv->index_lock); if (key) { parse->priv->index_last_offset = offset; @@ -3384,7 +3390,7 @@ gst_base_parse_find_offset (GstBaseParse * parse, GstClockTime time, goto exit; } - GST_OBJECT_LOCK (parse); + g_static_mutex_lock (&parse->priv->index_lock); if (parse->priv->index) { /* Let's check if we have an index entry for that time */ entry = gst_index_get_assoc_entry (parse->priv->index, @@ -3408,7 +3414,7 @@ gst_base_parse_find_offset (GstBaseParse * parse, GstClockTime time, ts = GST_CLOCK_TIME_NONE; } } - GST_OBJECT_UNLOCK (parse); + g_static_mutex_unlock (&parse->priv->index_lock); exit: if (_ts) @@ -3736,17 +3742,18 @@ gst_base_parse_set_index (GstElement * element, GstIndex * index) { GstBaseParse *parse = GST_BASE_PARSE (element); - GST_OBJECT_LOCK (parse); + g_static_mutex_lock (&parse->priv->index_lock); if (parse->priv->index) gst_object_unref (parse->priv->index); if (index) { parse->priv->index = gst_object_ref (index); - gst_index_get_writer_id (index, GST_OBJECT (element), + gst_index_get_writer_id (index, GST_OBJECT_CAST (element), &parse->priv->index_id); parse->priv->own_index = FALSE; - } else + } else { parse->priv->index = NULL; - GST_OBJECT_UNLOCK (parse); + } + g_static_mutex_unlock (&parse->priv->index_lock); } static GstIndex * @@ -3755,10 +3762,10 @@ gst_base_parse_get_index (GstElement * element) GstBaseParse *parse = GST_BASE_PARSE (element); GstIndex *result = NULL; - GST_OBJECT_LOCK (parse); + g_static_mutex_lock (&parse->priv->index_lock); if (parse->priv->index) result = gst_object_ref (parse->priv->index); - GST_OBJECT_UNLOCK (parse); + g_static_mutex_unlock (&parse->priv->index_lock); return result; } @@ -3775,6 +3782,7 @@ gst_base_parse_change_state (GstElement * element, GstStateChange transition) case GST_STATE_CHANGE_READY_TO_PAUSED: /* If this is our own index destroy it as the * old entries might be wrong for the new stream */ + g_static_mutex_lock (&parse->priv->index_lock); if (parse->priv->own_index) { gst_object_unref (parse->priv->index); parse->priv->index = NULL; @@ -3790,6 +3798,7 @@ gst_base_parse_change_state (GstElement * element, GstStateChange transition) &parse->priv->index_id); parse->priv->own_index = TRUE; } + g_static_mutex_unlock (&parse->priv->index_lock); break; default: break;