hlsdemux: Fix lots of deadlocks caused by race conditions in the task state handling
authorSebastian Dröge <sebastian.droege@collabora.co.uk>
Mon, 15 Oct 2012 07:24:01 +0000 (09:24 +0200)
committerSebastian Dröge <sebastian.droege@collabora.co.uk>
Mon, 15 Oct 2012 07:44:09 +0000 (09:44 +0200)
gst/hls/gsthlsdemux.c

index e39b2cc8ad4fdfb91a57cf3070351507b75e9703..10465542a774818c172c58722b12e4b841c57673 100644 (file)
@@ -126,6 +126,8 @@ gst_hls_demux_dispose (GObject * obj)
     if (GST_TASK_STATE (demux->stream_task) != GST_TASK_STOPPED) {
       GST_DEBUG_OBJECT (demux, "Leaving streaming task");
       gst_task_stop (demux->stream_task);
+      g_static_rec_mutex_lock (&demux->stream_lock);
+      g_static_rec_mutex_unlock (&demux->stream_lock);
       gst_task_join (demux->stream_task);
     }
     gst_object_unref (demux->stream_task);
@@ -137,6 +139,9 @@ gst_hls_demux_dispose (GObject * obj)
     if (GST_TASK_STATE (demux->updates_task) != GST_TASK_STOPPED) {
       GST_DEBUG_OBJECT (demux, "Leaving updates task");
       gst_task_stop (demux->updates_task);
+      GST_TASK_SIGNAL (demux->updates_task);
+      g_static_rec_mutex_lock (&demux->updates_lock);
+      g_static_rec_mutex_unlock (&demux->updates_lock);
       gst_task_join (demux->updates_task);
     }
     gst_object_unref (demux->updates_task);
@@ -316,6 +321,9 @@ gst_hls_demux_change_state (GstElement * element, GstStateChange transition)
   switch (transition) {
     case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
       gst_task_stop (demux->updates_task);
+      GST_TASK_SIGNAL (demux->updates_task);
+      g_static_rec_mutex_lock (&demux->updates_lock);
+      g_static_rec_mutex_unlock (&demux->updates_lock);
       break;
     case GST_STATE_CHANGE_PAUSED_TO_READY:
       demux->cancelled = TRUE;
@@ -397,6 +405,9 @@ gst_hls_demux_src_event (GstPad * pad, GstObject * parent, GstEvent * event)
       gst_task_pause (demux->stream_task);
       gst_uri_downloader_cancel (demux->downloader);
       gst_task_stop (demux->updates_task);
+      GST_TASK_SIGNAL (demux->updates_task);
+      g_static_rec_mutex_lock (&demux->updates_lock);
+      g_static_rec_mutex_unlock (&demux->updates_lock);
       gst_task_pause (demux->stream_task);
 
       /* wait for streaming to finish */
@@ -592,10 +603,15 @@ gst_hls_demux_stop (GstHLSDemux * demux)
     demux->stop_stream_task = TRUE;
     gst_task_stop (demux->updates_task);
     GST_TASK_SIGNAL (demux->updates_task);
+    g_static_rec_mutex_lock (&demux->updates_lock);
+    g_static_rec_mutex_unlock (&demux->updates_lock);
   }
 
-  if (GST_TASK_STATE (demux->stream_task) != GST_TASK_STOPPED)
+  if (GST_TASK_STATE (demux->stream_task) != GST_TASK_STOPPED) {
     gst_task_stop (demux->stream_task);
+    g_static_rec_mutex_lock (&demux->stream_lock);
+    g_static_rec_mutex_unlock (&demux->stream_lock);
+  }
 }
 
 static void