diff options
author | Nicolas Dufresne <nicolas.dufresne@collabora.com> | 2023-05-01 14:01:02 -0400 |
---|---|---|
committer | GStreamer Marge Bot <gitlab-merge-bot@gstreamer-foundation.org> | 2023-05-09 09:24:40 +0000 |
commit | 00e4ad2c396567352dfe361d747c91e43eae9b83 (patch) | |
tree | a6b5e374cc6c21c122ffb3e2e0705b8d4f0f1ca5 | |
parent | 268ce06c78571afdaf95671c9a455f24f469bf4b (diff) | |
download | gstreamer-00e4ad2c396567352dfe361d747c91e43eae9b83.tar.gz |
v4l2: device provider: Fix GMainLoop leak
On very quick start/stop, the mainloop may never be run. As a side
effect, our idle stop function is not really being ran, so we can't rely
on that to free the main loop. Simply unref the mainloop when the
thread have completely stop.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/4539>
-rw-r--r-- | subprojects/gst-plugins-good/sys/v4l2/gstv4l2deviceprovider.c | 13 |
1 files changed, 10 insertions, 3 deletions
diff --git a/subprojects/gst-plugins-good/sys/v4l2/gstv4l2deviceprovider.c b/subprojects/gst-plugins-good/sys/v4l2/gstv4l2deviceprovider.c index 7c2c87fea3..5eeec7dc8b 100644 --- a/subprojects/gst-plugins-good/sys/v4l2/gstv4l2deviceprovider.c +++ b/subprojects/gst-plugins-good/sys/v4l2/gstv4l2deviceprovider.c @@ -369,6 +369,8 @@ provider_thread (gpointer data) if (context == NULL || loop == NULL) { provider->started = TRUE; g_cond_broadcast (&provider->started_cond); + g_clear_pointer (&loop, g_main_loop_unref); + g_clear_pointer (&context, g_main_context_unref); GST_OBJECT_UNLOCK (provider); return NULL; } @@ -451,19 +453,24 @@ gst_v4l2_device_provider_stop (GstDeviceProvider * provider) self->loop = NULL; GST_OBJECT_UNLOCK (self); - if (!context || !loop) + if (!context || !loop) { + g_clear_pointer (&self->loop, g_main_loop_unref); + g_clear_pointer (&self->context, g_main_context_unref); return; + } idle_stop_source = g_idle_source_new (); g_source_set_callback (idle_stop_source, (GSourceFunc) g_main_loop_quit, loop, - (GDestroyNotify) g_main_loop_unref); + NULL); g_source_attach (idle_stop_source, context); g_source_unref (idle_stop_source); - g_main_context_unref (context); g_thread_join (self->thread); self->thread = NULL; self->started = FALSE; + + g_main_loop_unref (loop); + g_main_context_unref (context); } #endif |