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>
This commit is contained in:
Nicolas Dufresne 2021-08-26 09:23:46 -04:00 committed by Laurent Pinchart
parent 9c49106b97
commit d3be776654

View file

@ -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)) {