From 7b408bae69d514504faad777a99049db4dfe0fa6 Mon Sep 17 00:00:00 2001 From: Andoni Morales Alastruey Date: Wed, 20 Nov 2024 13:32:20 +0100 Subject: [PATCH] discoverer: fix segfault in race condition adding a new uri's 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: --- .../gst-libs/gst/pbutils/gstdiscoverer.c | 7 +++++ .../tests/check/libs/discoverer.c | 30 +++++++++++++------ 2 files changed, 28 insertions(+), 9 deletions(-) diff --git a/subprojects/gst-plugins-base/gst-libs/gst/pbutils/gstdiscoverer.c b/subprojects/gst-plugins-base/gst-libs/gst/pbutils/gstdiscoverer.c index b79732ca71..d12f73225e 100644 --- a/subprojects/gst-plugins-base/gst-libs/gst/pbutils/gstdiscoverer.c +++ b/subprojects/gst-plugins-base/gst-libs/gst/pbutils/gstdiscoverer.c @@ -2047,6 +2047,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; diff --git a/subprojects/gst-plugins-base/tests/check/libs/discoverer.c b/subprojects/gst-plugins-base/tests/check/libs/discoverer.c index 95a94940c4..1317a3ca87 100644 --- a/subprojects/gst-plugins-base/tests/check/libs/discoverer.c +++ b/subprojects/gst-plugins-base/tests/check/libs/discoverer.c @@ -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; }