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: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/7930>
This commit is contained in:
Andoni Morales Alastruey 2024-11-20 13:32:20 +01:00 committed by GStreamer Marge Bot
parent f8d9412e4b
commit 7b408bae69
2 changed files with 28 additions and 9 deletions

View file

@ -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;

View 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;
}