{"id":23696,"url":"https://patchwork.libcamera.org/api/patches/23696/?format=json","web_url":"https://patchwork.libcamera.org/patch/23696/","project":{"id":1,"url":"https://patchwork.libcamera.org/api/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":"<20250701045805.15201-1-uajain@igalia.com>","date":"2025-07-01T04:58:05","name":"libcamera: pipeline_hander: Return -EAGAIN if pipeline is saturated","commit_ref":null,"pull_url":null,"state":"superseded","archived":false,"hash":"78edc7c00765e1370546f55687320011ae5465ff","submitter":{"id":232,"url":"https://patchwork.libcamera.org/api/people/232/?format=json","name":"Umang Jain","email":"uajain@igalia.com"},"delegate":null,"mbox":"https://patchwork.libcamera.org/patch/23696/mbox/","series":[{"id":5259,"url":"https://patchwork.libcamera.org/api/series/5259/?format=json","web_url":"https://patchwork.libcamera.org/project/libcamera/list/?series=5259","date":"2025-07-01T04:58:05","name":"libcamera: pipeline_hander: Return -EAGAIN if pipeline is saturated","version":1,"mbox":"https://patchwork.libcamera.org/series/5259/mbox/"}],"comments":"https://patchwork.libcamera.org/api/patches/23696/comments/","check":"pending","checks":"https://patchwork.libcamera.org/api/patches/23696/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 9B910C3237\n\tfor <parsemail@patchwork.libcamera.org>;\n\tTue,  1 Jul 2025 04:58:12 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 6162F68E0E;\n\tTue,  1 Jul 2025 06:58:11 +0200 (CEST)","from fanzine2.igalia.com (fanzine2.igalia.com [213.97.179.56])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 1C43161524\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue,  1 Jul 2025 06:58:08 +0200 (CEST)","from [49.36.69.141] (helo=uajain)\n\tby fanzine2.igalia.com with esmtpsa \n\t(Cipher TLS1.3:ECDHE_X25519__RSA_PSS_RSAE_SHA256__AES_256_GCM:256)\n\t(Exim) id 1uWT4I-00AoPg-IL; Tue, 01 Jul 2025 06:58:07 +0200"],"Authentication-Results":"lancelot.ideasonboard.com;\n\tdkim=fail reason=\"signature verification failed\" (2048-bit key;\n\tunprotected) header.d=igalia.com header.i=@igalia.com\n\theader.b=\"ocQqqCv6\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=igalia.com;\n\ts=20170329;\n\th=Content-Transfer-Encoding:MIME-Version:Message-ID:Date:Subject:\n\tCc:To:From:Sender:Reply-To:Content-Type:Content-ID:Content-Description:\n\tResent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:\n\tIn-Reply-To:References:List-Id:List-Help:List-Unsubscribe:List-Subscribe:\n\tList-Post:List-Owner:List-Archive;\n\tbh=8lpcsVU2/8nvPxz6mt5TdzX3rdo0vrIYA1xtGdiqkFY=;\n\tb=ocQqqCv6b9oTn+96LTpTHLWuH9\n\tjW8ONnLGi5M2jjburv0oxeJEMsQNJ83CrrpUIQYnE2koHJxYA4HDPh/KN3t6ZO3azhWYEqXNGyHKr\n\tKcE905mAZod2Duo6SsV0ySAkMMt7N6+TC73cro3a8dOoDgLuc/SIjwdfpzikKPOVJGO6x8gRKDS73\n\tr3ONDY6RmV6AJdY4IhbdKdukyb+mSHTkdPM6hN5YGu1sw28EOrowagU5PnTvzFxGMwfMO6iM4fNn4\n\tmsKzFK/oauZpIVXntJ9YUzO2bpEhGUooYyAu9CHyVdd6CcSngVUhINY/J9ZmPGMg5HXzpHqHvDGYO\n\t7DJoYSoQ==;","From":"Umang Jain <uajain@igalia.com>","To":"libcamera-devel@lists.libcamera.org","Cc":"Stefan Klug <stefan.klug@ideasonboard.com>,\n\tUmang Jain <uajain@igalia.com>","Subject":"[PATCH] libcamera: pipeline_hander: Return -EAGAIN if pipeline is\n\tsaturated","Date":"Tue,  1 Jul 2025 10:28:05 +0530","Message-ID":"<20250701045805.15201-1-uajain@igalia.com>","X-Mailer":"git-send-email 2.50.0","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":"PipelineHandler::queueRequestDevice() returns a negative error code if\nthe request fails to get queued to the underlying hardware. One such\ncase would be if the hardware is saturated with requests beyond its\nlimits, in which case queueRequestDevice() should return -EAGAIN.\n\nThis way, each pipeline handler can keep their limits internal and\ndecide to start returning -EAGAIN if they foresee their pipelines\nqueues getting over-saturated with requests.\n\nHence, returns error codes from doQueueRequest() so that\ndoQueueRequests() can make an inform decision whether to pop off the\nrequests from the internal waiting queue or not.\n\nSigned-off-by: Umang Jain <uajain@igalia.com>\n---\n include/libcamera/internal/pipeline_handler.h |  2 +-\n src/libcamera/pipeline_handler.cpp            | 20 ++++++++++++++-----\n 2 files changed, 16 insertions(+), 6 deletions(-)","diff":"diff --git a/include/libcamera/internal/pipeline_handler.h b/include/libcamera/internal/pipeline_handler.h\nindex 972a2fa6..35252e3a 100644\n--- a/include/libcamera/internal/pipeline_handler.h\n+++ b/include/libcamera/internal/pipeline_handler.h\n@@ -88,7 +88,7 @@ private:\n \tvoid mediaDeviceDisconnected(MediaDevice *media);\n \tvirtual void disconnect();\n \n-\tvoid doQueueRequest(Request *request);\n+\tint doQueueRequest(Request *request);\n \tvoid doQueueRequests();\n \n \tstd::vector<std::shared_ptr<MediaDevice>> mediaDevices_;\ndiff --git a/src/libcamera/pipeline_handler.cpp b/src/libcamera/pipeline_handler.cpp\nindex d84dff3c..2ce093ff 100644\n--- a/src/libcamera/pipeline_handler.cpp\n+++ b/src/libcamera/pipeline_handler.cpp\n@@ -452,8 +452,10 @@ void PipelineHandler::queueRequest(Request *request)\n /**\n  * \\brief Queue one requests to the device\n  */\n-void PipelineHandler::doQueueRequest(Request *request)\n+int PipelineHandler::doQueueRequest(Request *request)\n {\n+\tint ret;\n+\n \tLIBCAMERA_TRACEPOINT(request_device_queue, request);\n \n \tCamera *camera = request->_d()->camera();\n@@ -464,12 +466,14 @@ void PipelineHandler::doQueueRequest(Request *request)\n \n \tif (request->_d()->cancelled_) {\n \t\tcompleteRequest(request);\n-\t\treturn;\n+\t\treturn -ECANCELED;\n \t}\n \n-\tint ret = queueRequestDevice(camera, request);\n-\tif (ret)\n+\tret = queueRequestDevice(camera, request);\n+\tif (ret && ret != -EAGAIN)\n \t\tcancelRequest(request);\n+\n+\treturn ret;\n }\n \n /**\n@@ -485,7 +489,9 @@ void PipelineHandler::doQueueRequests()\n \t\tif (!request->_d()->prepared_)\n \t\t\tbreak;\n \n-\t\tdoQueueRequest(request);\n+\t\tif (doQueueRequest(request) == -EAGAIN)\n+\t\t\tbreak;\n+\n \t\twaitingRequests_.pop();\n \t}\n }\n@@ -502,6 +508,10 @@ void PipelineHandler::doQueueRequests()\n  * parameters will be applied to the frames captured in the buffers provided in\n  * the request.\n  *\n+ * If the underlying hardware pipeline is saturated with requests, this\n+ * function returns -EAGAIN, so that the \\a request stays in the internal\n+ * waiting queue.\n+ *\n  * \\context This function is called from the CameraManager thread.\n  *\n  * \\return 0 on success or a negative error code otherwise\n","prefixes":[]}