Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/GStreamer/gstreamer.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Dröge <sebastian@centricular.com>2016-03-11 17:04:52 +0300
committerSebastian Dröge <sebastian@centricular.com>2016-05-20 09:04:45 +0300
commit0c6afcbeb26c0d54f816413bb29bcfc9150608f4 (patch)
tree27b60c006e0ffb685fc8d0b3e2379ee84abcf07b
parent22166a9d5f4c9b28aa3e06a96b60abbc89de02fc (diff)
queue: Only unblock upstream waiting for the query once downstream is finished
... when flushing and deactivating pads. Otherwise downstream might have a query that was already unreffed by upstream, causing crashes or other interesting effects. https://bugzilla.gnome.org/show_bug.cgi?id=763496
-rw-r--r--plugins/elements/gstqueue.c15
-rw-r--r--plugins/elements/gstqueue2.c10
2 files changed, 14 insertions, 11 deletions
diff --git a/plugins/elements/gstqueue.c b/plugins/elements/gstqueue.c
index d7bc1294a2..a0b880c09d 100644
--- a/plugins/elements/gstqueue.c
+++ b/plugins/elements/gstqueue.c
@@ -933,14 +933,20 @@ gst_queue_handle_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
/* unblock the loop and chain functions */
GST_QUEUE_SIGNAL_ADD (queue);
GST_QUEUE_SIGNAL_DEL (queue);
- queue->last_query = FALSE;
- g_cond_signal (&queue->query_handled);
GST_QUEUE_MUTEX_UNLOCK (queue);
/* make sure it pauses, this should happen since we sent
* flush_start downstream. */
gst_pad_pause_task (queue->srcpad);
GST_CAT_LOG_OBJECT (queue_dataflow, queue, "loop stopped");
+
+ /* unblock query handler after the streaming thread is shut down.
+ * Otherwise downstream might have a query that is already unreffed
+ * upstream */
+ GST_QUEUE_MUTEX_LOCK (queue);
+ queue->last_query = FALSE;
+ g_cond_signal (&queue->query_handled);
+ GST_QUEUE_MUTEX_UNLOCK (queue);
break;
case GST_EVENT_FLUSH_STOP:
STATUS (queue, pad, "received flush stop event");
@@ -1676,10 +1682,7 @@ gst_queue_sink_activate_mode (GstPad * pad, GstObject * parent, GstPadMode mode,
GST_QUEUE_MUTEX_LOCK (queue);
queue->srcresult = GST_FLOW_FLUSHING;
/* the item del signal will unblock */
- g_cond_signal (&queue->item_del);
- /* unblock query handler */
- queue->last_query = FALSE;
- g_cond_signal (&queue->query_handled);
+ GST_QUEUE_SIGNAL_DEL (queue);
GST_QUEUE_MUTEX_UNLOCK (queue);
/* step 2, wait until streaming thread stopped and flush queue */
diff --git a/plugins/elements/gstqueue2.c b/plugins/elements/gstqueue2.c
index 6f463c2d57..a69c9092b1 100644
--- a/plugins/elements/gstqueue2.c
+++ b/plugins/elements/gstqueue2.c
@@ -2395,14 +2395,17 @@ gst_queue2_handle_sink_event (GstPad * pad, GstObject * parent,
/* unblock the loop and chain functions */
GST_QUEUE2_SIGNAL_ADD (queue);
GST_QUEUE2_SIGNAL_DEL (queue);
- queue->last_query = FALSE;
- g_cond_signal (&queue->query_handled);
GST_QUEUE2_MUTEX_UNLOCK (queue);
/* make sure it pauses, this should happen since we sent
* flush_start downstream. */
gst_pad_pause_task (queue->srcpad);
GST_CAT_LOG_OBJECT (queue_dataflow, queue, "loop stopped");
+
+ GST_QUEUE2_MUTEX_LOCK (queue);
+ queue->last_query = FALSE;
+ g_cond_signal (&queue->query_handled);
+ GST_QUEUE2_MUTEX_UNLOCK (queue);
} else {
GST_QUEUE2_MUTEX_LOCK (queue);
/* flush the sink pad */
@@ -3373,9 +3376,6 @@ gst_queue2_sink_activate_mode (GstPad * pad, GstObject * parent,
queue->srcresult = GST_FLOW_FLUSHING;
queue->sinkresult = GST_FLOW_FLUSHING;
GST_QUEUE2_SIGNAL_DEL (queue);
- /* Unblock query handler */
- queue->last_query = FALSE;
- g_cond_signal (&queue->query_handled);
GST_QUEUE2_MUTEX_UNLOCK (queue);
/* wait until it is unblocked and clean up */