queue2: Refuse all serialized queries when posting buffering messages
authorEdward Hervey <edward@centricular.com>
Fri, 16 Apr 2021 09:36:33 +0000 (11:36 +0200)
committerEdward Hervey <bilboed@bilboed.com>
Fri, 16 Apr 2021 09:41:26 +0000 (11:41 +0200)
When posting buffering messages there are no safe places or timing to avoid
deadlocks.

Previously the code was trying to be "smart" by only forwarding serialized
queries if the queue was empty ... but that could happen when queue2 hadn't yet
posted a 100% buffering message. Meaning the pipeline might be paused and
pushing a serialized query downstream might never complete.

Therefore let's completely disable forwarding of serialized queries when
`queue2` is used as a buffering element (meaning `ALLOCATION` and `DRAIN`
queries).

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/796>

plugins/elements/gstqueue2.c

index e61caae..6d9dad9 100644 (file)
@@ -2785,10 +2785,14 @@ gst_queue2_handle_sink_query (GstPad * pad, GstObject * parent,
          * be pushed for sure) or we are not buffering. If we are buffering,
          * the pipeline waits to unblock downstream until our queue fills up
          * completely, which can not happen if we block on the query..
-         * Therefore we only potentially block when we are not buffering. */
+         * Therefore we only potentially block when we are not buffering.
+         *
+         * Update: Edward Hervey 2021: Realistically when posting buffering
+         * messages there are no safe places where we can block and forward a
+         * serialized query due to the potential of causing deadlocks. We
+         * therefore refuse any serialized queries in such cases. */
         GST_QUEUE2_MUTEX_LOCK_CHECK (queue, queue->sinkresult, out_flushing);
-        if (QUEUE_IS_USING_QUEUE (queue) && (gst_queue2_is_empty (queue)
-                || !queue->use_buffering)) {
+        if (QUEUE_IS_USING_QUEUE (queue) && !queue->use_buffering) {
           if (!g_atomic_int_get (&queue->downstream_may_block)) {
             gst_queue2_locked_enqueue (queue, query,
                 GST_QUEUE2_ITEM_TYPE_QUERY);
@@ -2807,7 +2811,7 @@ gst_queue2_handle_sink_query (GstPad * pad, GstObject * parent,
           }
         } else {
           GST_DEBUG_OBJECT (queue,
-              "refusing query, we are not using the queue");
+              "refusing query, we are not using the queue or we are posting buffering messages");
           res = FALSE;
         }
         GST_QUEUE2_MUTEX_UNLOCK (queue);