downloadbuffer: Check for flush after seek
authorAlicia Boya García <ntrrgc@gmail.com>
Mon, 22 Jul 2019 15:06:20 +0000 (15:06 +0000)
committerTim-Philipp Müller <tim@centricular.com>
Sun, 11 Aug 2019 11:37:45 +0000 (12:37 +0100)
In gst_download_buffer_wait_for_data(), when a seek is made with
perform_seek_to_offset() the `qlock` is released temporarily. Therefore,
the flushing condition can be set during this period and should be
checked.

This was not being checked before, causing occasional deadlocks when
GST_DOWNLOAD_BUFFER_WAIT_ADD_CHECK() was called.

GST_DOWNLOAD_BUFFER_WAIT_ADD_CHECK() assumes that the caller has already
checked that we're not flushing before, since this is done when
acquiring the lock; so if we release it temporarily somewhere, we need
to check for flush again.

Without that check, the function would keep waiting for the condition
variable to be notified before checking for flushing condition again,
and that may very well never happen. This was reproduced when during pad
deactivation when running WebKit in gdb.

plugins/elements/gstdownloadbuffer.c

index 6f67e78..2bdc43d 100644 (file)
@@ -703,9 +703,15 @@ gst_download_buffer_wait_for_data (GstDownloadBuffer * dlbuf, guint64 offset,
     }
   }
 
-  if (dlbuf->write_pos != offset)
+  if (dlbuf->write_pos != offset) {
     perform_seek_to_offset (dlbuf, offset);
 
+    /* perform_seek_to_offset() releases the lock, so we may have been flushed
+     * during the call. */
+    if (dlbuf->srcresult == GST_FLOW_FLUSHING)
+      goto out_flushing;
+  }
+
   dlbuf->filling = TRUE;
   if (dlbuf->write_pos > dlbuf->read_pos)
     update_levels (dlbuf, dlbuf->write_pos - dlbuf->read_pos);