Show a patch.

GET /api/patches/16419/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 16419,
    "url": "https://patchwork.libcamera.org/api/patches/16419/?format=api",
    "web_url": "https://patchwork.libcamera.org/patch/16419/",
    "project": {
        "id": 1,
        "url": "https://patchwork.libcamera.org/api/projects/1/?format=api",
        "name": "libcamera",
        "link_name": "libcamera",
        "list_id": "libcamera_core",
        "list_email": "libcamera-devel@lists.libcamera.org",
        "web_url": "",
        "scm_url": "",
        "webscm_url": ""
    },
    "msgid": "<20220629070416.17550-14-tomi.valkeinen@ideasonboard.com>",
    "date": "2022-06-29T07:04:15",
    "name": "[libcamera-devel,v2,13/14] py: Discard/Dispatch Request events on camera.stop()",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": false,
    "hash": "f3cf961fdf71fde618498af0d91229ae33617136",
    "submitter": {
        "id": 109,
        "url": "https://patchwork.libcamera.org/api/people/109/?format=api",
        "name": "Tomi Valkeinen",
        "email": "tomi.valkeinen@ideasonboard.com"
    },
    "delegate": null,
    "mbox": "https://patchwork.libcamera.org/patch/16419/mbox/",
    "series": [
        {
            "id": 3230,
            "url": "https://patchwork.libcamera.org/api/series/3230/?format=api",
            "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=3230",
            "date": "2022-06-29T07:04:02",
            "name": "Python bindings event handling",
            "version": 2,
            "mbox": "https://patchwork.libcamera.org/series/3230/mbox/"
        }
    ],
    "comments": "https://patchwork.libcamera.org/api/patches/16419/comments/",
    "check": "pending",
    "checks": "https://patchwork.libcamera.org/api/patches/16419/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 64F0EBE173\n\tfor <parsemail@patchwork.libcamera.org>;\n\tWed, 29 Jun 2022 07:05:00 +0000 (UTC)",
            "from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 04BC665659;\n\tWed, 29 Jun 2022 09:04:59 +0200 (CEST)",
            "from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id C977D65647\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 29 Jun 2022 09:04:47 +0200 (CEST)",
            "from deskari.lan (91-158-154-79.elisa-laajakaista.fi\n\t[91.158.154.79])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 395356D1;\n\tWed, 29 Jun 2022 09:04:47 +0200 (CEST)"
        ],
        "DKIM-Signature": [
            "v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org;\n\ts=mail; t=1656486300;\n\tbh=jMNfoKH54gCKMC1c4+vxSz2aDSApVNlcC2eDc42ZuDA=;\n\th=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe:\n\tList-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:\n\tFrom;\n\tb=kt+osuUNlpo2pR6JjZzxtuECzAZHs5bnWNtAxu/BrRQItO10bMYPOVVZTojzI6E8f\n\tJXwioi0v5hyuXeJlovwfvry4g/hJPIGUypHuhS2Is0lYkEjABX+BdTQMncNEgKe9e8\n\tzlRtMjHFLdWBSgmBUN0fA9fP9+U7u3fSKDI01aDWiiJqxHLtKq0NNDxEUNgI2VeejQ\n\tGBWEub+1GjPQnEIFd8NbQoUaiQoBC0HL9WKiaLecGkG2lMKZzSSKcV2KZUaZ9tNpA4\n\tFKYZN4UaZF2czhqUWKxEFmN5d1C/JaA8M4LbMhwRVBqQUc1vVqZuwPtryPFdgNgzsp\n\tS13Qi9TIL7rVw==",
            "v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1656486287;\n\tbh=jMNfoKH54gCKMC1c4+vxSz2aDSApVNlcC2eDc42ZuDA=;\n\th=From:To:Cc:Subject:Date:In-Reply-To:References:From;\n\tb=PslNNwxad2l/DDnCOyggrk0sDAxwJ8RYZuYaLw90UtDFkqbxQmUyGET9gDRbr+dkN\n\tCvwMatdL28XoqDCwFkKlyAr7B14ypnLRVn0YvbChgOElHmUs9fWv0yLYFCfgoy3E4S\n\tNTorJ9od4IHlQCmZVPkpiVzgSyoHICR1LKCKlClo="
        ],
        "Authentication-Results": "lancelot.ideasonboard.com; dkim=pass (1024-bit key; \n\tunprotected) header.d=ideasonboard.com\n\theader.i=@ideasonboard.com\n\theader.b=\"PslNNwxa\"; dkim-atps=neutral",
        "To": "libcamera-devel@lists.libcamera.org,\n\tDavid Plowman <david.plowman@raspberrypi.com>,\n\tKieran Bingham <kieran.bingham@ideasonboard.com>,\n\tLaurent Pinchart <laurent.pinchart@ideasonboard.com>,\n\tJacopo Mondi <jacopo@jmondi.org>",
        "Date": "Wed, 29 Jun 2022 10:04:15 +0300",
        "Message-Id": "<20220629070416.17550-14-tomi.valkeinen@ideasonboard.com>",
        "X-Mailer": "git-send-email 2.34.1",
        "In-Reply-To": "<20220629070416.17550-1-tomi.valkeinen@ideasonboard.com>",
        "References": "<20220629070416.17550-1-tomi.valkeinen@ideasonboard.com>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit",
        "Subject": "[libcamera-devel] [PATCH v2 13/14] py: Discard/Dispatch Request\n\tevents on camera.stop()",
        "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>",
        "From": "Tomi Valkeinen via libcamera-devel\n\t<libcamera-devel@lists.libcamera.org>",
        "Reply-To": "Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>",
        "Errors-To": "libcamera-devel-bounces@lists.libcamera.org",
        "Sender": "\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"
    },
    "content": "To prevent old Request related events from being left in the event\nqueue, messing up the next camera.start(), force the events to be either\ndiscarded or dispatched when camera.stop() is called.\n\ncamera.stop() will discard all Request events (RequestCompleted and\nBufferCompleted) for that camera. camera.stop(dispatch_events=True) will\ninstead dispatch all events, also for other cameras.\n\nThe dispatch version dispatches all events instead of just the Request\nevents for one camera so that the event ordering stays the same.\n\nSigned-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>\n---\n src/py/libcamera/py_camera_manager.cpp | 30 ++++++++++++++++++++++++++\n src/py/libcamera/py_camera_manager.h   |  1 +\n src/py/libcamera/py_main.cpp           | 12 +++++++++--\n 3 files changed, 41 insertions(+), 2 deletions(-)",
    "diff": "diff --git a/src/py/libcamera/py_camera_manager.cpp b/src/py/libcamera/py_camera_manager.cpp\nindex 599a9f7e..dfd43a09 100644\n--- a/src/py/libcamera/py_camera_manager.cpp\n+++ b/src/py/libcamera/py_camera_manager.cpp\n@@ -218,6 +218,36 @@ void PyCameraManager::discardEvents()\n \t}\n }\n \n+void PyCameraManager::discardRequests(std::shared_ptr<Camera> camera)\n+{\n+\tMutexLocker guard(cameraEventsMutex_);\n+\n+\tsize_t oldSize = cameraEvents_.size();\n+\n+\tfor (const auto &ev : cameraEvents_) {\n+\t\tif (ev.type_ != CameraEvent::Type::RequestCompleted)\n+\t\t\tcontinue;\n+\n+\t\tif (ev.camera_ != camera)\n+\t\t\tcontinue;\n+\n+\t\t/* Decrease the ref increased in Camera.queue_request() */\n+\t\tpy::object o = py::cast(ev.request_);\n+\t\to.dec_ref();\n+\t}\n+\n+\tcameraEvents_.erase(std::remove_if(cameraEvents_.begin(), cameraEvents_.end(),\n+\t\t[&camera](const CameraEvent &ev) {\n+\t\t\treturn ev.camera_ == camera &&\n+\t\t\t\t(ev.type_ == CameraEvent::Type::RequestCompleted ||\n+\t\t\t\t ev.type_ == CameraEvent::Type::BufferCompleted);\n+\t\t}),\n+\t\tcameraEvents_.end());\n+\n+\tLOG(Python, Debug) << \"Discarded \" << oldSize - cameraEvents_.size()\n+\t\t\t   << \" request events\";\n+}\n+\n std::function<void(std::shared_ptr<Camera>)> PyCameraManager::getCameraAdded() const\n {\n \treturn cameraAddedHandler_;\ndiff --git a/src/py/libcamera/py_camera_manager.h b/src/py/libcamera/py_camera_manager.h\nindex aa51a6bc..9c8d6ca8 100644\n--- a/src/py/libcamera/py_camera_manager.h\n+++ b/src/py/libcamera/py_camera_manager.h\n@@ -38,6 +38,7 @@ public:\n \n \tvoid dispatchEvents();\n \tvoid discardEvents();\n+\tvoid discardRequests(std::shared_ptr<Camera> camera);\n \n \tstd::function<void(std::shared_ptr<Camera>)> getCameraAdded() const;\n \tvoid setCameraAdded(std::function<void(std::shared_ptr<Camera>)> func);\ndiff --git a/src/py/libcamera/py_main.cpp b/src/py/libcamera/py_main.cpp\nindex a07f06c4..c4755bea 100644\n--- a/src/py/libcamera/py_main.cpp\n+++ b/src/py/libcamera/py_main.cpp\n@@ -168,16 +168,24 @@ PYBIND11_MODULE(_libcamera, m)\n \t\t\t}\n \t\t}, py::arg(\"controls\") = std::unordered_map<const ControlId *, py::object>())\n \n-\t\t.def(\"stop\", [](Camera &self) {\n+\t\t.def(\"stop\", [](Camera &self, bool dispatchEvents) {\n \t\t\tint ret = self.stop();\n \n \t\t\tself.requestCompleted.disconnect();\n \n+\t\t\tauto cm = gCameraManager.lock();\n+\t\t\tASSERT(cm);\n+\n+\t\t\tif (dispatchEvents)\n+\t\t\t\tcm->dispatchEvents();\n+\t\t\telse\n+\t\t\t\tcm->discardRequests(self.shared_from_this());\n+\n \t\t\t/* \\todo Should we just ignore the error? */\n \t\t\tif (ret)\n \t\t\t\tthrow std::system_error(-ret, std::generic_category(),\n \t\t\t\t                        \"Failed to start camera\");\n-\t\t})\n+\t\t}, py::arg(\"dispatch_events\") = false)\n \n \t\t.def_property(\"request_completed\",\n \t\t[](Camera &self) {\n",
    "prefixes": [
        "libcamera-devel",
        "v2",
        "13/14"
    ]
}