summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolas Dufresne <nicolas.dufresne@collabora.com>2021-08-26 09:23:46 -0400
committerLaurent Pinchart <laurent.pinchart@ideasonboard.com>2021-08-26 16:42:54 +0300
commitd3be776654076f7048c4365190535c0a2c39ad51 (patch)
treed12cb5a3a3be4cecb359aadf266ff60b37ccc256
parent9c49106b9709da130d81bff913db8ce2daecd9b6 (diff)
libcamerasrc: Fix deadlock on EOS
It's not allowed in GStreamer to push events while holding the object lock. This reduce the scope into which we hold the object lock. In fact we don't need to protect against gst_task_resume() concurrency when we stop the task as resume only do something if the task is paused. This fixes a deadlock when running multiple instances of libcamerasrc and closing one of the streaming window. Signed-off-by: Nicolas Dufresne <nicolas.dufresne@collabora.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Tested-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
-rw-r--r--src/gstreamer/gstlibcamerasrc.cpp12
1 files changed, 6 insertions, 6 deletions
diff --git a/src/gstreamer/gstlibcamerasrc.cpp b/src/gstreamer/gstlibcamerasrc.cpp
index 512fbbc1..55de1467 100644
--- a/src/gstreamer/gstlibcamerasrc.cpp
+++ b/src/gstreamer/gstlibcamerasrc.cpp
@@ -316,12 +316,6 @@ gst_libcamera_src_task_run(gpointer user_data)
}
{
- /*
- * Here we need to decide if we want to pause or stop the task. This
- * needs to happen in lock step with the callback thread which may want
- * to resume the task.
- */
- GLibLocker lock(GST_OBJECT(self));
if (ret != GST_FLOW_OK) {
if (ret == GST_FLOW_EOS) {
g_autoptr(GstEvent) eos = gst_event_new_eos();
@@ -336,6 +330,12 @@ gst_libcamera_src_task_run(gpointer user_data)
return;
}
+ /*
+ * Here we need to decide if we want to pause. This needs to
+ * happen in lock step with the callback thread which may want
+ * to resume the task and might push pending buffers.
+ */
+ GLibLocker lock(GST_OBJECT(self));
bool do_pause = true;
for (GstPad *srcpad : state->srcpads_) {
if (gst_libcamera_pad_has_pending(srcpad)) {