From 42e24c32e5aa11bc277952394eeed80a33e17eb4 Mon Sep 17 00:00:00 2001 From: Edward Hervey Date: Tue, 19 Mar 2024 09:32:39 +0100 Subject: [PATCH] uridecodebin3: Don't hold lock when posting messages or signals There's a very good chance that the receiver might react on those synchronously and call back into uridecodebin3 (ex: for setting the next URI). Make sure we release the lock if we need to do that. Fixes #3400 Part-of: --- .../gst/playback/gsturidecodebin3.c | 33 +++++++++++++------ 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/subprojects/gst-plugins-base/gst/playback/gsturidecodebin3.c b/subprojects/gst-plugins-base/gst/playback/gsturidecodebin3.c index 7f1263fe44..54f5e6e98b 100644 --- a/subprojects/gst-plugins-base/gst/playback/gsturidecodebin3.c +++ b/subprojects/gst-plugins-base/gst/playback/gsturidecodebin3.c @@ -1099,6 +1099,8 @@ switch_and_activate_input_locked (GstURIDecodeBin3 * uridecodebin, GList *to_activate = NULL; GList *iternew, *iterold; gboolean inactive_previous_item = old_pads == NULL; + GstMessage *pending_buffering_msg = NULL; + gboolean pending_about_to_finish = FALSE; /* Deactivate old urisourcebins first ? Problem is they might remove the pads */ @@ -1214,19 +1216,30 @@ switch_and_activate_input_locked (GstURIDecodeBin3 * uridecodebin, /* and set new one as input item */ uridecodebin->input_item = new_item; - /* If the new source is already drained, propagate about-to-finish */ - if (new_item->pending_about_to_finish) { - emit_and_handle_about_to_finish (uridecodebin, new_item); + pending_about_to_finish = new_item->pending_about_to_finish; + if (new_item->main_item->handler->pending_buffering_msg) { + pending_buffering_msg = new_item->main_item->handler->pending_buffering_msg; + new_item->main_item->handler->pending_buffering_msg = NULL; } - /* Finally propagate pending buffering message */ - if (new_item->main_item->handler->pending_buffering_msg) { - GstMessage *msg = new_item->main_item->handler->pending_buffering_msg; - new_item->main_item->handler->pending_buffering_msg = NULL; - GST_DEBUG_OBJECT (uridecodebin, - "Posting pending buffering message %" GST_PTR_FORMAT, msg); + /* If we have to post message or emit signals, it might trigger some + * re-entring actions (like setting the next URI). Make sure we release the + * lock when posting/emitting */ + if (pending_buffering_msg || pending_about_to_finish) { PLAY_ITEMS_UNLOCK (uridecodebin); - GST_BIN_CLASS (parent_class)->handle_message ((GstBin *) uridecodebin, msg); + /* If the new source is already drained, propagate about-to-finish */ + if (pending_about_to_finish) { + emit_and_handle_about_to_finish (uridecodebin, new_item); + } + + /* Finally propagate pending buffering message */ + if (pending_buffering_msg) { + GST_DEBUG_OBJECT (uridecodebin, + "Posting pending buffering message %" GST_PTR_FORMAT, + pending_buffering_msg); + GST_BIN_CLASS (parent_class)->handle_message ((GstBin *) uridecodebin, + pending_buffering_msg); + } PLAY_ITEMS_LOCK (uridecodebin); } }