summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolas Dufresne <nicolas.dufresne@collabora.com>2023-05-01 14:01:02 -0400
committerGStreamer Marge Bot <gitlab-merge-bot@gstreamer-foundation.org>2023-05-09 09:24:40 +0000
commit00e4ad2c396567352dfe361d747c91e43eae9b83 (patch)
treea6b5e374cc6c21c122ffb3e2e0705b8d4f0f1ca5
parent268ce06c78571afdaf95671c9a455f24f469bf4b (diff)
downloadgstreamer-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.c13
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