mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-20 15:27:07 +00:00
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
This commit is contained in:
parent
c364539620
commit
b35d54dcd1
1 changed files with 19 additions and 10 deletions
|
@ -276,6 +276,8 @@ struct _GstBaseParsePrivate
|
||||||
GstIndex *index;
|
GstIndex *index;
|
||||||
gint index_id;
|
gint index_id;
|
||||||
gboolean own_index;
|
gboolean own_index;
|
||||||
|
GStaticMutex index_lock;
|
||||||
|
|
||||||
/* seek table entries only maintained if upstream is BYTE seekable */
|
/* seek table entries only maintained if upstream is BYTE seekable */
|
||||||
gboolean upstream_seekable;
|
gboolean upstream_seekable;
|
||||||
gboolean upstream_has_duration;
|
gboolean upstream_has_duration;
|
||||||
|
@ -450,6 +452,8 @@ gst_base_parse_finalize (GObject * object)
|
||||||
parse->priv->index = NULL;
|
parse->priv->index = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_static_mutex_free (&parse->priv->index_lock);
|
||||||
|
|
||||||
gst_base_parse_clear_queues (parse);
|
gst_base_parse_clear_queues (parse);
|
||||||
|
|
||||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
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;
|
parse->priv->pad_mode = GST_ACTIVATE_NONE;
|
||||||
|
|
||||||
|
g_static_mutex_init (&parse->priv->index_lock);
|
||||||
|
|
||||||
/* init state */
|
/* init state */
|
||||||
gst_base_parse_reset (parse);
|
gst_base_parse_reset (parse);
|
||||||
GST_DEBUG_OBJECT (parse, "init ok");
|
GST_DEBUG_OBJECT (parse, "init ok");
|
||||||
|
@ -1416,11 +1422,11 @@ gst_base_parse_add_index_entry (GstBaseParse * parse, guint64 offset,
|
||||||
associations[1].value = offset;
|
associations[1].value = offset;
|
||||||
|
|
||||||
/* index might change on-the-fly, although that would be nutty app ... */
|
/* 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,
|
gst_index_add_associationv (parse->priv->index, parse->priv->index_id,
|
||||||
(key) ? GST_ASSOCIATION_FLAG_KEY_UNIT : GST_ASSOCIATION_FLAG_DELTA_UNIT,
|
(key) ? GST_ASSOCIATION_FLAG_KEY_UNIT : GST_ASSOCIATION_FLAG_DELTA_UNIT,
|
||||||
2, (const GstIndexAssociation *) &associations);
|
2, (const GstIndexAssociation *) &associations);
|
||||||
GST_OBJECT_UNLOCK (parse);
|
g_static_mutex_unlock (&parse->priv->index_lock);
|
||||||
|
|
||||||
if (key) {
|
if (key) {
|
||||||
parse->priv->index_last_offset = offset;
|
parse->priv->index_last_offset = offset;
|
||||||
|
@ -3384,7 +3390,7 @@ gst_base_parse_find_offset (GstBaseParse * parse, GstClockTime time,
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
GST_OBJECT_LOCK (parse);
|
g_static_mutex_lock (&parse->priv->index_lock);
|
||||||
if (parse->priv->index) {
|
if (parse->priv->index) {
|
||||||
/* Let's check if we have an index entry for that time */
|
/* Let's check if we have an index entry for that time */
|
||||||
entry = gst_index_get_assoc_entry (parse->priv->index,
|
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;
|
ts = GST_CLOCK_TIME_NONE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
GST_OBJECT_UNLOCK (parse);
|
g_static_mutex_unlock (&parse->priv->index_lock);
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
if (_ts)
|
if (_ts)
|
||||||
|
@ -3736,17 +3742,18 @@ gst_base_parse_set_index (GstElement * element, GstIndex * index)
|
||||||
{
|
{
|
||||||
GstBaseParse *parse = GST_BASE_PARSE (element);
|
GstBaseParse *parse = GST_BASE_PARSE (element);
|
||||||
|
|
||||||
GST_OBJECT_LOCK (parse);
|
g_static_mutex_lock (&parse->priv->index_lock);
|
||||||
if (parse->priv->index)
|
if (parse->priv->index)
|
||||||
gst_object_unref (parse->priv->index);
|
gst_object_unref (parse->priv->index);
|
||||||
if (index) {
|
if (index) {
|
||||||
parse->priv->index = gst_object_ref (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->index_id);
|
||||||
parse->priv->own_index = FALSE;
|
parse->priv->own_index = FALSE;
|
||||||
} else
|
} else {
|
||||||
parse->priv->index = NULL;
|
parse->priv->index = NULL;
|
||||||
GST_OBJECT_UNLOCK (parse);
|
}
|
||||||
|
g_static_mutex_unlock (&parse->priv->index_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstIndex *
|
static GstIndex *
|
||||||
|
@ -3755,10 +3762,10 @@ gst_base_parse_get_index (GstElement * element)
|
||||||
GstBaseParse *parse = GST_BASE_PARSE (element);
|
GstBaseParse *parse = GST_BASE_PARSE (element);
|
||||||
GstIndex *result = NULL;
|
GstIndex *result = NULL;
|
||||||
|
|
||||||
GST_OBJECT_LOCK (parse);
|
g_static_mutex_lock (&parse->priv->index_lock);
|
||||||
if (parse->priv->index)
|
if (parse->priv->index)
|
||||||
result = gst_object_ref (parse->priv->index);
|
result = gst_object_ref (parse->priv->index);
|
||||||
GST_OBJECT_UNLOCK (parse);
|
g_static_mutex_unlock (&parse->priv->index_lock);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -3775,6 +3782,7 @@ gst_base_parse_change_state (GstElement * element, GstStateChange transition)
|
||||||
case GST_STATE_CHANGE_READY_TO_PAUSED:
|
case GST_STATE_CHANGE_READY_TO_PAUSED:
|
||||||
/* If this is our own index destroy it as the
|
/* If this is our own index destroy it as the
|
||||||
* old entries might be wrong for the new stream */
|
* old entries might be wrong for the new stream */
|
||||||
|
g_static_mutex_lock (&parse->priv->index_lock);
|
||||||
if (parse->priv->own_index) {
|
if (parse->priv->own_index) {
|
||||||
gst_object_unref (parse->priv->index);
|
gst_object_unref (parse->priv->index);
|
||||||
parse->priv->index = NULL;
|
parse->priv->index = NULL;
|
||||||
|
@ -3790,6 +3798,7 @@ gst_base_parse_change_state (GstElement * element, GstStateChange transition)
|
||||||
&parse->priv->index_id);
|
&parse->priv->index_id);
|
||||||
parse->priv->own_index = TRUE;
|
parse->priv->own_index = TRUE;
|
||||||
}
|
}
|
||||||
|
g_static_mutex_unlock (&parse->priv->index_lock);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in a new issue