{"id":23692,"url":"https://patchwork.libcamera.org/api/1.1/patches/23692/?format=json","web_url":"https://patchwork.libcamera.org/patch/23692/","project":{"id":1,"url":"https://patchwork.libcamera.org/api/1.1/projects/1/?format=json","name":"libcamera","link_name":"libcamera","list_id":"libcamera_core","list_email":"libcamera-devel@lists.libcamera.org","web_url":"","scm_url":"","webscm_url":""},"msgid":"<20250630081126.2384387-7-stefan.klug@ideasonboard.com>","date":"2025-06-30T08:11:21","name":"[v1,6/6] libcamera: pipeline_handler: cancel waiting requests first","commit_ref":null,"pull_url":null,"state":"superseded","archived":false,"hash":"a7ba4290294c79d09ab19b96c5f1d612d9db8553","submitter":{"id":184,"url":"https://patchwork.libcamera.org/api/1.1/people/184/?format=json","name":"Stefan Klug","email":"stefan.klug@ideasonboard.com"},"delegate":null,"mbox":"https://patchwork.libcamera.org/patch/23692/mbox/","series":[{"id":5257,"url":"https://patchwork.libcamera.org/api/1.1/series/5257/?format=json","web_url":"https://patchwork.libcamera.org/project/libcamera/list/?series=5257","date":"2025-06-30T08:11:15","name":"rkisp1: Allow usage of more than 4 buffers","version":1,"mbox":"https://patchwork.libcamera.org/series/5257/mbox/"}],"comments":"https://patchwork.libcamera.org/api/patches/23692/comments/","check":"pending","checks":"https://patchwork.libcamera.org/api/patches/23692/checks/","tags":{},"headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 885D1C3237\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon, 30 Jun 2025 08:11:55 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 4407F68E0D;\n\tMon, 30 Jun 2025 10:11:54 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 6EF0B68E12\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 30 Jun 2025 10:11:50 +0200 (CEST)","from ideasonboard.com (unknown\n\t[IPv6:2a00:6020:448c:6c00:883b:eaf8:7aec:d1d4])\n\tby perceval.ideasonboard.com (Postfix) with UTF8SMTPSA id CFEBD16B8; \n\tMon, 30 Jun 2025 10:11:28 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"CQNp98F7\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1751271088;\n\tbh=TgrIkSU6tKIpjOwsgYCV1nBzb/y3gOE6vyBU1pvFPmI=;\n\th=From:To:Cc:Subject:Date:In-Reply-To:References:From;\n\tb=CQNp98F7CWOCV4LwaJX5QzFOUIq/meI/cbgll6T0J2DbFNc+tgTjx1sCQofd7p2pS\n\tdWLh0MBviVvy2bMnShfo6NrjN05w9I8KyaG42QLvhI8cp2BvoPsKYv9We1XPPKqJGT\n\tByDWKP0mZgPfPoyvffEAu0d7r/CcyWA5Ni18J5O4=","From":"Stefan Klug <stefan.klug@ideasonboard.com>","To":"libcamera-devel@lists.libcamera.org","Cc":"Stefan Klug <stefan.klug@ideasonboard.com>,\n\tKieran Bingham <kieran.bingham@ideasonboard.com>","Subject":"[PATCH v1 6/6] libcamera: pipeline_handler: cancel waiting requests\n\tfirst","Date":"Mon, 30 Jun 2025 10:11:21 +0200","Message-ID":"<20250630081126.2384387-7-stefan.klug@ideasonboard.com>","X-Mailer":"git-send-email 2.48.1","In-Reply-To":"<20250630081126.2384387-1-stefan.klug@ideasonboard.com>","References":"<20250630081126.2384387-1-stefan.klug@ideasonboard.com>","MIME-Version":"1.0","Content-Transfer-Encoding":"8bit","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"},"content":"From: Kieran Bingham <kieran.bingham@ideasonboard.com>\n\nWhen stopping a camera, we may now find that there are requests\nqueued to the camera but not yet available in the pipeline handler.\n\nThese are \"waitingReqeusts\" which are not yet queued to the device.\n\nWhile stopping a camera, we ask the pipeline to stop with stopDevice()\nand then cancel any waiting requests after.\n\nThis however can lead to a race where having stopped the camera and\ncompleted the requests, the pipeline may try to further consume requests\nfrom the waiting lists.\n\nTherefore empty the waitingRequests queue before stopping the device and\ncancel the waitingRequests afterwards.\n\nSigned-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\nSigned-off-by: Stefan Klug <stefan.klug@ideasonboard.com>\n---\n src/libcamera/pipeline_handler.cpp | 18 +++++++++++++-----\n 1 file changed, 13 insertions(+), 5 deletions(-)","diff":"diff --git a/src/libcamera/pipeline_handler.cpp b/src/libcamera/pipeline_handler.cpp\nindex 383c6ad0c4aa..207a2bae96d6 100644\n--- a/src/libcamera/pipeline_handler.cpp\n+++ b/src/libcamera/pipeline_handler.cpp\n@@ -364,20 +364,28 @@ void PipelineHandler::unlockMediaDevices()\n  */\n void PipelineHandler::stop(Camera *camera)\n {\n+\t/*\n+\t * Take all waiting requests so that they are not requeued in response\n+\t * to completeRequest() being called inside stopDevice(). Cancel them\n+\t * after the device to keep them in order.\n+\t */\n+\tCamera::Private *data = camera->_d();\n+\tstd::queue<Request *> waitingRequests;\n+\twaitingRequests.swap(data->waitingRequests_);\n+\n \t/* Stop the pipeline handler and let the queued requests complete. */\n \tstopDevice(camera);\n \n-\tCamera::Private *data = camera->_d();\n-\n \t/* Cancel and signal as complete all waiting requests. */\n-\twhile (!data->waitingRequests_.empty()) {\n-\t\tRequest *request = data->waitingRequests_.front();\n-\t\tdata->waitingRequests_.pop();\n+\twhile (!waitingRequests.empty()) {\n+\t\tRequest *request = waitingRequests.front();\n+\t\twaitingRequests.pop();\n \t\tcancelRequest(request);\n \t}\n \n \t/* Make sure no requests are pending. */\n \tASSERT(data->queuedRequests_.empty());\n+\tASSERT(data->waitingRequests_.empty());\n \n \tdata->requestSequence_ = 0;\n }\n","prefixes":["v1","6/6"]}