v4l2: device provider: Fix GMainLoop leak
authorNicolas Dufresne <nicolas.dufresne@collabora.com>
Mon, 1 May 2023 18:01:02 +0000 (14:01 -0400)
committerGStreamer Marge Bot <gitlab-merge-bot@gstreamer-foundation.org>
Tue, 9 May 2023 09:24:40 +0000 (09:24 +0000)
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>

subprojects/gst-plugins-good/sys/v4l2/gstv4l2deviceprovider.c

index 7c2c87f..5eeec7d 100644 (file)
@@ -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