discoverer: fix segfault in race condition adding a new uri's
authorAndoni Morales Alastruey <ylatuya@gmail.com>
Wed, 20 Nov 2024 12:32:20 +0000 (13:32 +0100)
committerGStreamer Marge Bot <gitlab-merge-bot@gstreamer-foundation.org>
Thu, 21 Nov 2024 00:03:09 +0000 (00:03 +0000)
There is a race condition adding new uri's right after receiving
the `discovered` event. We must wait until we have cleaned-up
the last discovery to start processing the new one

Fix #3758

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/7934>

subprojects/gst-plugins-base/gst-libs/gst/pbutils/gstdiscoverer.c
subprojects/gst-plugins-base/tests/check/libs/discoverer.c

index f913f451c25ce2f23c961ddf2344adc136c64936..dbbdc4d52e34886d54c0aa4dd569d01096ca96e5 100644 (file)
@@ -2065,6 +2065,13 @@ start_discovering (GstDiscoverer * dc)
   GST_DEBUG ("Starting");
 
   DISCO_LOCK (dc);
+  if (dc->priv->cleanup) {
+    GST_DEBUG ("The discoverer is busy cleaning up.");
+    res = GST_DISCOVERER_BUSY;
+    DISCO_UNLOCK (dc);
+    goto beach;
+  }
+
   if (dc->priv->pending_uris == NULL) {
     GST_WARNING ("No URI to process");
     res = GST_DISCOVERER_URI_INVALID;
index 95a94940c450f9f7fb84c731112df0725728486e..1317a3ca8708875416f9a698128e9a8ae8446cf5 100644 (file)
@@ -267,7 +267,7 @@ discovered_cb (GstDiscoverer * discoverer,
 }
 
 static void
-test_disco_async_with_context (GMainContext * context)
+test_disco_async_with_context (GMainContext * context, guint num)
 {
   GstDiscoverer *dc;
   GError *err = NULL;
@@ -293,14 +293,17 @@ test_disco_async_with_context (GMainContext * context)
   g_signal_connect (dc, "discovered", G_CALLBACK (discovered_cb), &data);
 
   gst_discoverer_start (dc);
-  fail_unless (gst_discoverer_discover_uri_async (dc, data.uri) == TRUE);
 
-  g_main_loop_run (data.loop);
+  for (guint i = 0; i < num; ++i) {
+    fail_unless (gst_discoverer_discover_uri_async (dc, data.uri) == TRUE);
 
-  if (have_theora && have_ogg) {
-    fail_unless_equals_int (data.result, GST_DISCOVERER_OK);
-  } else {
-    fail_unless_equals_int (data.result, GST_DISCOVERER_MISSING_PLUGINS);
+    g_main_loop_run (data.loop);
+
+    if (have_theora && have_ogg) {
+      fail_unless_equals_int (data.result, GST_DISCOVERER_OK);
+    } else {
+      fail_unless_equals_int (data.result, GST_DISCOVERER_MISSING_PLUGINS);
+    }
   }
 
   gst_discoverer_stop (dc);
@@ -316,7 +319,15 @@ test_disco_async_with_context (GMainContext * context)
 GST_START_TEST (test_disco_async)
 {
   /* use default GMainContext */
-  test_disco_async_with_context (NULL);
+  test_disco_async_with_context (NULL, 1);
+}
+
+GST_END_TEST;
+
+GST_START_TEST (test_disco_async_reuse)
+{
+  /* use default GMainContext */
+  test_disco_async_with_context (NULL, 3);
 }
 
 GST_END_TEST;
@@ -336,7 +347,7 @@ custom_context_thread_func (CustomContextData * data)
 
   /* test async APIs with custom GMainContext */
   context = g_main_context_new ();
-  test_disco_async_with_context (context);
+  test_disco_async_with_context (context, 1);
   g_main_context_unref (context);
 
   data->finish = TRUE;
@@ -394,6 +405,7 @@ discoverer_suite (void)
   tcase_add_test (tc_chain, test_disco_serializing);
   tcase_add_test (tc_chain, test_disco_async);
   tcase_add_test (tc_chain, test_disco_async_custom_context);
+  tcase_add_test (tc_chain, test_disco_async_reuse);
   return s;
 }