From 4df3fad9e436bbf0e201afa710b2998be13a9f07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Mon, 15 Oct 2012 09:35:16 +0200 Subject: [PATCH] hlsdemux: Never ever stop a task from the task function This will deadlock. Also make sure to always post an error message if required before pausing tasks from the task function. Should fix another bunch of deadlocks. Conflicts: gst/hls/gsthlsdemux.c --- gst/hls/gsthlsdemux.c | 47 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 38 insertions(+), 9 deletions(-) diff --git a/gst/hls/gsthlsdemux.c b/gst/hls/gsthlsdemux.c index 10465542a7..85dfdc6268 100644 --- a/gst/hls/gsthlsdemux.c +++ b/gst/hls/gsthlsdemux.c @@ -102,6 +102,7 @@ static gboolean gst_hls_demux_src_query (GstPad * pad, GstObject * parent, static void gst_hls_demux_stream_loop (GstHLSDemux * demux); static void gst_hls_demux_updates_loop (GstHLSDemux * demux); static void gst_hls_demux_stop (GstHLSDemux * demux); +static void gst_hls_demux_pause_tasks (GstHLSDemux * demux); static gboolean gst_hls_demux_cache_fragments (GstHLSDemux * demux); static gboolean gst_hls_demux_schedule (GstHLSDemux * demux); static gboolean gst_hls_demux_switch_playlist (GstHLSDemux * demux); @@ -594,6 +595,22 @@ gst_hls_demux_chain (GstPad * pad, GstObject * parent, GstBuffer * buf) return GST_FLOW_OK; } +static void +gst_hls_demux_pause_tasks (GstHLSDemux * demux) +{ + gst_uri_downloader_cancel (demux->downloader); + + if (GST_TASK_STATE (demux->updates_task) != GST_TASK_STOPPED) { + demux->stop_stream_task = TRUE; + gst_task_pause (demux->updates_task); + GST_TASK_SIGNAL (demux->updates_task); + } + + if (GST_TASK_STATE (demux->stream_task) != GST_TASK_STOPPED) { + gst_task_pause (demux->stream_task); + } +} + static void gst_hls_demux_stop (GstHLSDemux * demux) { @@ -725,7 +742,7 @@ end_of_playlist: { GST_DEBUG_OBJECT (demux, "Reached end of playlist, sending EOS"); gst_pad_push_event (demux->srcpad, gst_event_new_eos ()); - gst_hls_demux_stop (demux); + gst_hls_demux_pause_tasks (demux); return; } @@ -735,17 +752,22 @@ cache_error: if (!demux->cancelled) { GST_ELEMENT_ERROR (demux, RESOURCE, NOT_FOUND, ("Could not cache the first fragments"), (NULL)); - gst_hls_demux_stop (demux); + gst_hls_demux_pause_tasks (demux); } return; } error_pushing: { - /* FIXME: handle error */ - GST_DEBUG_OBJECT (demux, "Error pushing buffer: %s... stopping task", - gst_flow_get_name (ret)); - gst_hls_demux_stop (demux); + if (ret == GST_FLOW_NOT_LINKED || ret < GST_FLOW_EOS) { + GST_ELEMENT_ERROR (demux, STREAM, FAILED, (NULL), + ("stream stopped, reason %s", gst_flow_get_name (ret))); + gst_pad_push_event (demux->srcpad, gst_event_new_eos ()); + } else { + GST_DEBUG_OBJECT (demux, "stream stopped, reason %s", + gst_flow_get_name (ret)); + } + gst_hls_demux_pause_tasks (demux); return; } @@ -834,7 +856,7 @@ gst_hls_demux_updates_loop (GstHLSDemux * demux) } else { GST_ELEMENT_ERROR (demux, RESOURCE, NOT_FOUND, ("Could not update the playlist"), (NULL)); - goto quit; + goto error; } } } @@ -861,7 +883,7 @@ gst_hls_demux_updates_loop (GstHLSDemux * demux) } else { GST_ELEMENT_ERROR (demux, RESOURCE, NOT_FOUND, ("Could not fetch the next fragment"), (NULL)); - goto quit; + goto error; } } } else { @@ -876,7 +898,14 @@ gst_hls_demux_updates_loop (GstHLSDemux * demux) quit: { GST_DEBUG_OBJECT (demux, "Stopped updates task"); - gst_hls_demux_stop (demux); + g_mutex_unlock (&demux->updates_timed_lock); + return; + } + +error: + { + GST_DEBUG_OBJECT (demux, "Stopped updates task because of error"); + gst_hls_demux_pause_tasks (demux); g_mutex_unlock (&demux->updates_timed_lock); } }