From patchwork Fri Aug 19 11:16:10 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomi Valkeinen X-Patchwork-Id: 17176 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 92A25BE173 for ; Fri, 19 Aug 2022 11:16:35 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 023D961FC6; Fri, 19 Aug 2022 13:16:34 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1660907794; bh=fRRMCVBoNG8Bc6PNJEDWJE/dhM/dWtpWrWuxVQ6kOj4=; 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=IDxikQgk5EYPQg46S4JHqKeZ+oQ+4VjK3ixO8Xr2UJL5kKiGLeju5CQiNc0IKySEd u/L73Z7aYuNJfICwcIjjD2VVdknu115QtQhsUyQ9fCoc//pz0QWp++bIt+tvHbZdea CNOBqAog2rt31u6to1G4g/Hx4h7XROtvdwRn446maWPhoqPOa1jg4f2Tgq3YyI1lCP rSIz1A93r76pDhIVV6x3Z3cXKViMzw1kvYM06oDO/GitBI/ZAFKKcRbiTGXlWJw8y/ cBJKKAxh9sVzPHXZWWakkoTpYQBLQDjab+YCoDbsgcQzF/x+QJkILMDigaeI3lYKcu RLHq5JNA9jpUw== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id DE98761FA5 for ; Fri, 19 Aug 2022 13:16:30 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="AGBsq8c6"; 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 2AD5D576; Fri, 19 Aug 2022 13:16:30 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1660907790; bh=fRRMCVBoNG8Bc6PNJEDWJE/dhM/dWtpWrWuxVQ6kOj4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=AGBsq8c61CBS93XsYh+/XKj62+hzi5as3yAN8UOOUz21xLjCOoi1LFnqRxWdsME4h unTjOv4dP9C9nTbgy8TAVMrP4cJNSqBVsT/QXRgbF0JNVN6Wg/ukxzb0AJNCAM2Ouh tj8YnCwret1K4XgYvhefcPOSK8DHcBsjo/iV4Kcc= To: libcamera-devel@lists.libcamera.org, David Plowman , Kieran Bingham , Laurent Pinchart , Jacopo Mondi Date: Fri, 19 Aug 2022 14:16:10 +0300 Message-Id: <20220819111615.39814-2-tomi.valkeinen@ideasonboard.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220819111615.39814-1-tomi.valkeinen@ideasonboard.com> References: <20220819111615.39814-1-tomi.valkeinen@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v4 1/6] py: meson: Use libcamera_private dependency 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" We define -DLIBCAMERA_BASE_PRIVATE to get access to libcamera private headers, but the correct way to do this is to have a meson dependency to libcamera_private. Signed-off-by: Tomi Valkeinen Reviewed-by: Laurent Pinchart --- src/py/libcamera/meson.build | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/py/libcamera/meson.build b/src/py/libcamera/meson.build index 04578bac..99c2a8c0 100644 --- a/src/py/libcamera/meson.build +++ b/src/py/libcamera/meson.build @@ -60,7 +60,7 @@ pycamera_sources += custom_target('py_gen_formats', command : [gen_py_formats, '-o', '@OUTPUT@', '@INPUT@']) pycamera_deps = [ - libcamera_public, + libcamera_private, py3_dep, pybind11_dep, ] @@ -69,7 +69,6 @@ pycamera_args = [ '-fvisibility=hidden', '-Wno-shadow', '-DPYBIND11_USE_SMART_HOLDER_AS_DEFAULT', - '-DLIBCAMERA_BASE_PRIVATE', ] destdir = get_option('libdir') / ('python' + py3_dep.version()) / 'site-packages' / 'libcamera' From patchwork Fri Aug 19 11:16:11 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomi Valkeinen X-Patchwork-Id: 17177 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 523D9C3275 for ; Fri, 19 Aug 2022 11:16:36 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 12C5861FC3; Fri, 19 Aug 2022 13:16:35 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1660907795; bh=70FpsWphMwFsXjxrhbtR98Jo89gAd0RatrFTkqPgPgg=; 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=fzgzFsRUrQ8zptmH1J9Bjo6y8NUjPmRMxLTfXRKShKPzIj1uYr75tkphAwpIyMhCm G7s7IOQE61lKsuEPZOAm2n+Zp5VS51/4dwIOlFfOl89Yxm3IBzBZlt0Q2jqZIWlv4L mA3Wjv36n3dX7SiUPDHqVW+9qQmNaG5vlZNiXL7pj7sLT+9lVl8dkpjdgZfO1ryVup j5gDB144hqNBfninfUMJbo4zQiBW62CdrSRDxK8PdgeVpiSuItIBMUCRHNejduXLxt caVVMab6dJZEGvgslo1Nx9FnmbU9zcVwFujnKVsInbSnlgqFGrAKaXGpgpyL0h8kVh +WHSUSkTPdjWA== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 3544961FA4 for ; Fri, 19 Aug 2022 13:16:31 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="N5ZGagFw"; 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 A6D9C59D; Fri, 19 Aug 2022 13:16:30 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1660907791; bh=70FpsWphMwFsXjxrhbtR98Jo89gAd0RatrFTkqPgPgg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=N5ZGagFwlw3PQuZEkCxuUO/3/gf9n/thowHM39mexARKMNdxef/3lf1ohRRmrd7On L6QB3qTGhwz+k4U5PmVHk+NPKtHuGok/Dj8t6rPf5jzhw6xFg5bI1+MJn1VHpC5Qwp awe6asDA94BA0awkNh/yBdhTEG7QVe/pz2mu/6Wg= To: libcamera-devel@lists.libcamera.org, David Plowman , Kieran Bingham , Laurent Pinchart , Jacopo Mondi Date: Fri, 19 Aug 2022 14:16:11 +0300 Message-Id: <20220819111615.39814-3-tomi.valkeinen@ideasonboard.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220819111615.39814-1-tomi.valkeinen@ideasonboard.com> References: <20220819111615.39814-1-tomi.valkeinen@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v4 2/6] py: Create PyCameraManager 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" Wrap the CameraManager with a PyCameraManager class and move the related code inside the new class. This helps understanding the life times of the used-to-be global variables, gets rid of static handleRequestCompleted function, and allows us to simplify the binding code as the more complex pieces are inside the class. There should be no user visible functional changes. Signed-off-by: Tomi Valkeinen Reviewed-by: Laurent Pinchart --- src/py/libcamera/meson.build | 1 + src/py/libcamera/py_camera_manager.cpp | 127 +++++++++++++++++++++++++ src/py/libcamera/py_camera_manager.h | 44 +++++++++ src/py/libcamera/py_main.cpp | 120 +++++------------------ 4 files changed, 198 insertions(+), 94 deletions(-) create mode 100644 src/py/libcamera/py_camera_manager.cpp create mode 100644 src/py/libcamera/py_camera_manager.h diff --git a/src/py/libcamera/meson.build b/src/py/libcamera/meson.build index 99c2a8c0..af19ffdd 100644 --- a/src/py/libcamera/meson.build +++ b/src/py/libcamera/meson.build @@ -13,6 +13,7 @@ pybind11_proj = subproject('pybind11') pybind11_dep = pybind11_proj.get_variable('pybind11_dep') pycamera_sources = files([ + 'py_camera_manager.cpp', 'py_enums.cpp', 'py_geometry.cpp', 'py_helpers.cpp', diff --git a/src/py/libcamera/py_camera_manager.cpp b/src/py/libcamera/py_camera_manager.cpp new file mode 100644 index 00000000..228fb212 --- /dev/null +++ b/src/py/libcamera/py_camera_manager.cpp @@ -0,0 +1,127 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2022, Tomi Valkeinen + */ + +#include "py_camera_manager.h" + +#include +#include +#include +#include +#include +#include + +#include "py_main.h" + +namespace py = pybind11; + +using namespace libcamera; + +PyCameraManager::PyCameraManager() +{ + LOG(Python, Debug) << "PyCameraManager()"; + + cameraManager_ = std::make_unique(); + + int fd = eventfd(0, 0); + if (fd == -1) + throw std::system_error(errno, std::generic_category(), + "Failed to create eventfd"); + + eventFd_ = fd; + + int ret = cameraManager_->start(); + if (ret) { + close(fd); + eventFd_ = -1; + throw std::system_error(-ret, std::generic_category(), + "Failed to start CameraManager"); + } +} + +PyCameraManager::~PyCameraManager() +{ + LOG(Python, Debug) << "~PyCameraManager()"; + + if (eventFd_ != -1) { + close(eventFd_); + eventFd_ = -1; + } +} + +py::list PyCameraManager::cameras() +{ + /* + * Create a list of Cameras, where each camera has a keep-alive to + * CameraManager. + */ + py::list l; + + for (auto &camera : cameraManager_->cameras()) { + py::object py_cm = py::cast(this); + py::object py_cam = py::cast(camera); + py::detail::keep_alive_impl(py_cam, py_cm); + l.append(py_cam); + } + + return l; +} + +std::vector PyCameraManager::getReadyRequests() +{ + readFd(); + + std::vector py_reqs; + + for (Request *request : getCompletedRequests()) { + py::object o = py::cast(request); + /* Decrease the ref increased in Camera.queue_request() */ + o.dec_ref(); + py_reqs.push_back(o); + } + + return py_reqs; +} + +/* Note: Called from another thread */ +void PyCameraManager::handleRequestCompleted(Request *req) +{ + pushRequest(req); + writeFd(); +} + +void PyCameraManager::writeFd() +{ + uint64_t v = 1; + + size_t s = write(eventFd_, &v, 8); + /* + * We should never fail, and have no simple means to manage the error, + * so let's log a fatal error. + */ + if (s != 8) + LOG(Python, Fatal) << "Unable to write to eventfd"; +} + +void PyCameraManager::readFd() +{ + uint8_t buf[8]; + + if (read(eventFd_, buf, 8) != 8) + throw std::system_error(errno, std::generic_category()); +} + +void PyCameraManager::pushRequest(Request *req) +{ + std::lock_guard guard(completedRequestsMutex_); + completedRequests_.push_back(req); +} + +std::vector PyCameraManager::getCompletedRequests() +{ + std::vector v; + std::lock_guard guard(completedRequestsMutex_); + swap(v, completedRequests_); + return v; +} diff --git a/src/py/libcamera/py_camera_manager.h b/src/py/libcamera/py_camera_manager.h new file mode 100644 index 00000000..9c15f814 --- /dev/null +++ b/src/py/libcamera/py_camera_manager.h @@ -0,0 +1,44 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2022, Tomi Valkeinen + */ + +#pragma once + +#include + +#include + +#include + +using namespace libcamera; + +class PyCameraManager +{ +public: + PyCameraManager(); + ~PyCameraManager(); + + pybind11::list cameras(); + std::shared_ptr get(const std::string &name) { return cameraManager_->get(name); } + + static const std::string &version() { return CameraManager::version(); } + + int eventFd() const { return eventFd_; } + + std::vector getReadyRequests(); + + void handleRequestCompleted(Request *req); + +private: + std::unique_ptr cameraManager_; + + int eventFd_ = -1; + std::mutex completedRequestsMutex_; + std::vector completedRequests_; + + void writeFd(); + void readFd(); + void pushRequest(Request *req); + std::vector getCompletedRequests(); +}; diff --git a/src/py/libcamera/py_main.cpp b/src/py/libcamera/py_main.cpp index e652837f..7e613a3f 100644 --- a/src/py/libcamera/py_main.cpp +++ b/src/py/libcamera/py_main.cpp @@ -7,10 +7,10 @@ #include "py_main.h" -#include +#include #include -#include -#include +#include +#include #include @@ -21,6 +21,7 @@ #include #include +#include "py_camera_manager.h" #include "py_helpers.h" namespace py = pybind11; @@ -33,27 +34,11 @@ LOG_DEFINE_CATEGORY(Python) } -static std::weak_ptr gCameraManager; -static int gEventfd; -static std::mutex gReqlistMutex; -static std::vector gReqList; - -static void handleRequestCompleted(Request *req) -{ - { - std::lock_guard guard(gReqlistMutex); - gReqList.push_back(req); - } - - uint64_t v = 1; - size_t s = write(gEventfd, &v, 8); - /* - * We should never fail, and have no simple means to manage the error, - * so let's log a fatal error. - */ - if (s != 8) - LOG(Python, Fatal) << "Unable to write to eventfd"; -} +/* + * Note: global C++ destructors can be ran on this before the py module is + * destructed. + */ +static std::weak_ptr gCameraManager; void init_py_enums(py::module &m); void init_py_controls_generated(py::module &m); @@ -76,7 +61,7 @@ PYBIND11_MODULE(_libcamera, m) * https://pybind11.readthedocs.io/en/latest/advanced/misc.html#avoiding-c-types-in-docstrings */ - auto pyCameraManager = py::class_(m, "CameraManager"); + auto pyCameraManager = py::class_(m, "CameraManager"); auto pyCamera = py::class_(m, "Camera"); auto pyCameraConfiguration = py::class_(m, "CameraConfiguration"); auto pyCameraConfigurationStatus = py::enum_(pyCameraConfiguration, "Status"); @@ -110,78 +95,22 @@ PYBIND11_MODULE(_libcamera, m) /* Classes */ pyCameraManager .def_static("singleton", []() { - std::shared_ptr cm = gCameraManager.lock(); - if (cm) - return cm; - - int fd = eventfd(0, 0); - if (fd == -1) - throw std::system_error(errno, std::generic_category(), - "Failed to create eventfd"); - - cm = std::shared_ptr(new CameraManager, [](auto p) { - close(gEventfd); - gEventfd = -1; - delete p; - }); - - gEventfd = fd; - gCameraManager = cm; - - int ret = cm->start(); - if (ret) - throw std::system_error(-ret, std::generic_category(), - "Failed to start CameraManager"); - - return cm; - }) - - .def_property_readonly("version", &CameraManager::version) + std::shared_ptr cm = gCameraManager.lock(); - .def_property_readonly("event_fd", [](CameraManager &) { - return gEventfd; - }) - - .def("get_ready_requests", [](CameraManager &) { - uint8_t buf[8]; - - if (read(gEventfd, buf, 8) != 8) - throw std::system_error(errno, std::generic_category()); - - std::vector v; - - { - std::lock_guard guard(gReqlistMutex); - swap(v, gReqList); + if (!cm) { + cm = std::make_shared(); + gCameraManager = cm; } - std::vector ret; - - for (Request *req : v) { - py::object o = py::cast(req); - /* Decrease the ref increased in Camera.queue_request() */ - o.dec_ref(); - ret.push_back(o); - } - - return ret; + return cm; }) - .def("get", py::overload_cast(&CameraManager::get), py::keep_alive<0, 1>()) - - /* Create a list of Cameras, where each camera has a keep-alive to CameraManager */ - .def_property_readonly("cameras", [](CameraManager &self) { - py::list l; - - for (auto &c : self.cameras()) { - py::object py_cm = py::cast(self); - py::object py_cam = py::cast(c); - py::detail::keep_alive_impl(py_cam, py_cm); - l.append(py_cam); - } + .def_property_readonly("version", &PyCameraManager::version) + .def("get", &PyCameraManager::get, py::keep_alive<0, 1>()) + .def_property_readonly("cameras", &PyCameraManager::cameras) - return l; - }); + .def_property_readonly("event_fd", &PyCameraManager::eventFd) + .def("get_ready_requests", &PyCameraManager::getReadyRequests); pyCamera .def_property_readonly("id", &Camera::id) @@ -191,7 +120,10 @@ PYBIND11_MODULE(_libcamera, m) const std::unordered_map &controls) { /* \todo What happens if someone calls start() multiple times? */ - self.requestCompleted.connect(handleRequestCompleted); + auto cm = gCameraManager.lock(); + ASSERT(cm); + + self.requestCompleted.connect(cm.get(), &PyCameraManager::handleRequestCompleted); ControlList controlList(self.controls()); @@ -202,7 +134,7 @@ PYBIND11_MODULE(_libcamera, m) int ret = self.start(&controlList); if (ret) { - self.requestCompleted.disconnect(handleRequestCompleted); + self.requestCompleted.disconnect(); return ret; } @@ -214,7 +146,7 @@ PYBIND11_MODULE(_libcamera, m) if (ret) return ret; - self.requestCompleted.disconnect(handleRequestCompleted); + self.requestCompleted.disconnect(); return 0; }) From patchwork Fri Aug 19 11:16:12 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomi Valkeinen X-Patchwork-Id: 17178 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 01ED0C327D for ; Fri, 19 Aug 2022 11:16:36 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id AB17261FCF; Fri, 19 Aug 2022 13:16:36 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1660907796; bh=pIBSw2MG0xHoUVahGKD6tsWMWqXwvmJx/AUNp1RZles=; 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=CCWbfvh5Ks0unQpy7cqzjy+RSKf68g0/7WEvgfx0bQg5SMTooFL0nICMbqaUrPWwH SCOTvsQ0LcpjJMoEX9lhaYK1kBZgZq8/Sai02BhwBSCjm3jV0316TB4WYk7f508wOm v4Hd0mFgF8WTlMdaG1vEBONWBCzVYs78G/J1UVrtBCI5Sr828NOuEEtik6r1ic/a/U DcHnpb+D2KAhiuUszAo/zvn/rdDZvMj9pzI/FHScVSuI22vDiKut/2fntFYm9CTm/4 E7boN0EUkb5GkGEmcoKDZJxZrhIPZ+E2KmhqM3s4g4PgRkJEL7l1PvN2G4CCsnx3LT JMBQp5cJP31/Q== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id B767A61FA4 for ; Fri, 19 Aug 2022 13:16:31 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="VWssCl9n"; 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 30B25D51; Fri, 19 Aug 2022 13:16:31 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1660907791; bh=pIBSw2MG0xHoUVahGKD6tsWMWqXwvmJx/AUNp1RZles=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=VWssCl9nVTpp0syJYi/JOn/tbg3y++wQVjhGMejdInV41PAmwOjXKFg2/lnvKUIzj LG+5Rjkyv90CEQ89QDIF9KzAFmKKywNc3WRF937iIxonqXKu1xdwp/Nd274fuHWfGL EY/Bxy+L2F5Cv/qRBHjattTQQtiLVGJqhccp1w6Y= To: libcamera-devel@lists.libcamera.org, David Plowman , Kieran Bingham , Laurent Pinchart , Jacopo Mondi Date: Fri, 19 Aug 2022 14:16:12 +0300 Message-Id: <20220819111615.39814-4-tomi.valkeinen@ideasonboard.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220819111615.39814-1-tomi.valkeinen@ideasonboard.com> References: <20220819111615.39814-1-tomi.valkeinen@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v4 3/6] py: Use UniqueFD 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" Use UniqueFD to automate the eventfd lifetime management. Signed-off-by: Tomi Valkeinen Reviewed-by: Laurent Pinchart --- src/py/libcamera/py_camera_manager.cpp | 16 ++++------------ src/py/libcamera/py_camera_manager.h | 4 ++-- 2 files changed, 6 insertions(+), 14 deletions(-) diff --git a/src/py/libcamera/py_camera_manager.cpp b/src/py/libcamera/py_camera_manager.cpp index 228fb212..18fdb623 100644 --- a/src/py/libcamera/py_camera_manager.cpp +++ b/src/py/libcamera/py_camera_manager.cpp @@ -29,25 +29,17 @@ PyCameraManager::PyCameraManager() throw std::system_error(errno, std::generic_category(), "Failed to create eventfd"); - eventFd_ = fd; + eventFd_ = UniqueFD(fd); int ret = cameraManager_->start(); - if (ret) { - close(fd); - eventFd_ = -1; + if (ret) throw std::system_error(-ret, std::generic_category(), "Failed to start CameraManager"); - } } PyCameraManager::~PyCameraManager() { LOG(Python, Debug) << "~PyCameraManager()"; - - if (eventFd_ != -1) { - close(eventFd_); - eventFd_ = -1; - } } py::list PyCameraManager::cameras() @@ -95,7 +87,7 @@ void PyCameraManager::writeFd() { uint64_t v = 1; - size_t s = write(eventFd_, &v, 8); + size_t s = write(eventFd_.get(), &v, 8); /* * We should never fail, and have no simple means to manage the error, * so let's log a fatal error. @@ -108,7 +100,7 @@ void PyCameraManager::readFd() { uint8_t buf[8]; - if (read(eventFd_, buf, 8) != 8) + if (read(eventFd_.get(), buf, 8) != 8) throw std::system_error(errno, std::generic_category()); } diff --git a/src/py/libcamera/py_camera_manager.h b/src/py/libcamera/py_camera_manager.h index 9c15f814..710163e8 100644 --- a/src/py/libcamera/py_camera_manager.h +++ b/src/py/libcamera/py_camera_manager.h @@ -24,7 +24,7 @@ public: static const std::string &version() { return CameraManager::version(); } - int eventFd() const { return eventFd_; } + int eventFd() const { return eventFd_.get(); } std::vector getReadyRequests(); @@ -33,7 +33,7 @@ public: private: std::unique_ptr cameraManager_; - int eventFd_ = -1; + UniqueFD eventFd_; std::mutex completedRequestsMutex_; std::vector completedRequests_; From patchwork Fri Aug 19 11:16:13 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomi Valkeinen X-Patchwork-Id: 17179 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 88EFBBE173 for ; Fri, 19 Aug 2022 11:16:37 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 3AC1861FCC; Fri, 19 Aug 2022 13:16:37 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1660907797; bh=Ir9yWG2QFohno8uY8JuMwSpSfHmYnKcYj2mKDrRB6wU=; 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=Q9qc/ApeSv0ybcv9g9KIvoMmmTg94iC43d+w51/FtTukUzcOkwIkicoiY+XwqSD1U voNic79mOwFAyDVPzWA/Oo7eGo8lA8NGsg9EXAueC/cD0S7Hu6HTdlyl6SpuNUMDLM mJcKe8t0/aaMUI4aEBdedkZFx3yV9avLIFYMrulgwwi3129ehGXUF8ALVZKYxQiu58 Qh03yUrBn1K2RIYZFT3hLEzM0RUSTCOAEnub8lVTXOCkMPHCH+erwob2P/pmjUH4pL hfHLKwPW7W552gNO47fogI3LWI2ry999CpFEyWlQG6l9d1xeLEaAikm/2LoEbnJtZn ASmNYV1czn6DQ== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 41F0061FA4 for ; Fri, 19 Aug 2022 13:16:32 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="knfLlvU6"; 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 ADA583F1; Fri, 19 Aug 2022 13:16:31 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1660907792; bh=Ir9yWG2QFohno8uY8JuMwSpSfHmYnKcYj2mKDrRB6wU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=knfLlvU62q9qWGEWNkst7XjBIGRe7bLGqCDMwQI0mJkT1cAFAue4czZglo4kikx2h QEe7Uj9LPY65bAKYvy2L/eo5wZB4quUK6X4dM4JgiRkCKoYHO9ge6e4Y1YfMovVf2Q cqtNi8ke9HQ1cpBr8pVZZDlFxa9QDp0YzvUAEQ9U= To: libcamera-devel@lists.libcamera.org, David Plowman , Kieran Bingham , Laurent Pinchart , Jacopo Mondi Date: Fri, 19 Aug 2022 14:16:13 +0300 Message-Id: <20220819111615.39814-5-tomi.valkeinen@ideasonboard.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220819111615.39814-1-tomi.valkeinen@ideasonboard.com> References: <20220819111615.39814-1-tomi.valkeinen@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v4 4/6] py: Set EFD_CLOEXEC on eventfd to avoid fd leaking 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" Set EFD_CLOEXEC on eventfd to avoid fd leaking. Signed-off-by: Tomi Valkeinen Reviewed-by: Laurent Pinchart --- src/py/libcamera/py_camera_manager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/py/libcamera/py_camera_manager.cpp b/src/py/libcamera/py_camera_manager.cpp index 18fdb623..8bfb8e57 100644 --- a/src/py/libcamera/py_camera_manager.cpp +++ b/src/py/libcamera/py_camera_manager.cpp @@ -24,7 +24,7 @@ PyCameraManager::PyCameraManager() cameraManager_ = std::make_unique(); - int fd = eventfd(0, 0); + int fd = eventfd(0, EFD_CLOEXEC); if (fd == -1) throw std::system_error(errno, std::generic_category(), "Failed to create eventfd"); From patchwork Fri Aug 19 11:16:14 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomi Valkeinen X-Patchwork-Id: 17180 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 1DB78C327E for ; Fri, 19 Aug 2022 11:16:38 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id BEBA361FC9; Fri, 19 Aug 2022 13:16:37 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1660907797; bh=8NLR0FxcULLStTI51TfPY5LofhxaBSG9bWYCSh60mxc=; 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=C03zgG9KIwsB6PcrJ/OrGrVJvWhPnwb6TQd9MYJBzB2FxMwWvoLBrKi2+UZJlC+gE BrV4md3392Vu1eV55xaSXDE8k1IUiabKDQtd8yS5HemZtxiSjS83CySlUNnsvyuWVu LWzpZxO2R+sGim/GKShxQ+hKMK/vmftiDT5MlZuvoJb0vo3irptEwRYNPuZDhve8Fk oYvUFQnrTxKTwtb8B/aSXosiLMgQkmmFnL3uS5tNsf3UJkUF/JZwUhch6/1BtgGxIa DbiQr6lh7sfCFG1ldC4gk/T9g/KTC2Xlkkqznw+eFRDm0GnJ00klZcpE0wYRz1zcao rznJwZixWufqg== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id C898A61FA4 for ; Fri, 19 Aug 2022 13:16:32 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="SPUPGSg8"; 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 3E4C7576; Fri, 19 Aug 2022 13:16:32 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1660907792; bh=8NLR0FxcULLStTI51TfPY5LofhxaBSG9bWYCSh60mxc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=SPUPGSg8msC0/IN65vNbKEHwRe5JrxiWNCryTcjHT2J0x9Plj5p0JmocMp7y7l+RA LON6X6p8Ndm7X3imeo2EgT2j7xAmTRtWqPUaWEaGIF84JJswuRoGXbtGvI3npnSLd3 QS0LeJ1pJ1zoSLXNTcx0rZw+K3RToqaxtPO2hkaA= To: libcamera-devel@lists.libcamera.org, David Plowman , Kieran Bingham , Laurent Pinchart , Jacopo Mondi Date: Fri, 19 Aug 2022 14:16:14 +0300 Message-Id: <20220819111615.39814-6-tomi.valkeinen@ideasonboard.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220819111615.39814-1-tomi.valkeinen@ideasonboard.com> References: <20220819111615.39814-1-tomi.valkeinen@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v4 5/6] py: Use libcamera's Mutex classes 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" Use libcamera's Mutex and MutexLocker instead of the std versions to get thread safety annotations. Signed-off-by: Tomi Valkeinen Reviewed-by: Laurent Pinchart --- src/py/libcamera/py_camera_manager.cpp | 4 ++-- src/py/libcamera/py_camera_manager.h | 7 ++++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/py/libcamera/py_camera_manager.cpp b/src/py/libcamera/py_camera_manager.cpp index 8bfb8e57..ea4ae825 100644 --- a/src/py/libcamera/py_camera_manager.cpp +++ b/src/py/libcamera/py_camera_manager.cpp @@ -106,14 +106,14 @@ void PyCameraManager::readFd() void PyCameraManager::pushRequest(Request *req) { - std::lock_guard guard(completedRequestsMutex_); + MutexLocker guard(completedRequestsMutex_); completedRequests_.push_back(req); } std::vector PyCameraManager::getCompletedRequests() { std::vector v; - std::lock_guard guard(completedRequestsMutex_); + MutexLocker guard(completedRequestsMutex_); swap(v, completedRequests_); return v; } diff --git a/src/py/libcamera/py_camera_manager.h b/src/py/libcamera/py_camera_manager.h index 710163e8..56bea13d 100644 --- a/src/py/libcamera/py_camera_manager.h +++ b/src/py/libcamera/py_camera_manager.h @@ -5,7 +5,7 @@ #pragma once -#include +#include #include @@ -34,8 +34,9 @@ private: std::unique_ptr cameraManager_; UniqueFD eventFd_; - std::mutex completedRequestsMutex_; - std::vector completedRequests_; + libcamera::Mutex completedRequestsMutex_; + std::vector completedRequests_ + LIBCAMERA_TSA_GUARDED_BY(completedRequestsMutex_); void writeFd(); void readFd(); From patchwork Fri Aug 19 11:16:15 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomi Valkeinen X-Patchwork-Id: 17181 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 AF3F7C327F for ; Fri, 19 Aug 2022 11:16:38 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 6621661FC4; Fri, 19 Aug 2022 13:16:38 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1660907798; bh=rbdPJmlX0jh6SOF3bqFbTjLN0VOVLWoGLtX0RjstgwE=; 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=IGnezcy37PpPojES2zFlMUFykQVbY4MTWzqGBj5ZUSaLvXhEr7dtTsRokIuF0fVDT 9rppwr7J6VpFkwu+gNs4ZcgveFFRISlvL/jcRyVWXE/rXhJy6LjaaUVgsesyAv1NGh m6eS5vSXQFRtlI4D0bhfk7CKolx/GsqbTXANcY+SHCX/cY9W5fhHdnTOpaTA2TxGVX rcxF3y7LPw0FovHSu6uuPn4N0stGx2WINDNs+5y64bttFr4d44H/BgYUzZxSeHDQBj 7CuxgMxK8LVY5jTNK8yeLU3wWhJcf4mr2PtjypCks/PiDBrPy5hmdCGB8C9qqaHzaL Btle0d3bYGVIw== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 4A43A61FC9 for ; Fri, 19 Aug 2022 13:16:33 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="Uod3iUNY"; 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 B8F143F1; Fri, 19 Aug 2022 13:16:32 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1660907793; bh=rbdPJmlX0jh6SOF3bqFbTjLN0VOVLWoGLtX0RjstgwE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Uod3iUNYYPOvTBRoMxIxAdSe/zpfeWbk+AJGJHTnytDxvBSvX1Ijabull7YnF4EPi nDhCxRSyQAaOkdLrEcPkFRrl4koTB0WOA/L7OSkhCOqmwe6As6N2eRFrICni8EmHum B+S3ZVodjn13ABSbuk/EUqHUAl5RAxW3Zch1qveQ= To: libcamera-devel@lists.libcamera.org, David Plowman , Kieran Bingham , Laurent Pinchart , Jacopo Mondi Date: Fri, 19 Aug 2022 14:16:15 +0300 Message-Id: <20220819111615.39814-7-tomi.valkeinen@ideasonboard.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220819111615.39814-1-tomi.valkeinen@ideasonboard.com> References: <20220819111615.39814-1-tomi.valkeinen@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v4 6/6] py: Switch to non-blocking eventfd 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" Blocking wait can be easily implemented on top in Python, so rather than supporting only blocking reads, or supporting both non-blocking and blocking reads, let's support only non-blocking reads. Signed-off-by: Tomi Valkeinen Reviewed-by: Laurent Pinchart --- src/py/examples/simple-cam.py | 5 +++-- src/py/examples/simple-capture.py | 12 +++++++++-- src/py/examples/simple-continuous-capture.py | 5 +++-- src/py/libcamera/py_camera_manager.cpp | 22 +++++++++++++++----- src/py/libcamera/py_camera_manager.h | 2 +- test/py/unittests.py | 7 +++++++ 6 files changed, 41 insertions(+), 12 deletions(-) diff --git a/src/py/examples/simple-cam.py b/src/py/examples/simple-cam.py index 2b81bb65..b3e97ca7 100755 --- a/src/py/examples/simple-cam.py +++ b/src/py/examples/simple-cam.py @@ -19,8 +19,9 @@ TIMEOUT_SEC = 3 def handle_camera_event(cm): - # cm.get_ready_requests() will not block here, as we know there is an event - # to read. + # cm.get_ready_requests() returns the ready requests, which in our case + # should almost always return a single Request, but in some cases there + # could be multiple or none. reqs = cm.get_ready_requests() diff --git a/src/py/examples/simple-capture.py b/src/py/examples/simple-capture.py index a6a9b33e..5f93574f 100755 --- a/src/py/examples/simple-capture.py +++ b/src/py/examples/simple-capture.py @@ -14,6 +14,7 @@ import argparse import libcamera as libcam +import selectors import sys # Number of frames to capture @@ -107,11 +108,18 @@ def main(): # The main loop. Wait for the queued Requests to complete, process them, # and re-queue them again. + sel = selectors.DefaultSelector() + sel.register(cm.event_fd, selectors.EVENT_READ) + while frames_done < TOTAL_FRAMES: - # cm.get_ready_requests() blocks until there is an event and returns - # all the ready requests. Here we should almost always get a single + # cm.get_ready_requests() does not block, so we use a Selector to wait + # for a camera event. Here we should almost always get a single # Request, but in some cases there could be multiple or none. + events = sel.select() + if not events: + continue + reqs = cm.get_ready_requests() for req in reqs: diff --git a/src/py/examples/simple-continuous-capture.py b/src/py/examples/simple-continuous-capture.py index fe78a2dd..26a8060b 100755 --- a/src/py/examples/simple-continuous-capture.py +++ b/src/py/examples/simple-continuous-capture.py @@ -88,8 +88,9 @@ class CaptureContext: camera_contexts: list[CameraCaptureContext] = [] def handle_camera_event(self): - # cm.get_ready_requests() will not block here, as we know there is an event - # to read. + # cm.get_ready_requests() returns the ready requests, which in our case + # should almost always return a single Request, but in some cases there + # could be multiple or none. reqs = self.cm.get_ready_requests() diff --git a/src/py/libcamera/py_camera_manager.cpp b/src/py/libcamera/py_camera_manager.cpp index ea4ae825..9ccb7aad 100644 --- a/src/py/libcamera/py_camera_manager.cpp +++ b/src/py/libcamera/py_camera_manager.cpp @@ -24,7 +24,7 @@ PyCameraManager::PyCameraManager() cameraManager_ = std::make_unique(); - int fd = eventfd(0, EFD_CLOEXEC); + int fd = eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK); if (fd == -1) throw std::system_error(errno, std::generic_category(), "Failed to create eventfd"); @@ -62,7 +62,13 @@ py::list PyCameraManager::cameras() std::vector PyCameraManager::getReadyRequests() { - readFd(); + int ret = readFd(); + + if (ret == -EAGAIN) + return std::vector(); + + if (ret != 0) + throw std::system_error(-ret, std::generic_category()); std::vector py_reqs; @@ -96,12 +102,18 @@ void PyCameraManager::writeFd() LOG(Python, Fatal) << "Unable to write to eventfd"; } -void PyCameraManager::readFd() +int PyCameraManager::readFd() { uint8_t buf[8]; - if (read(eventFd_.get(), buf, 8) != 8) - throw std::system_error(errno, std::generic_category()); + ssize_t ret = read(eventFd_.get(), buf, 8); + + if (ret == 8) + return 0; + else if (ret < 0) + return -errno; + else + return -EIO; } void PyCameraManager::pushRequest(Request *req) diff --git a/src/py/libcamera/py_camera_manager.h b/src/py/libcamera/py_camera_manager.h index 56bea13d..3525057d 100644 --- a/src/py/libcamera/py_camera_manager.h +++ b/src/py/libcamera/py_camera_manager.h @@ -39,7 +39,7 @@ private: LIBCAMERA_TSA_GUARDED_BY(completedRequestsMutex_); void writeFd(); - void readFd(); + int readFd(); void pushRequest(Request *req); std::vector getCompletedRequests(); }; diff --git a/test/py/unittests.py b/test/py/unittests.py index 9adc4337..6dea80fc 100755 --- a/test/py/unittests.py +++ b/test/py/unittests.py @@ -207,9 +207,16 @@ class SimpleCaptureMethods(CameraTesterBase): reqs = None gc.collect() + sel = selectors.DefaultSelector() + sel.register(cm.event_fd, selectors.EVENT_READ) + reqs = [] while True: + events = sel.select() + if not events: + continue + ready_reqs = cm.get_ready_requests() reqs += ready_reqs