ges: discoverer-manager: Use a recursive mutex to protect the discoverers

So we can have subtimelines specified in `ges-launch` without
deadlocking

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/5973>
This commit is contained in:
Thibault Saunier 2024-01-08 11:21:18 -03:00 committed by GStreamer Marge Bot
parent dd6fca1d02
commit 0a292b8246

View file

@ -44,7 +44,7 @@ struct _GESDiscovererManager
GObject parent; GObject parent;
GHashTable *discoverers; GHashTable *discoverers;
GMutex lock; GRecMutex lock;
GstClockTime timeout; GstClockTime timeout;
gboolean use_cache; gboolean use_cache;
@ -125,7 +125,7 @@ ges_discoverer_manager_finalize (GObject * object)
if (!context) if (!context)
context = g_main_context_default (); context = g_main_context_default ();
g_mutex_lock (&self->lock); g_rec_mutex_lock (&self->lock);
g_hash_table_iter_init (&iter, self->discoverers); g_hash_table_iter_init (&iter, self->discoverers);
while (g_hash_table_iter_next (&iter, NULL, (gpointer *) & discoverer_data)) { while (g_hash_table_iter_next (&iter, NULL, (gpointer *) & discoverer_data)) {
GSource *source; GSource *source;
@ -138,7 +138,7 @@ ges_discoverer_manager_finalize (GObject * object)
} }
g_hash_table_unref (self->discoverers); g_hash_table_unref (self->discoverers);
g_mutex_unlock (&self->lock); g_rec_mutex_unlock (&self->lock);
G_OBJECT_CLASS (ges_discoverer_manager_parent_class)->finalize (object); G_OBJECT_CLASS (ges_discoverer_manager_parent_class)->finalize (object);
} }
@ -333,11 +333,11 @@ ges_discoverer_manager_set_timeout (GESDiscovererManager * self,
self->timeout = timeout; self->timeout = timeout;
g_mutex_lock (&self->lock); g_rec_mutex_lock (&self->lock);
g_hash_table_iter_init (&iter, self->discoverers); g_hash_table_iter_init (&iter, self->discoverers);
while (g_hash_table_iter_next (&iter, NULL, (gpointer *) & discoverer_data)) while (g_hash_table_iter_next (&iter, NULL, (gpointer *) & discoverer_data))
g_object_set (discoverer_data->discoverer, "timeout", timeout, NULL); g_object_set (discoverer_data->discoverer, "timeout", timeout, NULL);
g_mutex_unlock (&self->lock); g_rec_mutex_unlock (&self->lock);
} }
static GstDiscovererInfo * static GstDiscovererInfo *
@ -366,7 +366,7 @@ cleanup_discoverer_cb (GESDiscovererData * discoverer_data)
return G_SOURCE_REMOVE; return G_SOURCE_REMOVE;
} }
g_mutex_lock (&self->lock); g_rec_mutex_lock (&self->lock);
if (discoverer_data->n_uri > 0) { if (discoverer_data->n_uri > 0) {
GST_DEBUG_OBJECT (self, "Discoverer still has %d uris to discover", GST_DEBUG_OBJECT (self, "Discoverer still has %d uris to discover",
discoverer_data->n_uri); discoverer_data->n_uri);
@ -385,7 +385,7 @@ cleanup_discoverer_cb (GESDiscovererData * discoverer_data)
} }
done: done:
g_mutex_unlock (&self->lock); g_rec_mutex_unlock (&self->lock);
g_object_unref (self); g_object_unref (self);
return res; return res;
@ -397,14 +397,14 @@ proxy_discovered_cb (GESDiscovererManager * self,
{ {
g_signal_emit (self, signals[DISCOVERER_SIGNAL], 0, info, err); g_signal_emit (self, signals[DISCOVERER_SIGNAL], 0, info, err);
g_mutex_lock (&self->lock); g_rec_mutex_lock (&self->lock);
GESDiscovererData *data = GESDiscovererData *data =
g_hash_table_lookup (self->discoverers, g_thread_self ()); g_hash_table_lookup (self->discoverers, g_thread_self ());
if (data) { if (data) {
data->n_uri--; data->n_uri--;
data = g_atomic_rc_box_acquire (data); data = g_atomic_rc_box_acquire (data);
} }
g_mutex_unlock (&self->lock); g_rec_mutex_unlock (&self->lock);
if (data) { if (data) {
ges_timeout_add (1000, (GSourceFunc) cleanup_discoverer_cb, data, ges_timeout_add (1000, (GSourceFunc) cleanup_discoverer_cb, data,
@ -446,14 +446,14 @@ ges_discoverer_manager_get_discoverer (GESDiscovererManager * self)
g_return_val_if_fail (GES_IS_DISCOVERER_MANAGER (self), NULL); g_return_val_if_fail (GES_IS_DISCOVERER_MANAGER (self), NULL);
g_mutex_lock (&self->lock); g_rec_mutex_lock (&self->lock);
ret = g_hash_table_lookup (self->discoverers, g_thread_self ()); ret = g_hash_table_lookup (self->discoverers, g_thread_self ());
if (!ret) { if (!ret) {
ret = create_discoverer (self); ret = create_discoverer (self);
} else { } else {
g_hash_table_steal (self->discoverers, g_thread_self ()); g_hash_table_steal (self->discoverers, g_thread_self ());
} }
g_mutex_unlock (&self->lock); g_rec_mutex_unlock (&self->lock);
return ret; return ret;
} }
@ -468,12 +468,12 @@ ges_discoverer_manager_start_discovery (GESDiscovererManager * self,
disco_data = ges_discoverer_manager_get_discoverer (self); disco_data = ges_discoverer_manager_get_discoverer (self);
g_mutex_lock (&self->lock); g_rec_mutex_lock (&self->lock);
gboolean res = gboolean res =
gst_discoverer_discover_uri_async (disco_data->discoverer, uri); gst_discoverer_discover_uri_async (disco_data->discoverer, uri);
disco_data->n_uri++; disco_data->n_uri++;
g_hash_table_insert (self->discoverers, g_thread_self (), disco_data); g_hash_table_insert (self->discoverers, g_thread_self (), disco_data);
g_mutex_unlock (&self->lock); g_rec_mutex_unlock (&self->lock);
return res; return res;
} }