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"); GST_DEBUG ("Starting");
DISCO_LOCK (dc); 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) { if (dc->priv->pending_uris == NULL) {
GST_WARNING ("No URI to process"); GST_WARNING ("No URI to process");
res = GST_DISCOVERER_URI_INVALID; res = GST_DISCOVERER_URI_INVALID;

View file

@ -267,7 +267,7 @@ discovered_cb (GstDiscoverer * discoverer,
} }
static void static void
test_disco_async_with_context (GMainContext * context) test_disco_async_with_context (GMainContext * context, guint num)
{ {
GstDiscoverer *dc; GstDiscoverer *dc;
GError *err = NULL; GError *err = NULL;
@ -293,6 +293,8 @@ test_disco_async_with_context (GMainContext * context)
g_signal_connect (dc, "discovered", G_CALLBACK (discovered_cb), &data); g_signal_connect (dc, "discovered", G_CALLBACK (discovered_cb), &data);
gst_discoverer_start (dc); gst_discoverer_start (dc);
for (guint i = 0; i < num; ++i) {
fail_unless (gst_discoverer_discover_uri_async (dc, data.uri) == TRUE); fail_unless (gst_discoverer_discover_uri_async (dc, data.uri) == TRUE);
g_main_loop_run (data.loop); g_main_loop_run (data.loop);
@ -302,6 +304,7 @@ test_disco_async_with_context (GMainContext * context)
} else { } else {
fail_unless_equals_int (data.result, GST_DISCOVERER_MISSING_PLUGINS); fail_unless_equals_int (data.result, GST_DISCOVERER_MISSING_PLUGINS);
} }
}
gst_discoverer_stop (dc); gst_discoverer_stop (dc);
g_object_unref (dc); g_object_unref (dc);
@ -316,7 +319,15 @@ test_disco_async_with_context (GMainContext * context)
GST_START_TEST (test_disco_async) GST_START_TEST (test_disco_async)
{ {
/* use default GMainContext */ /* 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; GST_END_TEST;
@ -336,7 +347,7 @@ custom_context_thread_func (CustomContextData * data)
/* test async APIs with custom GMainContext */ /* test async APIs with custom GMainContext */
context = g_main_context_new (); context = g_main_context_new ();
test_disco_async_with_context (context); test_disco_async_with_context (context, 1);
g_main_context_unref (context); g_main_context_unref (context);
data->finish = TRUE; 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_serializing);
tcase_add_test (tc_chain, test_disco_async); 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_custom_context);
tcase_add_test (tc_chain, test_disco_async_reuse);
return s; return s;
} }