From patchwork Thu Jun 23 14:47:34 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomi Valkeinen X-Patchwork-Id: 16343 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id CC360BD808 for ; Thu, 23 Jun 2022 14:48:06 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 277F165647; Thu, 23 Jun 2022 16:48:06 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1655995686; bh=ypyZr0h0B0esoBDRGJv43rUnwKdehaP63OxAJslBc+Q=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=syCXpx4nCTb3CpWpur5eimpbM1ouvl8Wf7ZGoMW66KD88prcwYC+Quh7z7qAhtWtF YzY5azWSrzuBcO9ZQq471jS2s40JVw5qXIBt/zv1F1+MqUF1fiIm+0n3chHlz8eeWC eGb6UMsJ8Rpa3xK9gOeg0avcnY/uu8lRfcyhD/kaKiHBeFQSEULDIzk3op4GIRSZly x0fV/czK/PsWUdRHSD8paAnjN5hw9T3vBbBbTrOgHlQ77L0hfrMJev0jp3SoPnK3+r ZMKny3lO1EgcoHSTfiP6UY1v4JgjID76ynDn3np0F0sstDugUjJhILlIu59tZLrFj7 +WWKilP5c6ECQ== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id F1A6B65636 for ; Thu, 23 Jun 2022 16:47:59 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="BpJnU9oR"; dkim-atps=neutral Received: from deskari.lan (91-158-154-79.elisa-laajakaista.fi [91.158.154.79]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 7069CDD; Thu, 23 Jun 2022 16:47:59 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1655995679; bh=ypyZr0h0B0esoBDRGJv43rUnwKdehaP63OxAJslBc+Q=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=BpJnU9oRv4qBXgVVXu9gwToebJ2SukHbpw1jufxqaOvqM09Onmns2hwv4GwWAqaGA UpgW2jmKMXZ86IyvHvMnVdLjj1G4kIx41SlwvfQr3J+34q7bopOjxUsHyPTHgsaDPP O6FSOQeUUbzzslLQgtowoV29IxdNSK3nDyRMwUXI= To: libcamera-devel@lists.libcamera.org, David Plowman , Kieran Bingham , Laurent Pinchart , Jacopo Mondi Date: Thu, 23 Jun 2022 17:47:34 +0300 Message-Id: <20220623144736.78537-6-tomi.valkeinen@ideasonboard.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220623144736.78537-1-tomi.valkeinen@ideasonboard.com> References: <20220623144736.78537-1-tomi.valkeinen@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [RFC v1 5/7] py: Add 'nonblocking' argument to get_ready_requests() X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Tomi Valkeinen via libcamera-devel From: Tomi Valkeinen Reply-To: Tomi Valkeinen Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Add 'nonblocking' argument to get_ready_requests() which allows the user to ensure get_ready_requests() never blocks. This can be used e.g. after calling camera.stop(), to process or discard any ready or cancelled Requests. In fact, it probably should always be used after stopping the cameras, unless you have made sure that there are no unprocessed Requests. If you start the camera again, and you have left Requests unprocessed, you will get those "old" Requests when you expect to get the new Requests. It may be good to call this even if your script exits after stopping the cameras, as unprocessed Requests will keep the Cameras and related objects alive, and thus they won't be freed. As your script is exiting it's strictly speaking not an issue, but it does make tracking other "real" memory leaks more difficult. Perhaps the camera.start() should go and discard any old Requests related to that camera. For the exit issue I don't see any automatic solution. Signed-off-by: Tomi Valkeinen --- src/py/libcamera/py_camera_manager.cpp | 21 +++++++++++++++++++-- src/py/libcamera/py_camera_manager.h | 4 +++- src/py/libcamera/py_main.cpp | 3 ++- 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/src/py/libcamera/py_camera_manager.cpp b/src/py/libcamera/py_camera_manager.cpp index c9e5a99c..ba45f713 100644 --- a/src/py/libcamera/py_camera_manager.cpp +++ b/src/py/libcamera/py_camera_manager.cpp @@ -5,6 +5,7 @@ #include "py_camera_manager.h" +#include #include #include @@ -55,9 +56,10 @@ py::list PyCameraManager::getCameras() return l; } -std::vector PyCameraManager::getReadyRequests() +std::vector PyCameraManager::getReadyRequests(bool nonBlocking) { - readFd(); + if (!nonBlocking || hasEvents()) + readFd(); std::vector v; getRequests(v); @@ -113,3 +115,18 @@ void PyCameraManager::getRequests(std::vector &v) std::lock_guard guard(reqlist_mutex_); swap(v, reqList_); } + +bool PyCameraManager::hasEvents() +{ + struct pollfd pfd = { + .fd = eventFd_, + .events = POLLIN, + .revents = 0, + }; + + int ret = poll(&pfd, 1, 0); + if (ret == -1) + throw std::system_error(errno, std::generic_category()); + + return pfd.revents & POLLIN; +} diff --git a/src/py/libcamera/py_camera_manager.h b/src/py/libcamera/py_camera_manager.h index b0b971ad..2396d236 100644 --- a/src/py/libcamera/py_camera_manager.h +++ b/src/py/libcamera/py_camera_manager.h @@ -23,7 +23,7 @@ public: int eventFd() const { return eventFd_; } - std::vector getReadyRequests(); + std::vector getReadyRequests(bool nonBlocking = false); void handleRequestCompleted(Request *req); @@ -36,4 +36,6 @@ private: void readFd(); void pushRequest(Request *req); void getRequests(std::vector &v); + + bool hasEvents(); }; diff --git a/src/py/libcamera/py_main.cpp b/src/py/libcamera/py_main.cpp index 23018288..ee4ecb9b 100644 --- a/src/py/libcamera/py_main.cpp +++ b/src/py/libcamera/py_main.cpp @@ -103,7 +103,8 @@ PYBIND11_MODULE(_libcamera, m) .def_property_readonly("cameras", &PyCameraManager::getCameras) .def_property_readonly("event_fd", &PyCameraManager::eventFd) - .def("get_ready_requests", &PyCameraManager::getReadyRequests); + .def("get_ready_requests", &PyCameraManager::getReadyRequests, + py::arg("nonblocking") = false); pyCamera .def_property_readonly("id", &Camera::id)