mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-20 08:41:07 +00:00
decodebin: possible fix for deadlock when spamming "next song"
There was a deadlock between a thread changing decodebin/demuxer state from PAUSED to READY, and another thread pushing data when starting. From the stack trace at https://bug741355.bugzilla-attachments.gnome.org/attachment.cgi?id=292471, I deduce the following is happening, though I did not reproduce the problem so I'm not sure this patch fixes it. The streaming thread (thread 2 in that stack trace) takes the demuxer's sink pad's stream lock in gst_ogg_demux_perform_seek_pull and will activate a new chain. This ends up causing the expose lock being taken in _pad_added_cb in decodebin. Meanwhile, a state changed is triggered on thread 1, which takes the expose lock in decodebin in gst_decode_bin_change_state, then frees the previous chain, which ends up calling gst_pad_stop_task on the demuxer's task, which in turn takes the demuxer's sink pad's stream lock, deadlocking as both threads are now waiting for each other. https://bugzilla.gnome.org/show_bug.cgi?id=741355
This commit is contained in:
parent
cd07101420
commit
9036dc8594
1 changed files with 5 additions and 1 deletions
|
@ -4853,6 +4853,7 @@ gst_decode_bin_change_state (GstElement * element, GstStateChange transition)
|
||||||
{
|
{
|
||||||
GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
|
GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
|
||||||
GstDecodeBin *dbin = GST_DECODE_BIN (element);
|
GstDecodeBin *dbin = GST_DECODE_BIN (element);
|
||||||
|
GstDecodeChain *chain_to_free = NULL;
|
||||||
|
|
||||||
switch (transition) {
|
switch (transition) {
|
||||||
case GST_STATE_CHANGE_NULL_TO_READY:
|
case GST_STATE_CHANGE_NULL_TO_READY:
|
||||||
|
@ -4911,10 +4912,13 @@ gst_decode_bin_change_state (GstElement * element, GstStateChange transition)
|
||||||
do_async_done (dbin);
|
do_async_done (dbin);
|
||||||
EXPOSE_LOCK (dbin);
|
EXPOSE_LOCK (dbin);
|
||||||
if (dbin->decode_chain) {
|
if (dbin->decode_chain) {
|
||||||
gst_decode_chain_free (dbin->decode_chain);
|
chain_to_free = dbin->decode_chain;
|
||||||
|
gst_decode_chain_free_internal (dbin->decode_chain, TRUE);
|
||||||
dbin->decode_chain = NULL;
|
dbin->decode_chain = NULL;
|
||||||
}
|
}
|
||||||
EXPOSE_UNLOCK (dbin);
|
EXPOSE_UNLOCK (dbin);
|
||||||
|
if (chain_to_free)
|
||||||
|
gst_decode_chain_free (chain_to_free);
|
||||||
g_list_free_full (dbin->buffering_status,
|
g_list_free_full (dbin->buffering_status,
|
||||||
(GDestroyNotify) gst_message_unref);
|
(GDestroyNotify) gst_message_unref);
|
||||||
dbin->buffering_status = NULL;
|
dbin->buffering_status = NULL;
|
||||||
|
|
Loading…
Reference in a new issue