summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFabrice Bellet <fabrice@bellet.info>2019-06-16 17:42:45 +0200
committerOlivier CrĂȘte <olivier.crete@ocrete.ca>2020-03-12 14:37:24 +0000
commit46d7b108179b477a00464fc47dc8aa1c6389ee03 (patch)
treea3f29db0ce2e6a3f2458e7b1ad477c8487ccdff4
parentf047f4f6640146dda90cf9c87565fd61a3edeee8 (diff)
downloadfarstream-46d7b108179b477a00464fc47dc8aa1c6389ee03.tar.gz
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.
-rw-r--r--transmitters/nice/fs-nice-agent.c71
1 files 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