From 46d7b108179b477a00464fc47dc8aa1c6389ee03 Mon Sep 17 00:00:00 2001 From: Fabrice Bellet Date: Sun, 16 Jun 2019 17:42:45 +0200 Subject: nice agent: keep the main context alive until the agent is destroyed Recent addition of async removal of turn refreshes added sources to the main context when a stream is removed from the agent. Then, the main context must be still running until the nice agent is disposed to properly free resources. --- transmitters/nice/fs-nice-agent.c | 71 ++++++++++++++++++++++++--------------- 1 file changed, 43 insertions(+), 28 deletions(-) diff --git a/transmitters/nice/fs-nice-agent.c b/transmitters/nice/fs-nice-agent.c index b94e7138..744c9641 100644 --- a/transmitters/nice/fs-nice-agent.c +++ b/transmitters/nice/fs-nice-agent.c @@ -87,7 +87,8 @@ static void fs_nice_agent_class_init ( static void fs_nice_agent_init (FsNiceAgent *self); static void fs_nice_agent_dispose (GObject *object); static void fs_nice_agent_finalize (GObject *object); -static void fs_nice_agent_stop_thread (FsNiceAgent *self); +static void fs_nice_agent_stop_thread (gpointer user_data, + GObject *where_the_object_was); static void fs_nice_agent_set_property (GObject *object, guint prop_id, @@ -183,15 +184,34 @@ fs_nice_agent_init (FsNiceAgent *self) } +typedef struct _ThreadData { + GMainContext *main_context; + GMainLoop *main_loop; + GThread *thread; +} ThreadData; + static void fs_nice_agent_dispose (GObject *object) { FsNiceAgent *self = FS_NICE_AGENT (object); - - fs_nice_agent_stop_thread (self); + ThreadData *data; if (self->agent) + { + FS_NICE_AGENT_LOCK (self); + if (self->priv->thread) + { + data = g_new0 (ThreadData, 1); + data->main_context = g_main_context_ref (self->priv->main_context); + data->main_loop = g_main_loop_ref (self->priv->main_loop); + data->thread = self->priv->thread; + g_object_weak_ref (G_OBJECT (self->agent), + fs_nice_agent_stop_thread, data); + } + self->priv->thread = NULL; + FS_NICE_AGENT_UNLOCK (self); g_object_unref (self->agent); + } self->agent = NULL; parent_class->dispose (object); @@ -262,47 +282,42 @@ fs_nice_agent_get_property (GObject *object, } } - static gboolean -thread_unlock_idler (gpointer data) +thread_unlock_idler (gpointer user_data) { - FsNiceAgent *self = FS_NICE_AGENT (data); + ThreadData *data = user_data; - g_main_loop_quit (self->priv->main_loop); + g_main_loop_quit (data->main_loop); return TRUE; } static void -fs_nice_agent_stop_thread (FsNiceAgent *self) +fs_nice_agent_stop_thread (gpointer user_data, GObject *where_the_object_was) { + ThreadData *data = user_data; GSource *idle_source; - g_main_loop_quit (self->priv->main_loop); - - FS_NICE_AGENT_LOCK(self); + g_main_loop_quit (data->main_loop); - if (self->priv->thread == NULL || - self->priv->thread == g_thread_self ()) + if (data->thread && + data->thread != g_thread_self ()) { - FS_NICE_AGENT_UNLOCK (self); - return; - } - FS_NICE_AGENT_UNLOCK (self); - - idle_source = g_idle_source_new (); - g_source_set_priority (idle_source, G_PRIORITY_HIGH); - g_source_set_callback (idle_source, thread_unlock_idler, self, NULL); - g_source_attach (idle_source, self->priv->main_context); + idle_source = g_idle_source_new (); + g_source_set_priority (idle_source, G_PRIORITY_HIGH); + g_source_set_callback (idle_source, thread_unlock_idler, user_data, NULL); + g_source_attach (idle_source, data->main_context); - g_thread_join (self->priv->thread); + g_thread_join (data->thread); - g_source_destroy (idle_source); - g_source_unref (idle_source); + g_source_destroy (idle_source); + g_source_unref (idle_source); + } else + g_thread_unref (data->thread); - FS_NICE_AGENT_LOCK (self); - self->priv->thread = NULL; - FS_NICE_AGENT_UNLOCK (self); + g_main_context_unref (data->main_context); + g_main_loop_unref (data->main_loop); + g_free (data); } static gpointer -- cgit v1.2.1