[{"id":23568,"web_url":"https://patchwork.libcamera.org/comment/23568/","msgid":"<165606562844.1149771.15547198942218026607@Monstersaurus>","date":"2022-06-24T10:13:48","subject":"Re: [libcamera-devel] [RFC v1 5/7] py: Add 'nonblocking' argument\n\tto get_ready_requests()","submitter":{"id":4,"url":"https://patchwork.libcamera.org/api/people/4/","name":"Kieran Bingham","email":"kieran.bingham@ideasonboard.com"},"content":"Quoting Tomi Valkeinen (2022-06-23 15:47:34)\n> Add 'nonblocking' argument to get_ready_requests() which allows the user\n> to ensure get_ready_requests() never blocks. This can be used e.g. after\n> calling camera.stop(), to process or discard any ready or cancelled\n> Requests.\n\nI guess I needed to read ahead for the comments I posted on the previous\npatch ;-)\n\n> \n> In fact, it probably should always be used after stopping the cameras,\n> unless you have made sure that there are no unprocessed Requests. If you\n> start the camera again, and you have left Requests unprocessed, you will\n> get those \"old\" Requests when you expect to get the new Requests.\n> \n> It may be good to call this even if your script exits after stopping\n> the cameras, as unprocessed Requests will keep the Cameras and related\n> objects alive, and thus they won't be freed. As your script is exiting\n> it's strictly speaking not an issue, but it does make tracking other\n> \"real\" memory leaks more difficult.\n> \n> Perhaps the camera.start() should go and discard any old Requests\n> related to that camera. For the exit issue I don't see any automatic\n> solution.\n\nAt the end of camera.stop() we should validate and ensure that all\nRequests are released to the application. We should hold no internal\nrequests when camera.stop() completes.\n\nI.e. ... if we have things to discard at camera.start() - that's a bug I\nbelieve.\n\nahhh but here perhaps the issue is that the python code is the one that\nhas to 'retrieve' those, while in C++ they are returned via a signal?\n\nIs there any harm in discarding the requests at the end of camera.stop()\nsuch that there is simply 'nothing left to process' after? Or does the\npython application have to end up owning the requests to correctly\nrelease them?\n\n\n> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>\n> ---\n>  src/py/libcamera/py_camera_manager.cpp | 21 +++++++++++++++++++--\n>  src/py/libcamera/py_camera_manager.h   |  4 +++-\n>  src/py/libcamera/py_main.cpp           |  3 ++-\n>  3 files changed, 24 insertions(+), 4 deletions(-)\n> \n> diff --git a/src/py/libcamera/py_camera_manager.cpp b/src/py/libcamera/py_camera_manager.cpp\n> index c9e5a99c..ba45f713 100644\n> --- a/src/py/libcamera/py_camera_manager.cpp\n> +++ b/src/py/libcamera/py_camera_manager.cpp\n> @@ -5,6 +5,7 @@\n>  \n>  #include \"py_camera_manager.h\"\n>  \n> +#include <poll.h>\n>  #include <sys/eventfd.h>\n>  #include <unistd.h>\n>  \n> @@ -55,9 +56,10 @@ py::list PyCameraManager::getCameras()\n>         return l;\n>  }\n>  \n> -std::vector<py::object> PyCameraManager::getReadyRequests()\n> +std::vector<py::object> PyCameraManager::getReadyRequests(bool nonBlocking)\n>  {\n> -       readFd();\n> +       if (!nonBlocking || hasEvents())\n> +               readFd();\n>  \n>         std::vector<Request *> v;\n>         getRequests(v);\n> @@ -113,3 +115,18 @@ void PyCameraManager::getRequests(std::vector<Request *> &v)\n>         std::lock_guard guard(reqlist_mutex_);\n>         swap(v, reqList_);\n>  }\n> +\n> +bool PyCameraManager::hasEvents()\n> +{\n> +       struct pollfd pfd = {\n> +               .fd = eventFd_,\n> +               .events = POLLIN,\n> +               .revents = 0,\n> +       };\n> +\n> +       int ret = poll(&pfd, 1, 0);\n> +       if (ret == -1)\n> +               throw std::system_error(errno, std::generic_category());\n> +\n> +       return pfd.revents & POLLIN;\n> +}\n> diff --git a/src/py/libcamera/py_camera_manager.h b/src/py/libcamera/py_camera_manager.h\n> index b0b971ad..2396d236 100644\n> --- a/src/py/libcamera/py_camera_manager.h\n> +++ b/src/py/libcamera/py_camera_manager.h\n> @@ -23,7 +23,7 @@ public:\n>  \n>         int eventFd() const { return eventFd_; }\n>  \n> -       std::vector<pybind11::object> getReadyRequests();\n> +       std::vector<pybind11::object> getReadyRequests(bool nonBlocking = false);\n>  \n>         void handleRequestCompleted(Request *req);\n>  \n> @@ -36,4 +36,6 @@ private:\n>         void readFd();\n>         void pushRequest(Request *req);\n>         void getRequests(std::vector<Request *> &v);\n> +\n> +       bool hasEvents();\n>  };\n> diff --git a/src/py/libcamera/py_main.cpp b/src/py/libcamera/py_main.cpp\n> index 23018288..ee4ecb9b 100644\n> --- a/src/py/libcamera/py_main.cpp\n> +++ b/src/py/libcamera/py_main.cpp\n> @@ -103,7 +103,8 @@ PYBIND11_MODULE(_libcamera, m)\n>                 .def_property_readonly(\"cameras\", &PyCameraManager::getCameras)\n>  \n>                 .def_property_readonly(\"event_fd\", &PyCameraManager::eventFd)\n> -               .def(\"get_ready_requests\", &PyCameraManager::getReadyRequests);\n> +               .def(\"get_ready_requests\", &PyCameraManager::getReadyRequests,\n> +                    py::arg(\"nonblocking\") = false);\n>  \n>         pyCamera\n>                 .def_property_readonly(\"id\", &Camera::id)\n> -- \n> 2.34.1\n>","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 7A2A2BE173\n\tfor <parsemail@patchwork.libcamera.org>;\n\tFri, 24 Jun 2022 10:13:52 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id D610365635;\n\tFri, 24 Jun 2022 12:13:51 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id ED0E0600EC\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 24 Jun 2022 12:13:50 +0200 (CEST)","from pendragon.ideasonboard.com\n\t(cpc89244-aztw30-2-0-cust3082.18-1.cable.virginm.net [86.31.172.11])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 6A90EDD;\n\tFri, 24 Jun 2022 12:13:50 +0200 (CEST)"],"DKIM-Signature":["v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org;\n\ts=mail; t=1656065631;\n\tbh=4HNhkHQ1WClLoWrFNQ/A9ynYlzUNmj0zZHd8ni60Pws=;\n\th=In-Reply-To:References:To:Date:Subject:List-Id:List-Unsubscribe:\n\tList-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:\n\tFrom;\n\tb=aPj/bMqzmL/Bxz0VNUEL14j8gOjJK4X2usPMcDw2Ppg4VpEU/dOvX61E98XeHORgB\n\tVOEAFDRUZyI7JzUVhHgatrviUA+WhWmhB6ObLxwQ7cRCcbqRY5WXh2X1W62SkGashr\n\tNsFLA+/okC5q2oGEIu5VwpyFBoyLfBcv5JPro6AlRsyRvd0ITnA6Jhu7wnBESwn6rt\n\tCrn+14XJEpczKTP7NTJx+LRABgAhiMju63V7NT+y0AAjdfvLn4gp8qRpEhTLZFIVql\n\tKe/BnAvd+EeKP7HrovATPz581281eQHY8CD1JasPKrpl8eTYS3GHipMhDuDE5RfDC5\n\tVl8Hsz3IDJupw==","v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1656065630;\n\tbh=4HNhkHQ1WClLoWrFNQ/A9ynYlzUNmj0zZHd8ni60Pws=;\n\th=In-Reply-To:References:Subject:From:Cc:To:Date:From;\n\tb=PF1TU6Brs0fw0Urfxwv0akmmUzR+kHgq78Ly9yyFeG1NBeKdGNHW2zu8KDUNHL+1O\n\tq3T4W8oSKslDVJ9AtCMZlpZXY+Qic8lcPp+e9jjte9SeMGDyGELs7V2LacZck9jkcV\n\t40N6NcBUOpq2ndCubu/SFyu0ksRw1JVWjhExoLC0="],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key; \n\tunprotected) header.d=ideasonboard.com\n\theader.i=@ideasonboard.com\n\theader.b=\"PF1TU6Br\"; dkim-atps=neutral","Content-Type":"text/plain; charset=\"utf-8\"","MIME-Version":"1.0","Content-Transfer-Encoding":"quoted-printable","In-Reply-To":"<20220623144736.78537-6-tomi.valkeinen@ideasonboard.com>","References":"<20220623144736.78537-1-tomi.valkeinen@ideasonboard.com>\n\t<20220623144736.78537-6-tomi.valkeinen@ideasonboard.com>","To":"David Plowman <david.plowman@raspberrypi.com>,\n\tJacopo Mondi <jacopo@jmondi.org>,\n\tLaurent Pinchart <laurent.pinchart@ideasonboard.com>,\n\tTomi Valkeinen <tomi.valkeinen@ideasonboard.com>,\n\tlibcamera-devel@lists.libcamera.org","Date":"Fri, 24 Jun 2022 11:13:48 +0100","Message-ID":"<165606562844.1149771.15547198942218026607@Monstersaurus>","User-Agent":"alot/0.10","Subject":"Re: [libcamera-devel] [RFC v1 5/7] py: Add 'nonblocking' argument\n\tto get_ready_requests()","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":"Kieran Bingham via libcamera-devel\n\t<libcamera-devel@lists.libcamera.org>","Reply-To":"Kieran Bingham <kieran.bingham@ideasonboard.com>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":23569,"web_url":"https://patchwork.libcamera.org/comment/23569/","msgid":"<CAHW6GYJ16vLOrELLE8YCayRQ-T8Sg+0SFxP8g0LXu99478a9zw@mail.gmail.com>","date":"2022-06-24T10:26:18","subject":"Re: [libcamera-devel] [RFC v1 5/7] py: Add 'nonblocking' argument\n\tto get_ready_requests()","submitter":{"id":42,"url":"https://patchwork.libcamera.org/api/people/42/","name":"David Plowman","email":"david.plowman@raspberrypi.com"},"content":"Hi everyone\n\nJust to add some background to this one...\n\nThis has been causing me a little trouble in Picamera2 lately.\nget_ready_requests used to be non-blocking so I would always call it\nafter stopping the camera to clear out any \"lurking\" requests. Since\nit became blocking I've had to stop that but it does mean that a stray\nrequest can be read out at an awkward time. This can lead to us\ngetting the \"wrong\" image (and probably falling over when it's the\nwrong size or something), or even trying to queue it back to libcamera\n(while the camera is still stopped).\n\nAnyway, either solution works for me. Either I can flush out those\nrequests after calling stop(), which is what I used to do. Or they\ncould disappear \"spontaneously\". Both work for me!!\n\nThanks\nDavid\n\nOn Fri, 24 Jun 2022 at 11:13, Kieran Bingham\n<kieran.bingham@ideasonboard.com> wrote:\n>\n> Quoting Tomi Valkeinen (2022-06-23 15:47:34)\n> > Add 'nonblocking' argument to get_ready_requests() which allows the user\n> > to ensure get_ready_requests() never blocks. This can be used e.g. after\n> > calling camera.stop(), to process or discard any ready or cancelled\n> > Requests.\n>\n> I guess I needed to read ahead for the comments I posted on the previous\n> patch ;-)\n>\n> >\n> > In fact, it probably should always be used after stopping the cameras,\n> > unless you have made sure that there are no unprocessed Requests. If you\n> > start the camera again, and you have left Requests unprocessed, you will\n> > get those \"old\" Requests when you expect to get the new Requests.\n> >\n> > It may be good to call this even if your script exits after stopping\n> > the cameras, as unprocessed Requests will keep the Cameras and related\n> > objects alive, and thus they won't be freed. As your script is exiting\n> > it's strictly speaking not an issue, but it does make tracking other\n> > \"real\" memory leaks more difficult.\n> >\n> > Perhaps the camera.start() should go and discard any old Requests\n> > related to that camera. For the exit issue I don't see any automatic\n> > solution.\n>\n> At the end of camera.stop() we should validate and ensure that all\n> Requests are released to the application. We should hold no internal\n> requests when camera.stop() completes.\n>\n> I.e. ... if we have things to discard at camera.start() - that's a bug I\n> believe.\n>\n> ahhh but here perhaps the issue is that the python code is the one that\n> has to 'retrieve' those, while in C++ they are returned via a signal?\n>\n> Is there any harm in discarding the requests at the end of camera.stop()\n> such that there is simply 'nothing left to process' after? Or does the\n> python application have to end up owning the requests to correctly\n> release them?\n>\n>\n> > Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>\n> > ---\n> >  src/py/libcamera/py_camera_manager.cpp | 21 +++++++++++++++++++--\n> >  src/py/libcamera/py_camera_manager.h   |  4 +++-\n> >  src/py/libcamera/py_main.cpp           |  3 ++-\n> >  3 files changed, 24 insertions(+), 4 deletions(-)\n> >\n> > diff --git a/src/py/libcamera/py_camera_manager.cpp b/src/py/libcamera/py_camera_manager.cpp\n> > index c9e5a99c..ba45f713 100644\n> > --- a/src/py/libcamera/py_camera_manager.cpp\n> > +++ b/src/py/libcamera/py_camera_manager.cpp\n> > @@ -5,6 +5,7 @@\n> >\n> >  #include \"py_camera_manager.h\"\n> >\n> > +#include <poll.h>\n> >  #include <sys/eventfd.h>\n> >  #include <unistd.h>\n> >\n> > @@ -55,9 +56,10 @@ py::list PyCameraManager::getCameras()\n> >         return l;\n> >  }\n> >\n> > -std::vector<py::object> PyCameraManager::getReadyRequests()\n> > +std::vector<py::object> PyCameraManager::getReadyRequests(bool nonBlocking)\n> >  {\n> > -       readFd();\n> > +       if (!nonBlocking || hasEvents())\n> > +               readFd();\n> >\n> >         std::vector<Request *> v;\n> >         getRequests(v);\n> > @@ -113,3 +115,18 @@ void PyCameraManager::getRequests(std::vector<Request *> &v)\n> >         std::lock_guard guard(reqlist_mutex_);\n> >         swap(v, reqList_);\n> >  }\n> > +\n> > +bool PyCameraManager::hasEvents()\n> > +{\n> > +       struct pollfd pfd = {\n> > +               .fd = eventFd_,\n> > +               .events = POLLIN,\n> > +               .revents = 0,\n> > +       };\n> > +\n> > +       int ret = poll(&pfd, 1, 0);\n> > +       if (ret == -1)\n> > +               throw std::system_error(errno, std::generic_category());\n> > +\n> > +       return pfd.revents & POLLIN;\n> > +}\n> > diff --git a/src/py/libcamera/py_camera_manager.h b/src/py/libcamera/py_camera_manager.h\n> > index b0b971ad..2396d236 100644\n> > --- a/src/py/libcamera/py_camera_manager.h\n> > +++ b/src/py/libcamera/py_camera_manager.h\n> > @@ -23,7 +23,7 @@ public:\n> >\n> >         int eventFd() const { return eventFd_; }\n> >\n> > -       std::vector<pybind11::object> getReadyRequests();\n> > +       std::vector<pybind11::object> getReadyRequests(bool nonBlocking = false);\n> >\n> >         void handleRequestCompleted(Request *req);\n> >\n> > @@ -36,4 +36,6 @@ private:\n> >         void readFd();\n> >         void pushRequest(Request *req);\n> >         void getRequests(std::vector<Request *> &v);\n> > +\n> > +       bool hasEvents();\n> >  };\n> > diff --git a/src/py/libcamera/py_main.cpp b/src/py/libcamera/py_main.cpp\n> > index 23018288..ee4ecb9b 100644\n> > --- a/src/py/libcamera/py_main.cpp\n> > +++ b/src/py/libcamera/py_main.cpp\n> > @@ -103,7 +103,8 @@ PYBIND11_MODULE(_libcamera, m)\n> >                 .def_property_readonly(\"cameras\", &PyCameraManager::getCameras)\n> >\n> >                 .def_property_readonly(\"event_fd\", &PyCameraManager::eventFd)\n> > -               .def(\"get_ready_requests\", &PyCameraManager::getReadyRequests);\n> > +               .def(\"get_ready_requests\", &PyCameraManager::getReadyRequests,\n> > +                    py::arg(\"nonblocking\") = false);\n> >\n> >         pyCamera\n> >                 .def_property_readonly(\"id\", &Camera::id)\n> > --\n> > 2.34.1\n> >","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 EEB2BBD808\n\tfor <parsemail@patchwork.libcamera.org>;\n\tFri, 24 Jun 2022 10:26:31 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 5490C65637;\n\tFri, 24 Jun 2022 12:26:31 +0200 (CEST)","from mail-ej1-x635.google.com (mail-ej1-x635.google.com\n\t[IPv6:2a00:1450:4864:20::635])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 7CC7B600EC\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 24 Jun 2022 12:26:29 +0200 (CEST)","by mail-ej1-x635.google.com with SMTP id ge10so3761770ejb.7\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 24 Jun 2022 03:26:29 -0700 (PDT)"],"DKIM-Signature":["v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org;\n\ts=mail; t=1656066391;\n\tbh=OYlTYgQUBzpB0K8sn5BVnRLBzsAiksBfBFEo3xeZwBU=;\n\th=References:In-Reply-To:Date:To:Subject:List-Id:List-Unsubscribe:\n\tList-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc:\n\tFrom;\n\tb=fCNlZ0oAYrzbZGPectKLqbMOIQPqXifoA/JY1w8on5HzAKoi0G49StEC6qfYqfz91\n\tNYmG1Eq1lCMqAm8+d0YSBnJYXvWdVHZG+coSJSVwX+x5i1PK4v6T4XWWy1ftnk1sBT\n\tDbc/yt7TdNsfMSlrMEOk16xwVx0steJcGltZ+gZCvGaVkjNc1cFGAbU+BW4bW5xkRA\n\tFgrhNk4ccBbKi2eBLnPEiHkKQxngvnNc7yYfjIvBALYDGi7uiLThNF9QvK1wlRliop\n\tY3OHimrASWuaRuAH1iJp5bL+3g5cQ7xxQDRDGqmcqgFnK7yNLYiIkyXWxb7Bg/4GLf\n\tP1ERcTRKCdkiw==","v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=raspberrypi.com; s=google;\n\th=mime-version:references:in-reply-to:from:date:message-id:subject:to\n\t:cc; bh=7K8PRtIaFNXLfYiPN1SdBX6FjqNkstua2sfBEiCdnLg=;\n\tb=YrAyzFuLb+TPg5zBC1AgIRgD18dtwGVv6OmlcEgv8f0dZ9TBc34x/F23L3F1kznwi2\n\tlyLYuoNVfr+J+wVvvML75tE7z+Tq1wQ94E9eOv7iMyPHy2hUjX+MaPjwCnZ8dSSDhuaT\n\t5vcuFBxoV1heu04YPeNeaB5fw5VOevX9XCQvjFPqq12MZMsUrOdM2580n4wppAmROBAA\n\tASUvkFqcvUyYyZzsnCJDrGrjZJGGuFFJR5vE0YS4bCghDAJuYHJ/G2MM4DgtlKHDMCNB\n\tadd528za5nPcIrbZDcgAClPVQo8mkg47x4na0le25J579reD5d87LjPWHw0Sbwn5RjGy\n\t97KQ=="],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (2048-bit key; \n\tunprotected) header.d=raspberrypi.com\n\theader.i=@raspberrypi.com\n\theader.b=\"YrAyzFuL\"; dkim-atps=neutral","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20210112;\n\th=x-gm-message-state:mime-version:references:in-reply-to:from:date\n\t:message-id:subject:to:cc;\n\tbh=7K8PRtIaFNXLfYiPN1SdBX6FjqNkstua2sfBEiCdnLg=;\n\tb=vpGCa5VzmC+ZRahxvL1ZmBnOqdKujKNQC3RCoEojDjy66Pf0TNF7K/HuNyO5/n8CMa\n\tS/mN1LeM5KHv+quPYBk/S9sDhMpY3KEB7yo7uhByhvXAN5U04onX5qTGnJgQnxPyd0Ap\n\tmIbVyNXQrvzXDVYovmtrSchX5q6p+z1fEdn1YPQzY1xCYpwkjxIgJpqkOV6ioswgVfz/\n\te1lIGMxfg/6H1U+72lTHQcz/QCqizrMKFxv0sIMAMYARTEYJN7YW9BiphJVPH7o3O/3V\n\tLZv8qBk9XENuUcqtemhAkB5N3wOcWKCh59/ep+z5UkfZSv5ziDBuRLdssOOG+jSOhDms\n\tLVZQ==","X-Gm-Message-State":"AJIora+THdnuOx9hOVMKbZcq7pweBn4ELDwCw3Q2FNVMZZu7pSmJhALk\n\tDjl6ehP5no1obaqD4APSF4z5u7TRYcySsRM47eohBXTTgXDqIA==","X-Google-Smtp-Source":"AGRyM1sndEebYkRJh22sEZREkurhJxKh/FDSrqD+dOw26Hh1/7fhKpEEddIXs/rTeqtxyZhTZz1B6p/xIoAdBsJYfGU=","X-Received":"by 2002:a17:906:2086:b0:712:1257:77bf with SMTP id\n\t6-20020a170906208600b00712125777bfmr13225165ejq.655.1656066389024;\n\tFri, 24 Jun 2022 03:26:29 -0700 (PDT)","MIME-Version":"1.0","References":"<20220623144736.78537-1-tomi.valkeinen@ideasonboard.com>\n\t<20220623144736.78537-6-tomi.valkeinen@ideasonboard.com>\n\t<165606562844.1149771.15547198942218026607@Monstersaurus>","In-Reply-To":"<165606562844.1149771.15547198942218026607@Monstersaurus>","Date":"Fri, 24 Jun 2022 11:26:18 +0100","Message-ID":"<CAHW6GYJ16vLOrELLE8YCayRQ-T8Sg+0SFxP8g0LXu99478a9zw@mail.gmail.com>","To":"Kieran Bingham <kieran.bingham@ideasonboard.com>","Content-Type":"text/plain; charset=\"UTF-8\"","Subject":"Re: [libcamera-devel] [RFC v1 5/7] py: Add 'nonblocking' argument\n\tto get_ready_requests()","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":"David Plowman via libcamera-devel <libcamera-devel@lists.libcamera.org>","Reply-To":"David Plowman <david.plowman@raspberrypi.com>","Cc":"libcamera devel <libcamera-devel@lists.libcamera.org>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":23578,"web_url":"https://patchwork.libcamera.org/comment/23578/","msgid":"<YrXBxMP4cOdEUI/Y@pendragon.ideasonboard.com>","date":"2022-06-24T13:53:08","subject":"Re: [libcamera-devel] [RFC v1 5/7] py: Add 'nonblocking' argument\n\tto get_ready_requests()","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"Hello,\n\nOn Fri, Jun 24, 2022 at 11:26:18AM +0100, David Plowman wrote:\n> Hi everyone\n> \n> Just to add some background to this one...\n> \n> This has been causing me a little trouble in Picamera2 lately.\n> get_ready_requests used to be non-blocking so I would always call it\n> after stopping the camera to clear out any \"lurking\" requests. Since\n> it became blocking I've had to stop that but it does mean that a stray\n> request can be read out at an awkward time. This can lead to us\n> getting the \"wrong\" image (and probably falling over when it's the\n> wrong size or something), or even trying to queue it back to libcamera\n> (while the camera is still stopped).\n> \n> Anyway, either solution works for me. Either I can flush out those\n> requests after calling stop(), which is what I used to do. Or they\n> could disappear \"spontaneously\". Both work for me!!\n\nI'd like to make get_ready_requests() non-blocking unconditionally,\ncould that be done ?\n\n> On Fri, 24 Jun 2022 at 11:13, Kieran Bingham wrote:\n> > Quoting Tomi Valkeinen (2022-06-23 15:47:34)\n> > > Add 'nonblocking' argument to get_ready_requests() which allows the user\n> > > to ensure get_ready_requests() never blocks. This can be used e.g. after\n> > > calling camera.stop(), to process or discard any ready or cancelled\n> > > Requests.\n> >\n> > I guess I needed to read ahead for the comments I posted on the previous\n> > patch ;-)\n> >\n> > > In fact, it probably should always be used after stopping the cameras,\n> > > unless you have made sure that there are no unprocessed Requests. If you\n> > > start the camera again, and you have left Requests unprocessed, you will\n> > > get those \"old\" Requests when you expect to get the new Requests.\n> > >\n> > > It may be good to call this even if your script exits after stopping\n> > > the cameras, as unprocessed Requests will keep the Cameras and related\n> > > objects alive, and thus they won't be freed. As your script is exiting\n> > > it's strictly speaking not an issue, but it does make tracking other\n> > > \"real\" memory leaks more difficult.\n\nDevelopers will forget to do so, so I think a better API would be nice.\n\n> > > Perhaps the camera.start() should go and discard any old Requests\n> > > related to that camera. For the exit issue I don't see any automatic\n> > > solution.\n> >\n> > At the end of camera.stop() we should validate and ensure that all\n> > Requests are released to the application. We should hold no internal\n> > requests when camera.stop() completes.\n> >\n> > I.e. ... if we have things to discard at camera.start() - that's a bug I\n> > believe.\n> >\n> > ahhh but here perhaps the issue is that the python code is the one that\n> > has to 'retrieve' those, while in C++ they are returned via a signal?\n> >\n> > Is there any harm in discarding the requests at the end of camera.stop()\n> > such that there is simply 'nothing left to process' after? Or does the\n> > python application have to end up owning the requests to correctly\n> > release them?\n\nSounds like an idea to explore. What's the drawback of clearing in\nstop() ?\n\n> > > Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>\n> > > ---\n> > >  src/py/libcamera/py_camera_manager.cpp | 21 +++++++++++++++++++--\n> > >  src/py/libcamera/py_camera_manager.h   |  4 +++-\n> > >  src/py/libcamera/py_main.cpp           |  3 ++-\n> > >  3 files changed, 24 insertions(+), 4 deletions(-)\n> > >\n> > > diff --git a/src/py/libcamera/py_camera_manager.cpp b/src/py/libcamera/py_camera_manager.cpp\n> > > index c9e5a99c..ba45f713 100644\n> > > --- a/src/py/libcamera/py_camera_manager.cpp\n> > > +++ b/src/py/libcamera/py_camera_manager.cpp\n> > > @@ -5,6 +5,7 @@\n> > >\n> > >  #include \"py_camera_manager.h\"\n> > >\n> > > +#include <poll.h>\n> > >  #include <sys/eventfd.h>\n> > >  #include <unistd.h>\n> > >\n> > > @@ -55,9 +56,10 @@ py::list PyCameraManager::getCameras()\n> > >         return l;\n> > >  }\n> > >\n> > > -std::vector<py::object> PyCameraManager::getReadyRequests()\n> > > +std::vector<py::object> PyCameraManager::getReadyRequests(bool nonBlocking)\n> > >  {\n> > > -       readFd();\n> > > +       if (!nonBlocking || hasEvents())\n> > > +               readFd();\n> > >\n> > >         std::vector<Request *> v;\n> > >         getRequests(v);\n> > > @@ -113,3 +115,18 @@ void PyCameraManager::getRequests(std::vector<Request *> &v)\n> > >         std::lock_guard guard(reqlist_mutex_);\n> > >         swap(v, reqList_);\n> > >  }\n> > > +\n> > > +bool PyCameraManager::hasEvents()\n> > > +{\n> > > +       struct pollfd pfd = {\n> > > +               .fd = eventFd_,\n> > > +               .events = POLLIN,\n> > > +               .revents = 0,\n> > > +       };\n> > > +\n> > > +       int ret = poll(&pfd, 1, 0);\n> > > +       if (ret == -1)\n> > > +               throw std::system_error(errno, std::generic_category());\n> > > +\n> > > +       return pfd.revents & POLLIN;\n> > > +}\n> > > diff --git a/src/py/libcamera/py_camera_manager.h b/src/py/libcamera/py_camera_manager.h\n> > > index b0b971ad..2396d236 100644\n> > > --- a/src/py/libcamera/py_camera_manager.h\n> > > +++ b/src/py/libcamera/py_camera_manager.h\n> > > @@ -23,7 +23,7 @@ public:\n> > >\n> > >         int eventFd() const { return eventFd_; }\n> > >\n> > > -       std::vector<pybind11::object> getReadyRequests();\n> > > +       std::vector<pybind11::object> getReadyRequests(bool nonBlocking = false);\n> > >\n> > >         void handleRequestCompleted(Request *req);\n> > >\n> > > @@ -36,4 +36,6 @@ private:\n> > >         void readFd();\n> > >         void pushRequest(Request *req);\n> > >         void getRequests(std::vector<Request *> &v);\n> > > +\n> > > +       bool hasEvents();\n> > >  };\n> > > diff --git a/src/py/libcamera/py_main.cpp b/src/py/libcamera/py_main.cpp\n> > > index 23018288..ee4ecb9b 100644\n> > > --- a/src/py/libcamera/py_main.cpp\n> > > +++ b/src/py/libcamera/py_main.cpp\n> > > @@ -103,7 +103,8 @@ PYBIND11_MODULE(_libcamera, m)\n> > >                 .def_property_readonly(\"cameras\", &PyCameraManager::getCameras)\n> > >\n> > >                 .def_property_readonly(\"event_fd\", &PyCameraManager::eventFd)\n> > > -               .def(\"get_ready_requests\", &PyCameraManager::getReadyRequests);\n> > > +               .def(\"get_ready_requests\", &PyCameraManager::getReadyRequests,\n> > > +                    py::arg(\"nonblocking\") = false);\n> > >\n> > >         pyCamera\n> > >                 .def_property_readonly(\"id\", &Camera::id)","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 29F3BBE173\n\tfor <parsemail@patchwork.libcamera.org>;\n\tFri, 24 Jun 2022 13:53:27 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 69E7A65635;\n\tFri, 24 Jun 2022 15:53:26 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id DDBFB60412\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 24 Jun 2022 15:53:24 +0200 (CEST)","from pendragon.ideasonboard.com (62-78-145-57.bb.dnainternet.fi\n\t[62.78.145.57])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 2645747C;\n\tFri, 24 Jun 2022 15:53:24 +0200 (CEST)"],"DKIM-Signature":["v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org;\n\ts=mail; t=1656078806;\n\tbh=xX3kwjg0DPKG80h5ECxR6PhgJQqrcmxuSjoa5nfcvvA=;\n\th=Date:To:References:In-Reply-To:Subject:List-Id:List-Unsubscribe:\n\tList-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc:\n\tFrom;\n\tb=c1ggZq0UHy+fQG7I/peyfyCu1NOqWXAP1XV5K1ov8pKw4pN3uJJyH8hu7PIt9CF6V\n\twHtipROen9czcD2AHCRQzuhbZNL+GZmgTe8/k7ogNS4ppLwD1UERyKS2J30p5g6sSh\n\tpoS0Bby3pj1Wuzl95k+8qx+cm1fSsxiWmAtTsrWIgMfPlgBqirD9uChI9lHOcEx2mc\n\tKNolELRLY6lKv0dwR5wLBfImCS+4a/x8TP7wJK7ckJa2EXGI3VraHw20JSh1ywr6IR\n\t/2CnUTNinpoSqb0DESkv1ToAr57fmqGmSNRttMiNlHrts/+uY+xsCdsjOOJDmWxAfr\n\tZX7fTk2PGEDaA==","v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1656078804;\n\tbh=xX3kwjg0DPKG80h5ECxR6PhgJQqrcmxuSjoa5nfcvvA=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=VudL3/rixT37oIuREhejQXvGDP0D5bhpGjQZeHCLUETvRUtQey5qat7iXKoh9GoSm\n\tHTWontobWkSsYy+jVs/ijcUJqbVPyb1TWUapCw4RaAS2ZzQC2x7FqZztUcMMDYu1/Q\n\tUySVfZC9H5f5yCoXpGst/FAOPxs/Gxx0pftT9ljg="],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key; \n\tunprotected) header.d=ideasonboard.com\n\theader.i=@ideasonboard.com\n\theader.b=\"VudL3/ri\"; dkim-atps=neutral","Date":"Fri, 24 Jun 2022 16:53:08 +0300","To":"David Plowman <david.plowman@raspberrypi.com>","Message-ID":"<YrXBxMP4cOdEUI/Y@pendragon.ideasonboard.com>","References":"<20220623144736.78537-1-tomi.valkeinen@ideasonboard.com>\n\t<20220623144736.78537-6-tomi.valkeinen@ideasonboard.com>\n\t<165606562844.1149771.15547198942218026607@Monstersaurus>\n\t<CAHW6GYJ16vLOrELLE8YCayRQ-T8Sg+0SFxP8g0LXu99478a9zw@mail.gmail.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","In-Reply-To":"<CAHW6GYJ16vLOrELLE8YCayRQ-T8Sg+0SFxP8g0LXu99478a9zw@mail.gmail.com>","Subject":"Re: [libcamera-devel] [RFC v1 5/7] py: Add 'nonblocking' argument\n\tto get_ready_requests()","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":"Laurent Pinchart via libcamera-devel\n\t<libcamera-devel@lists.libcamera.org>","Reply-To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","Cc":"libcamera devel <libcamera-devel@lists.libcamera.org>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":23595,"web_url":"https://patchwork.libcamera.org/comment/23595/","msgid":"<6ad7f7ed-f2db-6bb6-4109-7992ee447d4a@ideasonboard.com>","date":"2022-06-27T09:37:10","subject":"Re: [libcamera-devel] [RFC v1 5/7] py: Add 'nonblocking' argument\n\tto get_ready_requests()","submitter":{"id":109,"url":"https://patchwork.libcamera.org/api/people/109/","name":"Tomi Valkeinen","email":"tomi.valkeinen@ideasonboard.com"},"content":"On 24/06/2022 13:13, Kieran Bingham wrote:\n> Quoting Tomi Valkeinen (2022-06-23 15:47:34)\n>> Add 'nonblocking' argument to get_ready_requests() which allows the user\n>> to ensure get_ready_requests() never blocks. This can be used e.g. after\n>> calling camera.stop(), to process or discard any ready or cancelled\n>> Requests.\n> \n> I guess I needed to read ahead for the comments I posted on the previous\n> patch ;-)\n> \n>>\n>> In fact, it probably should always be used after stopping the cameras,\n>> unless you have made sure that there are no unprocessed Requests. If you\n>> start the camera again, and you have left Requests unprocessed, you will\n>> get those \"old\" Requests when you expect to get the new Requests.\n>>\n>> It may be good to call this even if your script exits after stopping\n>> the cameras, as unprocessed Requests will keep the Cameras and related\n>> objects alive, and thus they won't be freed. As your script is exiting\n>> it's strictly speaking not an issue, but it does make tracking other\n>> \"real\" memory leaks more difficult.\n>>\n>> Perhaps the camera.start() should go and discard any old Requests\n>> related to that camera. For the exit issue I don't see any automatic\n>> solution.\n> \n> At the end of camera.stop() we should validate and ensure that all\n> Requests are released to the application. We should hold no internal\n> requests when camera.stop() completes.\n> \n> I.e. ... if we have things to discard at camera.start() - that's a bug I\n> believe.\n> \n> ahhh but here perhaps the issue is that the python code is the one that\n> has to 'retrieve' those, while in C++ they are returned via a signal?\n\nRight. All events are queued by the bindings when they happen, and the \nPython code can then separately handle the events in the Python thread.\n\n> Is there any harm in discarding the requests at the end of camera.stop()\n> such that there is simply 'nothing left to process' after? Or does the\n> python application have to end up owning the requests to correctly\n> release them?\n\nDiscarding automatically at camera.stop() sounds bad to me. There could \nbe normally completed requests in the list, not only cancelled requests. \nAnd you could well design an app so that the app expects each queued \nrequest to be \"given back\" via event handling.\n\nWe could make the camera.stop() call the event handlers, so that it \nwould automatically dispatch the events. But that doesn't sound very \ngood either, although perhaps better than discarding the events \nautomatically.\n\n  Tomi","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 6810FBE173\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon, 27 Jun 2022 09:37:16 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id A9AD265635;\n\tMon, 27 Jun 2022 11:37:15 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 7A20160412\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 27 Jun 2022 11:37:14 +0200 (CEST)","from [192.168.1.111] (91-158-154-79.elisa-laajakaista.fi\n\t[91.158.154.79])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id AEA9C1C6A;\n\tMon, 27 Jun 2022 11:37:13 +0200 (CEST)"],"DKIM-Signature":["v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org;\n\ts=mail; t=1656322635;\n\tbh=VvmYcFIha5ak3aMQOKgnIdRQfvoPDyL1XdoiP7ithFY=;\n\th=Date:To:References:In-Reply-To:Subject:List-Id:List-Unsubscribe:\n\tList-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:\n\tFrom;\n\tb=0xbHP7ajBo8vFUgBDIFKg+yy14ShiEw3OMu8wm/pzonZjV2b21J8WMa8Dq1AUz+aI\n\t85hTycxg5ubGHSYHow+HbTkrxUmCr98IoSypUjInFdiHt3g+KlF1WW0aJhkYlzl0QL\n\txM6djiNGLCSYn73dmhH5xaH73S4EEdSvNXqNH+aKh6b/mahNnrou/ehpxRIdpe5OEX\n\tQxhtC3lDv/4geBgTcYFjzsjfSNLYQ2HTBAbui6XRNE+fTGOnc9euIBtN8L/UI4qwKK\n\tCE7vQex4IewX9HNstEYZ5REB3poSFU2oz2ttp5lNTtXDSK5/EJ+nhE2mAlpDqqz8p5\n\tGk65e0llg7ntg==","v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1656322633;\n\tbh=VvmYcFIha5ak3aMQOKgnIdRQfvoPDyL1XdoiP7ithFY=;\n\th=Date:Subject:To:References:From:In-Reply-To:From;\n\tb=pXahiCtLQXs6nXBRVbS6KetVAFbTD6/libNXNCk4cFjmUZl+sQmfKFnCimbwXxAr4\n\tlLMyaqRuJRwLmfC8SpyahUE0nNp/SG8KHVxqh9fvRPQW7Jvshmzhq5lrE1ovQw4Iex\n\tr4Rn3nvsMC9QDvQgMSt1vtJhPbEE0FQliiYeCQAA="],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key; \n\tunprotected) header.d=ideasonboard.com\n\theader.i=@ideasonboard.com\n\theader.b=\"pXahiCtL\"; dkim-atps=neutral","Message-ID":"<6ad7f7ed-f2db-6bb6-4109-7992ee447d4a@ideasonboard.com>","Date":"Mon, 27 Jun 2022 12:37:10 +0300","MIME-Version":"1.0","User-Agent":"Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101\n\tThunderbird/91.9.1","Content-Language":"en-US","To":"Kieran Bingham <kieran.bingham@ideasonboard.com>,\n\tDavid Plowman <david.plowman@raspberrypi.com>,\n\tJacopo Mondi <jacopo@jmondi.org>,\n\tLaurent Pinchart <laurent.pinchart@ideasonboard.com>,\n\tlibcamera-devel@lists.libcamera.org","References":"<20220623144736.78537-1-tomi.valkeinen@ideasonboard.com>\n\t<20220623144736.78537-6-tomi.valkeinen@ideasonboard.com>\n\t<165606562844.1149771.15547198942218026607@Monstersaurus>","In-Reply-To":"<165606562844.1149771.15547198942218026607@Monstersaurus>","Content-Type":"text/plain; charset=UTF-8; format=flowed","Content-Transfer-Encoding":"7bit","Subject":"Re: [libcamera-devel] [RFC v1 5/7] py: Add 'nonblocking' argument\n\tto get_ready_requests()","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>"}},{"id":23596,"web_url":"https://patchwork.libcamera.org/comment/23596/","msgid":"<ad43e5f9-e683-01d9-6c24-82cfd5ab06ce@ideasonboard.com>","date":"2022-06-27T09:49:45","subject":"Re: [libcamera-devel] [RFC v1 5/7] py: Add 'nonblocking' argument\n\tto get_ready_requests()","submitter":{"id":109,"url":"https://patchwork.libcamera.org/api/people/109/","name":"Tomi Valkeinen","email":"tomi.valkeinen@ideasonboard.com"},"content":"On 24/06/2022 16:53, Laurent Pinchart wrote:\n> Hello,\n> \n> On Fri, Jun 24, 2022 at 11:26:18AM +0100, David Plowman wrote:\n>> Hi everyone\n>>\n>> Just to add some background to this one...\n>>\n>> This has been causing me a little trouble in Picamera2 lately.\n>> get_ready_requests used to be non-blocking so I would always call it\n>> after stopping the camera to clear out any \"lurking\" requests. Since\n>> it became blocking I've had to stop that but it does mean that a stray\n>> request can be read out at an awkward time. This can lead to us\n>> getting the \"wrong\" image (and probably falling over when it's the\n>> wrong size or something), or even trying to queue it back to libcamera\n>> (while the camera is still stopped).\n>>\n>> Anyway, either solution works for me. Either I can flush out those\n>> requests after calling stop(), which is what I used to do. Or they\n>> could disappear \"spontaneously\". Both work for me!!\n> \n> I'd like to make get_ready_requests() non-blocking unconditionally,\n> could that be done ?\n\nI think we should have a blocking version too.\n\n>> On Fri, 24 Jun 2022 at 11:13, Kieran Bingham wrote:\n>>> Quoting Tomi Valkeinen (2022-06-23 15:47:34)\n>>>> Add 'nonblocking' argument to get_ready_requests() which allows the user\n>>>> to ensure get_ready_requests() never blocks. This can be used e.g. after\n>>>> calling camera.stop(), to process or discard any ready or cancelled\n>>>> Requests.\n>>>\n>>> I guess I needed to read ahead for the comments I posted on the previous\n>>> patch ;-)\n>>>\n>>>> In fact, it probably should always be used after stopping the cameras,\n>>>> unless you have made sure that there are no unprocessed Requests. If you\n>>>> start the camera again, and you have left Requests unprocessed, you will\n>>>> get those \"old\" Requests when you expect to get the new Requests.\n>>>>\n>>>> It may be good to call this even if your script exits after stopping\n>>>> the cameras, as unprocessed Requests will keep the Cameras and related\n>>>> objects alive, and thus they won't be freed. As your script is exiting\n>>>> it's strictly speaking not an issue, but it does make tracking other\n>>>> \"real\" memory leaks more difficult.\n> \n> Developers will forget to do so, so I think a better API would be nice.\n\nI don't know yet what that better API could be, but perhaps something we \ncan easily do is to add a check in camera.start(), which will warn if \nthere are events about Requests already queued.\n\n>>>> Perhaps the camera.start() should go and discard any old Requests\n>>>> related to that camera. For the exit issue I don't see any automatic\n>>>> solution.\n>>>\n>>> At the end of camera.stop() we should validate and ensure that all\n>>> Requests are released to the application. We should hold no internal\n>>> requests when camera.stop() completes.\n>>>\n>>> I.e. ... if we have things to discard at camera.start() - that's a bug I\n>>> believe.\n>>>\n>>> ahhh but here perhaps the issue is that the python code is the one that\n>>> has to 'retrieve' those, while in C++ they are returned via a signal?\n>>>\n>>> Is there any harm in discarding the requests at the end of camera.stop()\n>>> such that there is simply 'nothing left to process' after? Or does the\n>>> python application have to end up owning the requests to correctly\n>>> release them?\n> \n> Sounds like an idea to explore. What's the drawback of clearing in\n> stop() ?\n\nLosing events that you expected to get, I think.\n\nI'm talking here about the event handling after adding the new event \nhandling, as I think it's more relevant than figuring out how to do \nthings with just the single event.\n\nWe could dispatch the events (All events? Or just events related to \nRequests for that camera?) automatically in stop(), but that would break \nthe backward compatibility.\n\nIf we drop the backward compatibility, automatically dispatching the \nevents in camera.stop() still feels a bit wrong to me. Instead of \ndispatching to functions, we could expose some kind of event objects to \nPython, and return a list of the events. The list would be returned \nnormally with cm.get_events() or such, but camera.stop() could then also \nreturn the events (related to that camera?).\n\nHandling or returning just some events is of course a bit more work, as \nwe need to lock the events list, then choose and pick, and remove the \npicked ones. But as that would only be done on camera.stop(), it's not \nreally an issue.\n\n  Tomi","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 D6B56BD808\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon, 27 Jun 2022 09:49:51 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 2F5E865633;\n\tMon, 27 Jun 2022 11:49:51 +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 75FE260412\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 27 Jun 2022 11:49:49 +0200 (CEST)","from [192.168.1.111] (91-158-154-79.elisa-laajakaista.fi\n\t[91.158.154.79])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 709861C6A;\n\tMon, 27 Jun 2022 11:49:48 +0200 (CEST)"],"DKIM-Signature":["v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org;\n\ts=mail; t=1656323391;\n\tbh=rKnaNrHCP6DaeiWX0i0n4ge8rYSrU35qgVbBtLoGpFs=;\n\th=Date:To:References:In-Reply-To:Subject:List-Id:List-Unsubscribe:\n\tList-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc:\n\tFrom;\n\tb=lUX9dCFQ3YtorNTwYEYUzq5sqFGno5uY9URhO5i3Grh5lmS/Ip9NJFwC66zvjwPuE\n\tEvGx3kAuA7wTkLEVdG0nKE7bWuM65IAE9aEYiwiaMSEbnuCUdQfhw5vmN6q5NYRiG6\n\td7l7FFOjc1pzBkhorGBSqoIGXwEcTdbXXF8LUXYBrhPFbgj3ci77IxAKIgngENmHeB\n\tT0zAI1b1gZbKLSF0mnc9ukxKnPfSjDabW2bKqngurw0TUu0hbddQDTIcHsE4si1i76\n\tbNZdOkQj13Qpdlw2PLGsJ6LzSAwkIlvCgmL1j6wr5ivM6TnyarYhcyw3a1vzQD8D7H\n\tkeVrvkxgyre8w==","v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1656323388;\n\tbh=rKnaNrHCP6DaeiWX0i0n4ge8rYSrU35qgVbBtLoGpFs=;\n\th=Date:Subject:To:Cc:References:From:In-Reply-To:From;\n\tb=wThYtDeABc6kHK84nKztH0Ea4B4N42usF37OUvffrWBrAgFeQpSe99V17WyF+Glf6\n\ttegJQ1EWJphef99CVd/mAGBcYTltd01RTX30EnaYp1ovGykuSHX5rSrN1EwXxE277i\n\t1Z2bjwS7ZP/Hv3lNoXkp32KOwhZXMv8No2z60HSY="],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key; \n\tunprotected) header.d=ideasonboard.com\n\theader.i=@ideasonboard.com\n\theader.b=\"wThYtDeA\"; dkim-atps=neutral","Message-ID":"<ad43e5f9-e683-01d9-6c24-82cfd5ab06ce@ideasonboard.com>","Date":"Mon, 27 Jun 2022 12:49:45 +0300","MIME-Version":"1.0","User-Agent":"Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101\n\tThunderbird/91.9.1","Content-Language":"en-US","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>,\n\tDavid Plowman <david.plowman@raspberrypi.com>","References":"<20220623144736.78537-1-tomi.valkeinen@ideasonboard.com>\n\t<20220623144736.78537-6-tomi.valkeinen@ideasonboard.com>\n\t<165606562844.1149771.15547198942218026607@Monstersaurus>\n\t<CAHW6GYJ16vLOrELLE8YCayRQ-T8Sg+0SFxP8g0LXu99478a9zw@mail.gmail.com>\n\t<YrXBxMP4cOdEUI/Y@pendragon.ideasonboard.com>","In-Reply-To":"<YrXBxMP4cOdEUI/Y@pendragon.ideasonboard.com>","Content-Type":"text/plain; charset=UTF-8; format=flowed","Content-Transfer-Encoding":"7bit","Subject":"Re: [libcamera-devel] [RFC v1 5/7] py: Add 'nonblocking' argument\n\tto get_ready_requests()","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>","Cc":"libcamera devel <libcamera-devel@lists.libcamera.org>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":23597,"web_url":"https://patchwork.libcamera.org/comment/23597/","msgid":"<YrmDkpIcGFLcrEY0@pendragon.ideasonboard.com>","date":"2022-06-27T10:16:50","subject":"Re: [libcamera-devel] [RFC v1 5/7] py: Add 'nonblocking' argument\n\tto get_ready_requests()","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"Hi Tomi,\n\nOn Mon, Jun 27, 2022 at 12:49:45PM +0300, Tomi Valkeinen wrote:\n> On 24/06/2022 16:53, Laurent Pinchart wrote:\n> > On Fri, Jun 24, 2022 at 11:26:18AM +0100, David Plowman wrote:\n> >> Hi everyone\n> >>\n> >> Just to add some background to this one...\n> >>\n> >> This has been causing me a little trouble in Picamera2 lately.\n> >> get_ready_requests used to be non-blocking so I would always call it\n> >> after stopping the camera to clear out any \"lurking\" requests. Since\n> >> it became blocking I've had to stop that but it does mean that a stray\n> >> request can be read out at an awkward time. This can lead to us\n> >> getting the \"wrong\" image (and probably falling over when it's the\n> >> wrong size or something), or even trying to queue it back to libcamera\n> >> (while the camera is still stopped).\n> >>\n> >> Anyway, either solution works for me. Either I can flush out those\n> >> requests after calling stop(), which is what I used to do. Or they\n> >> could disappear \"spontaneously\". Both work for me!!\n> > \n> > I'd like to make get_ready_requests() non-blocking unconditionally,\n> > could that be done ?\n> \n> I think we should have a blocking version too.\n\nWhy is that ?\n\n> >> On Fri, 24 Jun 2022 at 11:13, Kieran Bingham wrote:\n> >>> Quoting Tomi Valkeinen (2022-06-23 15:47:34)\n> >>>> Add 'nonblocking' argument to get_ready_requests() which allows the user\n> >>>> to ensure get_ready_requests() never blocks. This can be used e.g. after\n> >>>> calling camera.stop(), to process or discard any ready or cancelled\n> >>>> Requests.\n> >>>\n> >>> I guess I needed to read ahead for the comments I posted on the previous\n> >>> patch ;-)\n> >>>\n> >>>> In fact, it probably should always be used after stopping the cameras,\n> >>>> unless you have made sure that there are no unprocessed Requests. If you\n> >>>> start the camera again, and you have left Requests unprocessed, you will\n> >>>> get those \"old\" Requests when you expect to get the new Requests.\n> >>>>\n> >>>> It may be good to call this even if your script exits after stopping\n> >>>> the cameras, as unprocessed Requests will keep the Cameras and related\n> >>>> objects alive, and thus they won't be freed. As your script is exiting\n> >>>> it's strictly speaking not an issue, but it does make tracking other\n> >>>> \"real\" memory leaks more difficult.\n> > \n> > Developers will forget to do so, so I think a better API would be nice.\n> \n> I don't know yet what that better API could be, but perhaps something we \n> can easily do is to add a check in camera.start(), which will warn if \n> there are events about Requests already queued.\n\nThat could indeed help debugging.\n\n> >>>> Perhaps the camera.start() should go and discard any old Requests\n> >>>> related to that camera. For the exit issue I don't see any automatic\n> >>>> solution.\n> >>>\n> >>> At the end of camera.stop() we should validate and ensure that all\n> >>> Requests are released to the application. We should hold no internal\n> >>> requests when camera.stop() completes.\n> >>>\n> >>> I.e. ... if we have things to discard at camera.start() - that's a bug I\n> >>> believe.\n> >>>\n> >>> ahhh but here perhaps the issue is that the python code is the one that\n> >>> has to 'retrieve' those, while in C++ they are returned via a signal?\n> >>>\n> >>> Is there any harm in discarding the requests at the end of camera.stop()\n> >>> such that there is simply 'nothing left to process' after? Or does the\n> >>> python application have to end up owning the requests to correctly\n> >>> release them?\n> > \n> > Sounds like an idea to explore. What's the drawback of clearing in\n> > stop() ?\n> \n> Losing events that you expected to get, I think.\n> \n> I'm talking here about the event handling after adding the new event \n> handling, as I think it's more relevant than figuring out how to do \n> things with just the single event.\n> \n> We could dispatch the events (All events? Or just events related to \n> Requests for that camera?) automatically in stop(), but that would break \n> the backward compatibility.\n\nI don't recall if I've mentioned it in the review of another patch in\nthe series, but I've been thinking about dispatching events at stop\ntime, yes. This is how libcamera operates for buffer and request\ncompletion events, doing the same in Python would make the behaviour\nconsistent. Backward compatibility isn't a concern, the Python bindings\nare experimental, we shouldn't let that block the design of a good API.\n\n> If we drop the backward compatibility, automatically dispatching the \n> events in camera.stop() still feels a bit wrong to me. Instead of \n> dispatching to functions, we could expose some kind of event objects to \n> Python, and return a list of the events. The list would be returned \n> normally with cm.get_events() or such, but camera.stop() could then also \n> return the events (related to that camera?).\n> \n> Handling or returning just some events is of course a bit more work, as \n> we need to lock the events list, then choose and pick, and remove the \n> picked ones. But as that would only be done on camera.stop(), it's not \n> really an issue.","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 11D10BE173\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon, 27 Jun 2022 10:17:11 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id B2BB465636;\n\tMon, 27 Jun 2022 12:17:10 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id BBF526059B\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 27 Jun 2022 12:17:08 +0200 (CEST)","from pendragon.ideasonboard.com (62-78-145-57.bb.dnainternet.fi\n\t[62.78.145.57])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 1B51580A;\n\tMon, 27 Jun 2022 12:17:08 +0200 (CEST)"],"DKIM-Signature":["v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org;\n\ts=mail; t=1656325030;\n\tbh=PBxAka8sQHeBJ/lgm03m6HJit8lpM/ohE/xVLcNWW58=;\n\th=Date:To:References:In-Reply-To:Subject:List-Id:List-Unsubscribe:\n\tList-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc:\n\tFrom;\n\tb=SgIPav3XMj85O23oBuLtOpO7paBsrnoBjcEQAOkMpc53LthVBR44fw8PJ32OVC6Cm\n\tdKvh9rkaY88SAUPLDb5gr080brGkLPnWHwm//bUCiT3em9alCkzDY95eSztP/IVmFm\n\tLWQ3BmBHrAVPH6P6G4ScRwqQOuE17ICIcpcWQlKWqUdUPtflMrbr+ThjNu92jzsD7o\n\tWVCELc7VF9MGfsT1kCKvOHFVFOjDSMoR39EVanCP0q+K8NSOIJyZpBw5Uik4WYwQ4F\n\t+Ooumqq5KHntBt0liWRa5u/zYmFX/zsagJEW2PdIl0ELDlbxlHb2F3Js2XX5V2MOEE\n\tLDNJTGyFxkrcg==","v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1656325028;\n\tbh=PBxAka8sQHeBJ/lgm03m6HJit8lpM/ohE/xVLcNWW58=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=D0YWUst2FE+88q1DQkjNv4Ou7yE+dJhcnFQva2ZPAygU2lzD6S8XpSKWS73dBuh/e\n\tOkDp/i6rJoVn9UWg8oNjGWLOD5G03E4X+3+q82XqR8wHkTjsP40P8wUiF4y5RgbTOE\n\tS7Zwn9aU2s1/xAi3JmmSzCY0N+q9/GpvqGxYdTrc="],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key; \n\tunprotected) header.d=ideasonboard.com\n\theader.i=@ideasonboard.com\n\theader.b=\"D0YWUst2\"; dkim-atps=neutral","Date":"Mon, 27 Jun 2022 13:16:50 +0300","To":"Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>","Message-ID":"<YrmDkpIcGFLcrEY0@pendragon.ideasonboard.com>","References":"<20220623144736.78537-1-tomi.valkeinen@ideasonboard.com>\n\t<20220623144736.78537-6-tomi.valkeinen@ideasonboard.com>\n\t<165606562844.1149771.15547198942218026607@Monstersaurus>\n\t<CAHW6GYJ16vLOrELLE8YCayRQ-T8Sg+0SFxP8g0LXu99478a9zw@mail.gmail.com>\n\t<YrXBxMP4cOdEUI/Y@pendragon.ideasonboard.com>\n\t<ad43e5f9-e683-01d9-6c24-82cfd5ab06ce@ideasonboard.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","In-Reply-To":"<ad43e5f9-e683-01d9-6c24-82cfd5ab06ce@ideasonboard.com>","Subject":"Re: [libcamera-devel] [RFC v1 5/7] py: Add 'nonblocking' argument\n\tto get_ready_requests()","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":"Laurent Pinchart via libcamera-devel\n\t<libcamera-devel@lists.libcamera.org>","Reply-To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","Cc":"libcamera devel <libcamera-devel@lists.libcamera.org>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":23598,"web_url":"https://patchwork.libcamera.org/comment/23598/","msgid":"<YrmENn4l2uZoWlBI@pendragon.ideasonboard.com>","date":"2022-06-27T10:19:34","subject":"Re: [libcamera-devel] [RFC v1 5/7] py: Add 'nonblocking' argument\n\tto get_ready_requests()","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"On Mon, Jun 27, 2022 at 12:37:10PM +0300, Tomi Valkeinen wrote:\n> On 24/06/2022 13:13, Kieran Bingham wrote:\n> > Quoting Tomi Valkeinen (2022-06-23 15:47:34)\n> >> Add 'nonblocking' argument to get_ready_requests() which allows the user\n> >> to ensure get_ready_requests() never blocks. This can be used e.g. after\n> >> calling camera.stop(), to process or discard any ready or cancelled\n> >> Requests.\n> > \n> > I guess I needed to read ahead for the comments I posted on the previous\n> > patch ;-)\n> > \n> >>\n> >> In fact, it probably should always be used after stopping the cameras,\n> >> unless you have made sure that there are no unprocessed Requests. If you\n> >> start the camera again, and you have left Requests unprocessed, you will\n> >> get those \"old\" Requests when you expect to get the new Requests.\n> >>\n> >> It may be good to call this even if your script exits after stopping\n> >> the cameras, as unprocessed Requests will keep the Cameras and related\n> >> objects alive, and thus they won't be freed. As your script is exiting\n> >> it's strictly speaking not an issue, but it does make tracking other\n> >> \"real\" memory leaks more difficult.\n> >>\n> >> Perhaps the camera.start() should go and discard any old Requests\n> >> related to that camera. For the exit issue I don't see any automatic\n> >> solution.\n> > \n> > At the end of camera.stop() we should validate and ensure that all\n> > Requests are released to the application. We should hold no internal\n> > requests when camera.stop() completes.\n> > \n> > I.e. ... if we have things to discard at camera.start() - that's a bug I\n> > believe.\n> > \n> > ahhh but here perhaps the issue is that the python code is the one that\n> > has to 'retrieve' those, while in C++ they are returned via a signal?\n> \n> Right. All events are queued by the bindings when they happen, and the \n> Python code can then separately handle the events in the Python thread.\n> \n> > Is there any harm in discarding the requests at the end of camera.stop()\n> > such that there is simply 'nothing left to process' after? Or does the\n> > python application have to end up owning the requests to correctly\n> > release them?\n> \n> Discarding automatically at camera.stop() sounds bad to me. There could \n> be normally completed requests in the list, not only cancelled requests. \n> And you could well design an app so that the app expects each queued \n> request to be \"given back\" via event handling.\n\nIf requests are in flight when stop() is called, an application has no\nway to know if any particular request will complete successfully or not,\nso it shouldn't rely on that. Dropping all successful completion events\nwould then just hardcode one specific end result, which applications\nmust be ready to handle.\n\nI however agree that an application can be designed to assume each\nqueued request will complete. The libcamera C++ API guarantees that, and\nI think it makes sense to do the same in the Python bindings.\n\n> We could make the camera.stop() call the event handlers, so that it \n> would automatically dispatch the events. But that doesn't sound very \n> good either, although perhaps better than discarding the events \n> automatically.\n\nI like this option :-)","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 3DA0CBD808\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon, 27 Jun 2022 10:19:55 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id B6EA065635;\n\tMon, 27 Jun 2022 12:19: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 458E26059B\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 27 Jun 2022 12:19:53 +0200 (CEST)","from pendragon.ideasonboard.com (62-78-145-57.bb.dnainternet.fi\n\t[62.78.145.57])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 98EEF1C82;\n\tMon, 27 Jun 2022 12:19:52 +0200 (CEST)"],"DKIM-Signature":["v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org;\n\ts=mail; t=1656325194;\n\tbh=dLfng/cyyyquW/5M99Cw7I6Eu7IxUt9WSmwBrlHsqvE=;\n\th=Date:To:References:In-Reply-To:Subject:List-Id:List-Unsubscribe:\n\tList-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc:\n\tFrom;\n\tb=anPGv3T8e34Ej+G58jkA7JPZuG2gfaWxf2y0lfJFi1pXDnYrXsa4kjdDs5tRQ5XgG\n\tdtzuRkpU6lD5Hqg+tDrlWVhfKWINQo83Q/UYVuviS2E8V0XOBkwcko5ctXN8yQEMW6\n\t8DHqfJeN+YHMk9/ifGRzcYmWsLSS5Kg7IwAp+0hIZzWswtAixkWA/V/6g8SNUAfFfb\n\tvGuniLge1IG6uc1EWDRO8nsI/1lYa1PH3vnxUt9mZGiIVpHEPrTGFD61suNRXquqFa\n\tUfqcQ1WoOT4i2bZ6v+ZFpT2BhBpdyEA/6jRUSUu3A8cuu5BYllpw4/oZR3bM9LrSNi\n\tNjcel102kfnOQ==","v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1656325192;\n\tbh=dLfng/cyyyquW/5M99Cw7I6Eu7IxUt9WSmwBrlHsqvE=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=UD+S1w5htKCdPHYvVopnCxSJqRqddbAl3ciDIDCffiB0ZW1Zkl+Bs/X8YrTsYYopn\n\tEUyJzdtAFm8xFEncP+be5UneiteuCFZni8dtj7DZQcmxQ5vrQP0CtDCT08obS2m6VS\n\tx61x9HmbTo0DgBPYn8m5/32DjCHMC1t4hxisIpiE="],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key; \n\tunprotected) header.d=ideasonboard.com\n\theader.i=@ideasonboard.com\n\theader.b=\"UD+S1w5h\"; dkim-atps=neutral","Date":"Mon, 27 Jun 2022 13:19:34 +0300","To":"Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>","Message-ID":"<YrmENn4l2uZoWlBI@pendragon.ideasonboard.com>","References":"<20220623144736.78537-1-tomi.valkeinen@ideasonboard.com>\n\t<20220623144736.78537-6-tomi.valkeinen@ideasonboard.com>\n\t<165606562844.1149771.15547198942218026607@Monstersaurus>\n\t<6ad7f7ed-f2db-6bb6-4109-7992ee447d4a@ideasonboard.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","In-Reply-To":"<6ad7f7ed-f2db-6bb6-4109-7992ee447d4a@ideasonboard.com>","Subject":"Re: [libcamera-devel] [RFC v1 5/7] py: Add 'nonblocking' argument\n\tto get_ready_requests()","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":"Laurent Pinchart via libcamera-devel\n\t<libcamera-devel@lists.libcamera.org>","Reply-To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","Cc":"libcamera-devel@lists.libcamera.org","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":23602,"web_url":"https://patchwork.libcamera.org/comment/23602/","msgid":"<4348bd1d-15c4-46cb-0e78-49562d9ef5d1@ideasonboard.com>","date":"2022-06-27T10:51:36","subject":"Re: [libcamera-devel] [RFC v1 5/7] py: Add 'nonblocking' argument\n\tto get_ready_requests()","submitter":{"id":109,"url":"https://patchwork.libcamera.org/api/people/109/","name":"Tomi Valkeinen","email":"tomi.valkeinen@ideasonboard.com"},"content":"On 27/06/2022 13:16, Laurent Pinchart wrote:\n> Hi Tomi,\n> \n> On Mon, Jun 27, 2022 at 12:49:45PM +0300, Tomi Valkeinen wrote:\n>> On 24/06/2022 16:53, Laurent Pinchart wrote:\n>>> On Fri, Jun 24, 2022 at 11:26:18AM +0100, David Plowman wrote:\n>>>> Hi everyone\n>>>>\n>>>> Just to add some background to this one...\n>>>>\n>>>> This has been causing me a little trouble in Picamera2 lately.\n>>>> get_ready_requests used to be non-blocking so I would always call it\n>>>> after stopping the camera to clear out any \"lurking\" requests. Since\n>>>> it became blocking I've had to stop that but it does mean that a stray\n>>>> request can be read out at an awkward time. This can lead to us\n>>>> getting the \"wrong\" image (and probably falling over when it's the\n>>>> wrong size or something), or even trying to queue it back to libcamera\n>>>> (while the camera is still stopped).\n>>>>\n>>>> Anyway, either solution works for me. Either I can flush out those\n>>>> requests after calling stop(), which is what I used to do. Or they\n>>>> could disappear \"spontaneously\". Both work for me!!\n>>>\n>>> I'd like to make get_ready_requests() non-blocking unconditionally,\n>>> could that be done ?\n>>\n>> I think we should have a blocking version too.\n> \n> Why is that ?\n\nIt's the easiest and the most natural way to write a small script to get \nsomething captured. Maybe we'll do it with a separate function, but \nsomehow we need to offer a way to capture without dealing with Selectors \nor such.\n\n>>>> On Fri, 24 Jun 2022 at 11:13, Kieran Bingham wrote:\n>>>>> Quoting Tomi Valkeinen (2022-06-23 15:47:34)\n>>>>>> Add 'nonblocking' argument to get_ready_requests() which allows the user\n>>>>>> to ensure get_ready_requests() never blocks. This can be used e.g. after\n>>>>>> calling camera.stop(), to process or discard any ready or cancelled\n>>>>>> Requests.\n>>>>>\n>>>>> I guess I needed to read ahead for the comments I posted on the previous\n>>>>> patch ;-)\n>>>>>\n>>>>>> In fact, it probably should always be used after stopping the cameras,\n>>>>>> unless you have made sure that there are no unprocessed Requests. If you\n>>>>>> start the camera again, and you have left Requests unprocessed, you will\n>>>>>> get those \"old\" Requests when you expect to get the new Requests.\n>>>>>>\n>>>>>> It may be good to call this even if your script exits after stopping\n>>>>>> the cameras, as unprocessed Requests will keep the Cameras and related\n>>>>>> objects alive, and thus they won't be freed. As your script is exiting\n>>>>>> it's strictly speaking not an issue, but it does make tracking other\n>>>>>> \"real\" memory leaks more difficult.\n>>>\n>>> Developers will forget to do so, so I think a better API would be nice.\n>>\n>> I don't know yet what that better API could be, but perhaps something we\n>> can easily do is to add a check in camera.start(), which will warn if\n>> there are events about Requests already queued.\n> \n> That could indeed help debugging.\n> \n>>>>>> Perhaps the camera.start() should go and discard any old Requests\n>>>>>> related to that camera. For the exit issue I don't see any automatic\n>>>>>> solution.\n>>>>>\n>>>>> At the end of camera.stop() we should validate and ensure that all\n>>>>> Requests are released to the application. We should hold no internal\n>>>>> requests when camera.stop() completes.\n>>>>>\n>>>>> I.e. ... if we have things to discard at camera.start() - that's a bug I\n>>>>> believe.\n>>>>>\n>>>>> ahhh but here perhaps the issue is that the python code is the one that\n>>>>> has to 'retrieve' those, while in C++ they are returned via a signal?\n>>>>>\n>>>>> Is there any harm in discarding the requests at the end of camera.stop()\n>>>>> such that there is simply 'nothing left to process' after? Or does the\n>>>>> python application have to end up owning the requests to correctly\n>>>>> release them?\n>>>\n>>> Sounds like an idea to explore. What's the drawback of clearing in\n>>> stop() ?\n>>\n>> Losing events that you expected to get, I think.\n>>\n>> I'm talking here about the event handling after adding the new event\n>> handling, as I think it's more relevant than figuring out how to do\n>> things with just the single event.\n>>\n>> We could dispatch the events (All events? Or just events related to\n>> Requests for that camera?) automatically in stop(), but that would break\n>> the backward compatibility.\n> \n> I don't recall if I've mentioned it in the review of another patch in\n> the series, but I've been thinking about dispatching events at stop\n> time, yes. This is how libcamera operates for buffer and request\n> completion events, doing the same in Python would make the behaviour\n> consistent. Backward compatibility isn't a concern, the Python bindings\n> are experimental, we shouldn't let that block the design of a good API.\n\nWith C++, it sounds fine as the signals are fired behind the scenes. In \nthe Python bindings there's a specific call to dispatch the events. \nImplicitly dispatching the events elsewhere can be confusing.\n\n  Tomi","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 080B2BE173\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon, 27 Jun 2022 10:51:42 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 71E1665635;\n\tMon, 27 Jun 2022 12:51:41 +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 C87516059B\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 27 Jun 2022 12:51:39 +0200 (CEST)","from [192.168.1.111] (91-158-154-79.elisa-laajakaista.fi\n\t[91.158.154.79])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id E0F5D1C82;\n\tMon, 27 Jun 2022 12:51:38 +0200 (CEST)"],"DKIM-Signature":["v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org;\n\ts=mail; t=1656327101;\n\tbh=xsvID6qNW9EKl3Ra30+STu8jDf1CmzQ1fTNiusZOlh8=;\n\th=Date:To:References:In-Reply-To:Subject:List-Id:List-Unsubscribe:\n\tList-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc:\n\tFrom;\n\tb=Ko00s1fZ9veSgVMhGvlVxcsszLEpHKRx1PSL4x26o3rdX0f2j5UaK1Su0Cr0Om9bQ\n\t2JTU4XU6kwb1uoQkscQb1oLhkvK9lhzmP4QpDgSTWlXuFBMULj7cHsF+CdEkJeJaxB\n\tRJ9lyQniHi4zx4fbFjAJAo7YCnh4Wyr90joQzg92bt8xJI8BrypwwFqGAaJ+rfak0K\n\t2H20Bb09mzbE2JDJ/GwQ6pQQ+w4OCtR1nyN+1kx+AfAsR3HRVCiDTnz7hlsKYw0+48\n\tSaLH4D5/BsgZKJx2M9mzkKXkk04Ow51AI32njCjpy4loEU/CaDIClAbXoZq0t3P8tS\n\tcjnBiGLcyRfEA==","v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1656327099;\n\tbh=xsvID6qNW9EKl3Ra30+STu8jDf1CmzQ1fTNiusZOlh8=;\n\th=Date:Subject:To:Cc:References:From:In-Reply-To:From;\n\tb=uQs/NmgLaMts0bD93bE1RgEiXpUGVPD3+TDfID8P3eK//51fWZvZ/ycolo+XFlrD5\n\tWLzdjE9RDa53eG4um6hID6HTSoZUyN44mOGRAlZ6o7OtLl8XmfTQR0dgXXXOx14Apx\n\ty+VdBQX6qBj2Tcu9Cg2DYhLUwRUaxgyY9poBPr6w="],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key; \n\tunprotected) header.d=ideasonboard.com\n\theader.i=@ideasonboard.com\n\theader.b=\"uQs/NmgL\"; dkim-atps=neutral","Message-ID":"<4348bd1d-15c4-46cb-0e78-49562d9ef5d1@ideasonboard.com>","Date":"Mon, 27 Jun 2022 13:51:36 +0300","MIME-Version":"1.0","User-Agent":"Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101\n\tThunderbird/91.9.1","Content-Language":"en-US","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","References":"<20220623144736.78537-1-tomi.valkeinen@ideasonboard.com>\n\t<20220623144736.78537-6-tomi.valkeinen@ideasonboard.com>\n\t<165606562844.1149771.15547198942218026607@Monstersaurus>\n\t<CAHW6GYJ16vLOrELLE8YCayRQ-T8Sg+0SFxP8g0LXu99478a9zw@mail.gmail.com>\n\t<YrXBxMP4cOdEUI/Y@pendragon.ideasonboard.com>\n\t<ad43e5f9-e683-01d9-6c24-82cfd5ab06ce@ideasonboard.com>\n\t<YrmDkpIcGFLcrEY0@pendragon.ideasonboard.com>","In-Reply-To":"<YrmDkpIcGFLcrEY0@pendragon.ideasonboard.com>","Content-Type":"text/plain; charset=UTF-8; format=flowed","Content-Transfer-Encoding":"7bit","Subject":"Re: [libcamera-devel] [RFC v1 5/7] py: Add 'nonblocking' argument\n\tto get_ready_requests()","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>","Cc":"libcamera devel <libcamera-devel@lists.libcamera.org>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":23608,"web_url":"https://patchwork.libcamera.org/comment/23608/","msgid":"<YrmhorraByJ0t6fP@pendragon.ideasonboard.com>","date":"2022-06-27T12:25:06","subject":"Re: [libcamera-devel] [RFC v1 5/7] py: Add 'nonblocking' argument\n\tto get_ready_requests()","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"Hi Tomi,\n\nOn Mon, Jun 27, 2022 at 01:51:36PM +0300, Tomi Valkeinen wrote:\n> On 27/06/2022 13:16, Laurent Pinchart wrote:\n> > On Mon, Jun 27, 2022 at 12:49:45PM +0300, Tomi Valkeinen wrote:\n> >> On 24/06/2022 16:53, Laurent Pinchart wrote:\n> >>> On Fri, Jun 24, 2022 at 11:26:18AM +0100, David Plowman wrote:\n> >>>> Hi everyone\n> >>>>\n> >>>> Just to add some background to this one...\n> >>>>\n> >>>> This has been causing me a little trouble in Picamera2 lately.\n> >>>> get_ready_requests used to be non-blocking so I would always call it\n> >>>> after stopping the camera to clear out any \"lurking\" requests. Since\n> >>>> it became blocking I've had to stop that but it does mean that a stray\n> >>>> request can be read out at an awkward time. This can lead to us\n> >>>> getting the \"wrong\" image (and probably falling over when it's the\n> >>>> wrong size or something), or even trying to queue it back to libcamera\n> >>>> (while the camera is still stopped).\n> >>>>\n> >>>> Anyway, either solution works for me. Either I can flush out those\n> >>>> requests after calling stop(), which is what I used to do. Or they\n> >>>> could disappear \"spontaneously\". Both work for me!!\n> >>>\n> >>> I'd like to make get_ready_requests() non-blocking unconditionally,\n> >>> could that be done ?\n> >>\n> >> I think we should have a blocking version too.\n> > \n> > Why is that ?\n> \n> It's the easiest and the most natural way to write a small script to get \n> something captured. Maybe we'll do it with a separate function, but \n> somehow we need to offer a way to capture without dealing with Selectors \n> or such.\n\nI'd prefer, if possible, to offer higher-level features on top of the\ncore bindings. By excluding them from the core bindings, I think it will\nleave room for people to experiment with higher-level camera APIs, be it\nin the Raspberry Pi camera Python code, or in other implementations.\n\n> >>>> On Fri, 24 Jun 2022 at 11:13, Kieran Bingham wrote:\n> >>>>> Quoting Tomi Valkeinen (2022-06-23 15:47:34)\n> >>>>>> Add 'nonblocking' argument to get_ready_requests() which allows the user\n> >>>>>> to ensure get_ready_requests() never blocks. This can be used e.g. after\n> >>>>>> calling camera.stop(), to process or discard any ready or cancelled\n> >>>>>> Requests.\n> >>>>>\n> >>>>> I guess I needed to read ahead for the comments I posted on the previous\n> >>>>> patch ;-)\n> >>>>>\n> >>>>>> In fact, it probably should always be used after stopping the cameras,\n> >>>>>> unless you have made sure that there are no unprocessed Requests. If you\n> >>>>>> start the camera again, and you have left Requests unprocessed, you will\n> >>>>>> get those \"old\" Requests when you expect to get the new Requests.\n> >>>>>>\n> >>>>>> It may be good to call this even if your script exits after stopping\n> >>>>>> the cameras, as unprocessed Requests will keep the Cameras and related\n> >>>>>> objects alive, and thus they won't be freed. As your script is exiting\n> >>>>>> it's strictly speaking not an issue, but it does make tracking other\n> >>>>>> \"real\" memory leaks more difficult.\n> >>>\n> >>> Developers will forget to do so, so I think a better API would be nice.\n> >>\n> >> I don't know yet what that better API could be, but perhaps something we\n> >> can easily do is to add a check in camera.start(), which will warn if\n> >> there are events about Requests already queued.\n> > \n> > That could indeed help debugging.\n> > \n> >>>>>> Perhaps the camera.start() should go and discard any old Requests\n> >>>>>> related to that camera. For the exit issue I don't see any automatic\n> >>>>>> solution.\n> >>>>>\n> >>>>> At the end of camera.stop() we should validate and ensure that all\n> >>>>> Requests are released to the application. We should hold no internal\n> >>>>> requests when camera.stop() completes.\n> >>>>>\n> >>>>> I.e. ... if we have things to discard at camera.start() - that's a bug I\n> >>>>> believe.\n> >>>>>\n> >>>>> ahhh but here perhaps the issue is that the python code is the one that\n> >>>>> has to 'retrieve' those, while in C++ they are returned via a signal?\n> >>>>>\n> >>>>> Is there any harm in discarding the requests at the end of camera.stop()\n> >>>>> such that there is simply 'nothing left to process' after? Or does the\n> >>>>> python application have to end up owning the requests to correctly\n> >>>>> release them?\n> >>>\n> >>> Sounds like an idea to explore. What's the drawback of clearing in\n> >>> stop() ?\n> >>\n> >> Losing events that you expected to get, I think.\n> >>\n> >> I'm talking here about the event handling after adding the new event\n> >> handling, as I think it's more relevant than figuring out how to do\n> >> things with just the single event.\n> >>\n> >> We could dispatch the events (All events? Or just events related to\n> >> Requests for that camera?) automatically in stop(), but that would break\n> >> the backward compatibility.\n> > \n> > I don't recall if I've mentioned it in the review of another patch in\n> > the series, but I've been thinking about dispatching events at stop\n> > time, yes. This is how libcamera operates for buffer and request\n> > completion events, doing the same in Python would make the behaviour\n> > consistent. Backward compatibility isn't a concern, the Python bindings\n> > are experimental, we shouldn't let that block the design of a good API.\n> \n> With C++, it sounds fine as the signals are fired behind the scenes. In \n> the Python bindings there's a specific call to dispatch the events. \n> Implicitly dispatching the events elsewhere can be confusing.\n\nThe explicit dispatching call is needed to work around a Python\nlimitation related to threads. I'm fine with that, but I'd like to keep\nit as much as an internal detail as possible, thus minimizing its\nexplicit usage from applications. I get your point about this being\npossibly confusing for users. I'd be interested in feedback from said\nusers :-)","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 4F911BE173\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon, 27 Jun 2022 12:25:26 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id B576B65635;\n\tMon, 27 Jun 2022 14:25:25 +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 0D8D96059B\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 27 Jun 2022 14:25:25 +0200 (CEST)","from pendragon.ideasonboard.com (62-78-145-57.bb.dnainternet.fi\n\t[62.78.145.57])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 4C96F1C82;\n\tMon, 27 Jun 2022 14:25:24 +0200 (CEST)"],"DKIM-Signature":["v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org;\n\ts=mail; t=1656332725;\n\tbh=aGHiXKA9uAA7Ma1t8B2VWiQXIimZEl5sNle3hF6J3mQ=;\n\th=Date:To:References:In-Reply-To:Subject:List-Id:List-Unsubscribe:\n\tList-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc:\n\tFrom;\n\tb=skL+i6luJv9aKPNsoQxp/WVcjfuyByukk4Sjp8gefptY0sLDn5ESioUh20Z1QSwwp\n\t2iGju4oJIzkjFShKxRzyBkEvjWW+GgW7P31ZqXmrbvaAYnNDXknG0SagZnOVQZJL9f\n\tkzps1Ocnej3SpVNYvBSm6Gy3ZJybZhbHHtapanC4465j7P28abfiZ70sgtGZT8PXFL\n\tR+G2wxtWgks8NpoxnhJMzBYsE8qqSlB2uxTml5c4H9MEaI7q7FJFuQce0Bb2HsUQPd\n\tSrp0CL/3/EMqNAlyWqsfN0XA1wWJOGQzLamB5IAqyZ+cZ0ot7EryMQnUVQCFoMBfz0\n\thduVx3hdtPuYw==","v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1656332724;\n\tbh=aGHiXKA9uAA7Ma1t8B2VWiQXIimZEl5sNle3hF6J3mQ=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=dt/T/v295RQ0TMnXmZ2X02dS9a8ZqUyckBFO7Ya6OEPNiObl7mTsAu9CBHYOAH/ga\n\tSZtohUek5LooWBzJjL0vUTcmOvLdj+xATLX59W8i/2j/8ZiYGpnPdwIQxxUhTQWw62\n\tt9+wZJDBBBiuhw4S+7j+z+TNP0cfdSekhnUvXnEI="],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key; \n\tunprotected) header.d=ideasonboard.com\n\theader.i=@ideasonboard.com\n\theader.b=\"dt/T/v29\"; dkim-atps=neutral","Date":"Mon, 27 Jun 2022 15:25:06 +0300","To":"Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>","Message-ID":"<YrmhorraByJ0t6fP@pendragon.ideasonboard.com>","References":"<20220623144736.78537-1-tomi.valkeinen@ideasonboard.com>\n\t<20220623144736.78537-6-tomi.valkeinen@ideasonboard.com>\n\t<165606562844.1149771.15547198942218026607@Monstersaurus>\n\t<CAHW6GYJ16vLOrELLE8YCayRQ-T8Sg+0SFxP8g0LXu99478a9zw@mail.gmail.com>\n\t<YrXBxMP4cOdEUI/Y@pendragon.ideasonboard.com>\n\t<ad43e5f9-e683-01d9-6c24-82cfd5ab06ce@ideasonboard.com>\n\t<YrmDkpIcGFLcrEY0@pendragon.ideasonboard.com>\n\t<4348bd1d-15c4-46cb-0e78-49562d9ef5d1@ideasonboard.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","In-Reply-To":"<4348bd1d-15c4-46cb-0e78-49562d9ef5d1@ideasonboard.com>","Subject":"Re: [libcamera-devel] [RFC v1 5/7] py: Add 'nonblocking' argument\n\tto get_ready_requests()","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":"Laurent Pinchart via libcamera-devel\n\t<libcamera-devel@lists.libcamera.org>","Reply-To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","Cc":"libcamera devel <libcamera-devel@lists.libcamera.org>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":23609,"web_url":"https://patchwork.libcamera.org/comment/23609/","msgid":"<21dd961e-feaa-6e10-b8e5-b15d8738d32b@ideasonboard.com>","date":"2022-06-27T12:54:11","subject":"Re: [libcamera-devel] [RFC v1 5/7] py: Add 'nonblocking' argument\n\tto get_ready_requests()","submitter":{"id":109,"url":"https://patchwork.libcamera.org/api/people/109/","name":"Tomi Valkeinen","email":"tomi.valkeinen@ideasonboard.com"},"content":"On 27/06/2022 15:25, Laurent Pinchart wrote:\n> Hi Tomi,\n> \n> On Mon, Jun 27, 2022 at 01:51:36PM +0300, Tomi Valkeinen wrote:\n>> On 27/06/2022 13:16, Laurent Pinchart wrote:\n>>> On Mon, Jun 27, 2022 at 12:49:45PM +0300, Tomi Valkeinen wrote:\n>>>> On 24/06/2022 16:53, Laurent Pinchart wrote:\n>>>>> On Fri, Jun 24, 2022 at 11:26:18AM +0100, David Plowman wrote:\n>>>>>> Hi everyone\n>>>>>>\n>>>>>> Just to add some background to this one...\n>>>>>>\n>>>>>> This has been causing me a little trouble in Picamera2 lately.\n>>>>>> get_ready_requests used to be non-blocking so I would always call it\n>>>>>> after stopping the camera to clear out any \"lurking\" requests. Since\n>>>>>> it became blocking I've had to stop that but it does mean that a stray\n>>>>>> request can be read out at an awkward time. This can lead to us\n>>>>>> getting the \"wrong\" image (and probably falling over when it's the\n>>>>>> wrong size or something), or even trying to queue it back to libcamera\n>>>>>> (while the camera is still stopped).\n>>>>>>\n>>>>>> Anyway, either solution works for me. Either I can flush out those\n>>>>>> requests after calling stop(), which is what I used to do. Or they\n>>>>>> could disappear \"spontaneously\". Both work for me!!\n>>>>>\n>>>>> I'd like to make get_ready_requests() non-blocking unconditionally,\n>>>>> could that be done ?\n>>>>\n>>>> I think we should have a blocking version too.\n>>>\n>>> Why is that ?\n>>\n>> It's the easiest and the most natural way to write a small script to get\n>> something captured. Maybe we'll do it with a separate function, but\n>> somehow we need to offer a way to capture without dealing with Selectors\n>> or such.\n> \n> I'd prefer, if possible, to offer higher-level features on top of the\n> core bindings. By excluding them from the core bindings, I think it will\n> leave room for people to experiment with higher-level camera APIs, be it\n> in the Raspberry Pi camera Python code, or in other implementations.\n\nThat is a valid point, but I think mine is too =). Especially with a \nfeature like this, which doesn't hide or take anything away. I don't see \nwhat a blocking version would take away from a higher level API.\n\nI'll do some experimenting, perhaps it's so trivial to use a \nnon-blocking version with Selector or something else that we can just \ndrop the blocking version.\n\nBut I do think it's important to easily provide that feature, even with \nthe core bindings. Unless we want to target the core bindings only as a \nbase for higher level libraries, which I don't think is a good idea.\n\n>>>>>>>> Perhaps the camera.start() should go and discard any old Requests\n>>>>>>>> related to that camera. For the exit issue I don't see any automatic\n>>>>>>>> solution.\n>>>>>>>\n>>>>>>> At the end of camera.stop() we should validate and ensure that all\n>>>>>>> Requests are released to the application. We should hold no internal\n>>>>>>> requests when camera.stop() completes.\n>>>>>>>\n>>>>>>> I.e. ... if we have things to discard at camera.start() - that's a bug I\n>>>>>>> believe.\n>>>>>>>\n>>>>>>> ahhh but here perhaps the issue is that the python code is the one that\n>>>>>>> has to 'retrieve' those, while in C++ they are returned via a signal?\n>>>>>>>\n>>>>>>> Is there any harm in discarding the requests at the end of camera.stop()\n>>>>>>> such that there is simply 'nothing left to process' after? Or does the\n>>>>>>> python application have to end up owning the requests to correctly\n>>>>>>> release them?\n>>>>>\n>>>>> Sounds like an idea to explore. What's the drawback of clearing in\n>>>>> stop() ?\n>>>>\n>>>> Losing events that you expected to get, I think.\n>>>>\n>>>> I'm talking here about the event handling after adding the new event\n>>>> handling, as I think it's more relevant than figuring out how to do\n>>>> things with just the single event.\n>>>>\n>>>> We could dispatch the events (All events? Or just events related to\n>>>> Requests for that camera?) automatically in stop(), but that would break\n>>>> the backward compatibility.\n>>>\n>>> I don't recall if I've mentioned it in the review of another patch in\n>>> the series, but I've been thinking about dispatching events at stop\n>>> time, yes. This is how libcamera operates for buffer and request\n>>> completion events, doing the same in Python would make the behaviour\n>>> consistent. Backward compatibility isn't a concern, the Python bindings\n>>> are experimental, we shouldn't let that block the design of a good API.\n>>\n>> With C++, it sounds fine as the signals are fired behind the scenes. In\n>> the Python bindings there's a specific call to dispatch the events.\n>> Implicitly dispatching the events elsewhere can be confusing.\n> \n> The explicit dispatching call is needed to work around a Python\n> limitation related to threads. I'm fine with that, but I'd like to keep\n> it as much as an internal detail as possible, thus minimizing its\n> explicit usage from applications. I get your point about this being\n> possibly confusing for users. I'd be interested in feedback from said\n> users :-)\n\nMe too, but this is a rather difficult question to answer, so I don't \nreally expect to get help here =).\n\nI do like the idea of somehow forcibly making the events handled at \ncamera.stop() time, though.\n\nAlthough there may be other events queued anyway. Say, camera_added. \nThose will stay in the event queue, holding references to the relevant \nobjects, until the user calls dispatch_events().\n\nThen again those don't cause similar problems as getting \"old\" Request \nevents after restarting a camera, so maybe they are fine.\n\nIf the user wants a clean exit, he needs to either dispatch or discard \nthose events, otherwise the cameras and camera managers will be kept \nalive at the app exit time.\n\n  Tomi","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 3C177BD808\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon, 27 Jun 2022 12:54:19 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 6217D65635;\n\tMon, 27 Jun 2022 14:54:18 +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 539AE6059B\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 27 Jun 2022 14:54:15 +0200 (CEST)","from [192.168.1.111] (91-158-154-79.elisa-laajakaista.fi\n\t[91.158.154.79])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 5015E1C82;\n\tMon, 27 Jun 2022 14:54:14 +0200 (CEST)"],"DKIM-Signature":["v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org;\n\ts=mail; t=1656334458;\n\tbh=q71s3iRvmrgx9gt2F5mfUoaF3slRHrLZE8/7ycyobA8=;\n\th=Date:To:References:In-Reply-To:Subject:List-Id:List-Unsubscribe:\n\tList-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc:\n\tFrom;\n\tb=Zlzuj0PGbQNLxzVjd3sxOUqXg8KJAIARa3UOPMPnm7rSfPcKg1wRatuz9+Lr+CH1C\n\trkBpktvlohWSs4Sezeyfk6PziNZPy8XHRtfq9O2djIkrLiO0t6E8rP/CvkLWSBNpiF\n\tW+dDk1Sui9+ehlVDmne4OO5arESzyvlJn8Y+vnJkjg16YGSoyyCSv1zB9mTgI2vCSr\n\thMA9jpmb3pa4Bqve5mEHUvdnHG7Pfam+CcQL6LYCToQyuxedJSwENXr3aaJNWRAndH\n\t1JhMI+pUMY+7HZk2M1zcICqb4x4YQybVkqhEn77BdWWiqRaheZGN9aKlKK7XSW5XhP\n\tXGvxl+yie4fzA==","v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1656334454;\n\tbh=q71s3iRvmrgx9gt2F5mfUoaF3slRHrLZE8/7ycyobA8=;\n\th=Date:Subject:To:Cc:References:From:In-Reply-To:From;\n\tb=K6FXPbntaWKdAdUNWWmZx1ZaShNiQKHAKdrk3x8k758vjNMEa8isMXWquYgMY/JGp\n\t+WEl8YLD/d7818nOAKn6T26GJi66sw+bICCRid9SZegybWR8Ws3ztOAeTQot9rl9MI\n\tg97U9fFc+21dFNnodJMiXcX5klWI/STEcPKYK6ns="],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key; \n\tunprotected) header.d=ideasonboard.com\n\theader.i=@ideasonboard.com\n\theader.b=\"K6FXPbnt\"; dkim-atps=neutral","Message-ID":"<21dd961e-feaa-6e10-b8e5-b15d8738d32b@ideasonboard.com>","Date":"Mon, 27 Jun 2022 15:54:11 +0300","MIME-Version":"1.0","User-Agent":"Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101\n\tThunderbird/91.9.1","Content-Language":"en-US","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","References":"<20220623144736.78537-1-tomi.valkeinen@ideasonboard.com>\n\t<20220623144736.78537-6-tomi.valkeinen@ideasonboard.com>\n\t<165606562844.1149771.15547198942218026607@Monstersaurus>\n\t<CAHW6GYJ16vLOrELLE8YCayRQ-T8Sg+0SFxP8g0LXu99478a9zw@mail.gmail.com>\n\t<YrXBxMP4cOdEUI/Y@pendragon.ideasonboard.com>\n\t<ad43e5f9-e683-01d9-6c24-82cfd5ab06ce@ideasonboard.com>\n\t<YrmDkpIcGFLcrEY0@pendragon.ideasonboard.com>\n\t<4348bd1d-15c4-46cb-0e78-49562d9ef5d1@ideasonboard.com>\n\t<YrmhorraByJ0t6fP@pendragon.ideasonboard.com>","In-Reply-To":"<YrmhorraByJ0t6fP@pendragon.ideasonboard.com>","Content-Type":"text/plain; charset=UTF-8; format=flowed","Content-Transfer-Encoding":"7bit","Subject":"Re: [libcamera-devel] [RFC v1 5/7] py: Add 'nonblocking' argument\n\tto get_ready_requests()","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>","Cc":"libcamera devel <libcamera-devel@lists.libcamera.org>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":23618,"web_url":"https://patchwork.libcamera.org/comment/23618/","msgid":"<YroWTianZr8FDSsL@pendragon.ideasonboard.com>","date":"2022-06-27T20:42:54","subject":"Re: [libcamera-devel] [RFC v1 5/7] py: Add 'nonblocking' argument\n\tto get_ready_requests()","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"Hi Tomi,\n\nOn Mon, Jun 27, 2022 at 03:54:11PM +0300, Tomi Valkeinen wrote:\n> On 27/06/2022 15:25, Laurent Pinchart wrote:\n> > On Mon, Jun 27, 2022 at 01:51:36PM +0300, Tomi Valkeinen wrote:\n> >> On 27/06/2022 13:16, Laurent Pinchart wrote:\n> >>> On Mon, Jun 27, 2022 at 12:49:45PM +0300, Tomi Valkeinen wrote:\n> >>>> On 24/06/2022 16:53, Laurent Pinchart wrote:\n> >>>>> On Fri, Jun 24, 2022 at 11:26:18AM +0100, David Plowman wrote:\n> >>>>>> Hi everyone\n> >>>>>>\n> >>>>>> Just to add some background to this one...\n> >>>>>>\n> >>>>>> This has been causing me a little trouble in Picamera2 lately.\n> >>>>>> get_ready_requests used to be non-blocking so I would always call it\n> >>>>>> after stopping the camera to clear out any \"lurking\" requests. Since\n> >>>>>> it became blocking I've had to stop that but it does mean that a stray\n> >>>>>> request can be read out at an awkward time. This can lead to us\n> >>>>>> getting the \"wrong\" image (and probably falling over when it's the\n> >>>>>> wrong size or something), or even trying to queue it back to libcamera\n> >>>>>> (while the camera is still stopped).\n> >>>>>>\n> >>>>>> Anyway, either solution works for me. Either I can flush out those\n> >>>>>> requests after calling stop(), which is what I used to do. Or they\n> >>>>>> could disappear \"spontaneously\". Both work for me!!\n> >>>>>\n> >>>>> I'd like to make get_ready_requests() non-blocking unconditionally,\n> >>>>> could that be done ?\n> >>>>\n> >>>> I think we should have a blocking version too.\n> >>>\n> >>> Why is that ?\n> >>\n> >> It's the easiest and the most natural way to write a small script to get\n> >> something captured. Maybe we'll do it with a separate function, but\n> >> somehow we need to offer a way to capture without dealing with Selectors\n> >> or such.\n> > \n> > I'd prefer, if possible, to offer higher-level features on top of the\n> > core bindings. By excluding them from the core bindings, I think it will\n> > leave room for people to experiment with higher-level camera APIs, be it\n> > in the Raspberry Pi camera Python code, or in other implementations.\n> \n> That is a valid point, but I think mine is too =). Especially with a \n> feature like this, which doesn't hide or take anything away. I don't see \n> what a blocking version would take away from a higher level API.\n> \n> I'll do some experimenting, perhaps it's so trivial to use a \n> non-blocking version with Selector or something else that we can just \n> drop the blocking version.\n\nIf it's not trivial then maybe it means the core bindings are not good\nenough :-) Implementing this purely in Python would be a good test.\n\n> But I do think it's important to easily provide that feature, even with \n> the core bindings. Unless we want to target the core bindings only as a \n> base for higher level libraries, which I don't think is a good idea.\n\nIt seems to be time to start discussing this. So far, I would prefer\nhaving the core bindings matching the C++ API as closely as possible,\nwithout additional features, and having convenience helpers developed on\ntop. We could develop our own convenience helpers shipped with libcamera\nof course.\n\nAnyone else wants to chime in ?\n\n> >>>>>>>> Perhaps the camera.start() should go and discard any old Requests\n> >>>>>>>> related to that camera. For the exit issue I don't see any automatic\n> >>>>>>>> solution.\n> >>>>>>>\n> >>>>>>> At the end of camera.stop() we should validate and ensure that all\n> >>>>>>> Requests are released to the application. We should hold no internal\n> >>>>>>> requests when camera.stop() completes.\n> >>>>>>>\n> >>>>>>> I.e. ... if we have things to discard at camera.start() - that's a bug I\n> >>>>>>> believe.\n> >>>>>>>\n> >>>>>>> ahhh but here perhaps the issue is that the python code is the one that\n> >>>>>>> has to 'retrieve' those, while in C++ they are returned via a signal?\n> >>>>>>>\n> >>>>>>> Is there any harm in discarding the requests at the end of camera.stop()\n> >>>>>>> such that there is simply 'nothing left to process' after? Or does the\n> >>>>>>> python application have to end up owning the requests to correctly\n> >>>>>>> release them?\n> >>>>>\n> >>>>> Sounds like an idea to explore. What's the drawback of clearing in\n> >>>>> stop() ?\n> >>>>\n> >>>> Losing events that you expected to get, I think.\n> >>>>\n> >>>> I'm talking here about the event handling after adding the new event\n> >>>> handling, as I think it's more relevant than figuring out how to do\n> >>>> things with just the single event.\n> >>>>\n> >>>> We could dispatch the events (All events? Or just events related to\n> >>>> Requests for that camera?) automatically in stop(), but that would break\n> >>>> the backward compatibility.\n> >>>\n> >>> I don't recall if I've mentioned it in the review of another patch in\n> >>> the series, but I've been thinking about dispatching events at stop\n> >>> time, yes. This is how libcamera operates for buffer and request\n> >>> completion events, doing the same in Python would make the behaviour\n> >>> consistent. Backward compatibility isn't a concern, the Python bindings\n> >>> are experimental, we shouldn't let that block the design of a good API.\n> >>\n> >> With C++, it sounds fine as the signals are fired behind the scenes. In\n> >> the Python bindings there's a specific call to dispatch the events.\n> >> Implicitly dispatching the events elsewhere can be confusing.\n> > \n> > The explicit dispatching call is needed to work around a Python\n> > limitation related to threads. I'm fine with that, but I'd like to keep\n> > it as much as an internal detail as possible, thus minimizing its\n> > explicit usage from applications. I get your point about this being\n> > possibly confusing for users. I'd be interested in feedback from said\n> > users :-)\n> \n> Me too, but this is a rather difficult question to answer, so I don't \n> really expect to get help here =).\n\nMaybe David could shine some light here, as our mean user of the core\nbindings at this point ?\n\n> I do like the idea of somehow forcibly making the events handled at \n> camera.stop() time, though.\n> \n> Although there may be other events queued anyway. Say, camera_added. \n> Those will stay in the event queue, holding references to the relevant \n> objects, until the user calls dispatch_events().\n\nWe could only dispatch buffer and request completion events in stop()\nfor the camera being stopped, that would be fine with me. I'm not sure\nif we would gain much from such a selective dispatch though, but it\nwould certainly mimic the C++ API.\n\n> Then again those don't cause similar problems as getting \"old\" Request \n> events after restarting a camera, so maybe they are fine.\n> \n> If the user wants a clean exit, he needs to either dispatch or discard \n> those events, otherwise the cameras and camera managers will be kept \n> alive at the app exit time.\n\nMaybe a cleanup function on the camera manager would do the job ? We're\ngoing back to explicit start/stop then though :-)","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 B21B5BE173\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon, 27 Jun 2022 20:43:18 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id EDDF665635;\n\tMon, 27 Jun 2022 22:43:17 +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 CAE2D6059B\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 27 Jun 2022 22:43:15 +0200 (CEST)","from pendragon.ideasonboard.com (62-78-145-57.bb.dnainternet.fi\n\t[62.78.145.57])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 5484D1C82;\n\tMon, 27 Jun 2022 22:43:13 +0200 (CEST)"],"DKIM-Signature":["v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org;\n\ts=mail; t=1656362598;\n\tbh=7/5yA7IkdzcGkif9+N83GxA5v7/oo+Qzyhcw3Xn+9sA=;\n\th=Date:To:References:In-Reply-To:Subject:List-Id:List-Unsubscribe:\n\tList-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc:\n\tFrom;\n\tb=qjY+rvDNsHfHspTaCFK5qGLjz/gqERtXEciUCWcDwLkuTHMxg6nEc3MxOgb9xma6d\n\tRy1Q8kwUvbH5CfhkM6pqVLricC1R1ykrtSUev1AL+vfdqdGqU2jASTbpJfxZXJNwdY\n\tOzwf8TJRjnTlrkK4BT+PUmX1O8rqHUjZU9xuj12roPVAWY69VBnLdhw+KM8Ah5R2VX\n\teS2vS+7jSDx3wkTwqs5+T8i/F0f5aPWHGLehbgpnmi1TX00kXs34UCjdKEZkkMEk1l\n\t87YOVB6lilqmouB60bn2nVKTCayHRSuNa3HSlzxyE36WvdBgC3t+NsJhG7DjiNjdKR\n\tovfDWvIm7SrjQ==","v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1656362595;\n\tbh=7/5yA7IkdzcGkif9+N83GxA5v7/oo+Qzyhcw3Xn+9sA=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=Qk8KnCaKzfbg64LivhMVjHz9M17aMuuxBqPd9Eb0XvOv8pbtgUPTP1tCGnpFtj7+T\n\tBJWsDEoba5YuUXVpLhOkE7gsTzYMBi/z+i4fYgsy95DahSgjm8APN8jRExbWfVqzZf\n\tKCSJA0CtKjCuieO/wNQmMurILB/C/E/dz1Sc/hi4="],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key; \n\tunprotected) header.d=ideasonboard.com\n\theader.i=@ideasonboard.com\n\theader.b=\"Qk8KnCaK\"; dkim-atps=neutral","Date":"Mon, 27 Jun 2022 23:42:54 +0300","To":"Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>","Message-ID":"<YroWTianZr8FDSsL@pendragon.ideasonboard.com>","References":"<20220623144736.78537-1-tomi.valkeinen@ideasonboard.com>\n\t<20220623144736.78537-6-tomi.valkeinen@ideasonboard.com>\n\t<165606562844.1149771.15547198942218026607@Monstersaurus>\n\t<CAHW6GYJ16vLOrELLE8YCayRQ-T8Sg+0SFxP8g0LXu99478a9zw@mail.gmail.com>\n\t<YrXBxMP4cOdEUI/Y@pendragon.ideasonboard.com>\n\t<ad43e5f9-e683-01d9-6c24-82cfd5ab06ce@ideasonboard.com>\n\t<YrmDkpIcGFLcrEY0@pendragon.ideasonboard.com>\n\t<4348bd1d-15c4-46cb-0e78-49562d9ef5d1@ideasonboard.com>\n\t<YrmhorraByJ0t6fP@pendragon.ideasonboard.com>\n\t<21dd961e-feaa-6e10-b8e5-b15d8738d32b@ideasonboard.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","In-Reply-To":"<21dd961e-feaa-6e10-b8e5-b15d8738d32b@ideasonboard.com>","Subject":"Re: [libcamera-devel] [RFC v1 5/7] py: Add 'nonblocking' argument\n\tto get_ready_requests()","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":"Laurent Pinchart via libcamera-devel\n\t<libcamera-devel@lists.libcamera.org>","Reply-To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","Cc":"libcamera devel <libcamera-devel@lists.libcamera.org>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":23631,"web_url":"https://patchwork.libcamera.org/comment/23631/","msgid":"<4e58f214-08ff-65ff-2449-911d81d99ac2@ideasonboard.com>","date":"2022-06-28T07:08:44","subject":"Re: [libcamera-devel] [RFC v1 5/7] py: Add 'nonblocking' argument\n\tto get_ready_requests()","submitter":{"id":109,"url":"https://patchwork.libcamera.org/api/people/109/","name":"Tomi Valkeinen","email":"tomi.valkeinen@ideasonboard.com"},"content":"On 27/06/2022 23:42, Laurent Pinchart wrote:\n> Hi Tomi,\n> \n> On Mon, Jun 27, 2022 at 03:54:11PM +0300, Tomi Valkeinen wrote:\n>> On 27/06/2022 15:25, Laurent Pinchart wrote:\n>>> On Mon, Jun 27, 2022 at 01:51:36PM +0300, Tomi Valkeinen wrote:\n>>>> On 27/06/2022 13:16, Laurent Pinchart wrote:\n>>>>> On Mon, Jun 27, 2022 at 12:49:45PM +0300, Tomi Valkeinen wrote:\n>>>>>> On 24/06/2022 16:53, Laurent Pinchart wrote:\n>>>>>>> On Fri, Jun 24, 2022 at 11:26:18AM +0100, David Plowman wrote:\n>>>>>>>> Hi everyone\n>>>>>>>>\n>>>>>>>> Just to add some background to this one...\n>>>>>>>>\n>>>>>>>> This has been causing me a little trouble in Picamera2 lately.\n>>>>>>>> get_ready_requests used to be non-blocking so I would always call it\n>>>>>>>> after stopping the camera to clear out any \"lurking\" requests. Since\n>>>>>>>> it became blocking I've had to stop that but it does mean that a stray\n>>>>>>>> request can be read out at an awkward time. This can lead to us\n>>>>>>>> getting the \"wrong\" image (and probably falling over when it's the\n>>>>>>>> wrong size or something), or even trying to queue it back to libcamera\n>>>>>>>> (while the camera is still stopped).\n>>>>>>>>\n>>>>>>>> Anyway, either solution works for me. Either I can flush out those\n>>>>>>>> requests after calling stop(), which is what I used to do. Or they\n>>>>>>>> could disappear \"spontaneously\". Both work for me!!\n>>>>>>>\n>>>>>>> I'd like to make get_ready_requests() non-blocking unconditionally,\n>>>>>>> could that be done ?\n>>>>>>\n>>>>>> I think we should have a blocking version too.\n>>>>>\n>>>>> Why is that ?\n>>>>\n>>>> It's the easiest and the most natural way to write a small script to get\n>>>> something captured. Maybe we'll do it with a separate function, but\n>>>> somehow we need to offer a way to capture without dealing with Selectors\n>>>> or such.\n>>>\n>>> I'd prefer, if possible, to offer higher-level features on top of the\n>>> core bindings. By excluding them from the core bindings, I think it will\n>>> leave room for people to experiment with higher-level camera APIs, be it\n>>> in the Raspberry Pi camera Python code, or in other implementations.\n>>\n>> That is a valid point, but I think mine is too =). Especially with a\n>> feature like this, which doesn't hide or take anything away. I don't see\n>> what a blocking version would take away from a higher level API.\n>>\n>> I'll do some experimenting, perhaps it's so trivial to use a\n>> non-blocking version with Selector or something else that we can just\n>> drop the blocking version.\n> \n> If it's not trivial then maybe it means the core bindings are not good\n> enough :-) Implementing this purely in Python would be a good test.\n\nOh, it's trivial in Python in the sense that it's a few lines of code. \nBut it's not trivial in the sense that you could just write\n\nwhile True:\n\t# This waits until there are requests\n         reqs = cm.get_ready_requests()\n         for req in reqs:\n\t\tdo something\n\nWe can easily write a helper function on top of non-blocking API to \nachieve the above.\n\n>> But I do think it's important to easily provide that feature, even with\n>> the core bindings. Unless we want to target the core bindings only as a\n>> base for higher level libraries, which I don't think is a good idea.\n> \n> It seems to be time to start discussing this. So far, I would prefer\n> having the core bindings matching the C++ API as closely as possible,\n> without additional features, and having convenience helpers developed on\n> top. We could develop our own convenience helpers shipped with libcamera\n> of course.\n\nI can't make my mind on this. On one hand, what you suggest is a clean \napproach. On the other, if we have a core bindings module and a \nconvenience module on top, it brings up some questions:\n\n- Module naming. libcamera-core and libcamera? libcamera and \nlibcamera-for-dummies?\n\n- Is the convenience module just a sugar topping, i.e. helper \nfunctions/classes here and there, or is it something that fully wraps \nthe core (somewhat like pilibcamera2)?\n\n- If it's just some helpers, what is the benefit of using the core module?\n\n- If it fully wraps the core, most likely it somewhat dummies down the \nlibcamera features. If so, there are always users for the core module. \nThose users would most likely want to use simple helpers like blocking \nwait or mmapped fb.\n\n- Perhaps a third module option would be something in between: a module \nthat \"pythonizes\" the classes, while still exposing everything. But are \nthe convenience features part of that, or yet another module on top? \nSuch a module also brings up the annoyance that you would access many \nthings via the higher level module (say, pylibcamera.Camera), but \nprobably many things would be just exposed from libcamera module if we \ndon't do a full wrap (say, camera.set_format(libcamera.formats.RGB123).\n\nSo... I think it's clear that a fully wrapping module is obviously a new \nmodule on top of the core bindings. But the simple helpers and possibly \nthe pythonization could be part of the core bindings, or on top.\n\nIt's clear that features like mmapped fb class and blocking wait are \nfeatures that are needed by the users, so I think it's not a question of \nshould we have those, but where should they be.\n\nAlso, not that even if the helpers would be part of the core bindings, \nwe could have internal split there: the bindings made in C++ would be \nthe core bindings, and in the same module we could have convenience \nfeatures written in Python (similar to the MappedFrameBuffer.py we have \nnow). However, while that sounds nice, I don't know if there's any real \nlogic to it. If something is easier/better written in the C++ bindings, \nI don't see a point in forcing that feature to be written in Python instead.\n\n> Anyone else wants to chime in ?\n> \n>>>>>>>>>> Perhaps the camera.start() should go and discard any old Requests\n>>>>>>>>>> related to that camera. For the exit issue I don't see any automatic\n>>>>>>>>>> solution.\n>>>>>>>>>\n>>>>>>>>> At the end of camera.stop() we should validate and ensure that all\n>>>>>>>>> Requests are released to the application. We should hold no internal\n>>>>>>>>> requests when camera.stop() completes.\n>>>>>>>>>\n>>>>>>>>> I.e. ... if we have things to discard at camera.start() - that's a bug I\n>>>>>>>>> believe.\n>>>>>>>>>\n>>>>>>>>> ahhh but here perhaps the issue is that the python code is the one that\n>>>>>>>>> has to 'retrieve' those, while in C++ they are returned via a signal?\n>>>>>>>>>\n>>>>>>>>> Is there any harm in discarding the requests at the end of camera.stop()\n>>>>>>>>> such that there is simply 'nothing left to process' after? Or does the\n>>>>>>>>> python application have to end up owning the requests to correctly\n>>>>>>>>> release them?\n>>>>>>>\n>>>>>>> Sounds like an idea to explore. What's the drawback of clearing in\n>>>>>>> stop() ?\n>>>>>>\n>>>>>> Losing events that you expected to get, I think.\n>>>>>>\n>>>>>> I'm talking here about the event handling after adding the new event\n>>>>>> handling, as I think it's more relevant than figuring out how to do\n>>>>>> things with just the single event.\n>>>>>>\n>>>>>> We could dispatch the events (All events? Or just events related to\n>>>>>> Requests for that camera?) automatically in stop(), but that would break\n>>>>>> the backward compatibility.\n>>>>>\n>>>>> I don't recall if I've mentioned it in the review of another patch in\n>>>>> the series, but I've been thinking about dispatching events at stop\n>>>>> time, yes. This is how libcamera operates for buffer and request\n>>>>> completion events, doing the same in Python would make the behaviour\n>>>>> consistent. Backward compatibility isn't a concern, the Python bindings\n>>>>> are experimental, we shouldn't let that block the design of a good API.\n>>>>\n>>>> With C++, it sounds fine as the signals are fired behind the scenes. In\n>>>> the Python bindings there's a specific call to dispatch the events.\n>>>> Implicitly dispatching the events elsewhere can be confusing.\n>>>\n>>> The explicit dispatching call is needed to work around a Python\n>>> limitation related to threads. I'm fine with that, but I'd like to keep\n>>> it as much as an internal detail as possible, thus minimizing its\n>>> explicit usage from applications. I get your point about this being\n>>> possibly confusing for users. I'd be interested in feedback from said\n>>> users :-)\n>>\n>> Me too, but this is a rather difficult question to answer, so I don't\n>> really expect to get help here =).\n> \n> Maybe David could shine some light here, as our mean user of the core\n> bindings at this point ?\n> \n>> I do like the idea of somehow forcibly making the events handled at\n>> camera.stop() time, though.\n>>\n>> Although there may be other events queued anyway. Say, camera_added.\n>> Those will stay in the event queue, holding references to the relevant\n>> objects, until the user calls dispatch_events().\n> \n> We could only dispatch buffer and request completion events in stop()\n> for the camera being stopped, that would be fine with me. I'm not sure\n> if we would gain much from such a selective dispatch though, but it\n> would certainly mimic the C++ API.\n> \n>> Then again those don't cause similar problems as getting \"old\" Request\n>> events after restarting a camera, so maybe they are fine.\n>>\n>> If the user wants a clean exit, he needs to either dispatch or discard\n>> those events, otherwise the cameras and camera managers will be kept\n>> alive at the app exit time.\n> \n> Maybe a cleanup function on the camera manager would do the job ? We're\n> going back to explicit start/stop then though :-)\n\nThe discard_events() is essentially a cleanup function.\n\nPerhaps we can do some clever weak-ref tricks there, though... I think \nthe events should not keep anything alive. Oh, but we depend on the \nevent keeping the Request alive, so that doesn't work.\n\n  Tomi","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 186BBBD808\n\tfor <parsemail@patchwork.libcamera.org>;\n\tTue, 28 Jun 2022 07:08:50 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 8169E65635;\n\tTue, 28 Jun 2022 09:08:49 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id D0ED16559A\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 28 Jun 2022 09:08:48 +0200 (CEST)","from [192.168.1.111] (91-158-154-79.elisa-laajakaista.fi\n\t[91.158.154.79])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id E170555A;\n\tTue, 28 Jun 2022 09:08:47 +0200 (CEST)"],"DKIM-Signature":["v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org;\n\ts=mail; t=1656400129;\n\tbh=PrPEQzqg2fEcj/ETM8Xb8Rsio4omUdlit9fK4w3wFV4=;\n\th=Date:To:References:In-Reply-To:Subject:List-Id:List-Unsubscribe:\n\tList-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc:\n\tFrom;\n\tb=yMRi/wRqNclJOP7HZB9cnLMpAmDevaRQ+Eulb/x8wYnJx1hu9OGAHGCE8/yMojW7T\n\tp5xx49uuLREyTy7el2UoSKmQXK8lVi0EYHofA77ggjGxS2bAxbzjTI2aCoa+NbQJHn\n\tVf7X+Qu1apP9x82CfhKCwe6HlQhCJHObp0NjANqVYSWJTSdA6+drT6kcEpbT5wsAQK\n\tuv1SxTvMXuxMUtsC9U0BgRSl0VHMrqLyzIjhUXhFivcsWIFRNpGJaXXAgMz3bzsCGr\n\tnfYX2bXqXDXmdNp0bhj7uvnEv5u/PB8gMwnShDkd3SGRgjp+m/P70NfOqqY2YiHre8\n\tZHjW+p49dftiQ==","v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1656400128;\n\tbh=PrPEQzqg2fEcj/ETM8Xb8Rsio4omUdlit9fK4w3wFV4=;\n\th=Date:Subject:To:Cc:References:From:In-Reply-To:From;\n\tb=u78E4GPEfNYLN8Y6LVV6iEZ83KJkjubvANAYxrH7bkE3KY9kTYMYi672dkoyf6O0f\n\tHLiM9d0El1pWT7Q+Gv2cURuHmiN69PoAN8BRjdafk3ULtolrbYPICu2e7tad0FQkl4\n\tpy2/px7u0vIrZYvXun24VCh3wy/Bhc8ejcnElFdo="],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key; \n\tunprotected) header.d=ideasonboard.com\n\theader.i=@ideasonboard.com\n\theader.b=\"u78E4GPE\"; dkim-atps=neutral","Message-ID":"<4e58f214-08ff-65ff-2449-911d81d99ac2@ideasonboard.com>","Date":"Tue, 28 Jun 2022 10:08:44 +0300","MIME-Version":"1.0","User-Agent":"Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101\n\tThunderbird/91.9.1","Content-Language":"en-US","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","References":"<20220623144736.78537-1-tomi.valkeinen@ideasonboard.com>\n\t<20220623144736.78537-6-tomi.valkeinen@ideasonboard.com>\n\t<165606562844.1149771.15547198942218026607@Monstersaurus>\n\t<CAHW6GYJ16vLOrELLE8YCayRQ-T8Sg+0SFxP8g0LXu99478a9zw@mail.gmail.com>\n\t<YrXBxMP4cOdEUI/Y@pendragon.ideasonboard.com>\n\t<ad43e5f9-e683-01d9-6c24-82cfd5ab06ce@ideasonboard.com>\n\t<YrmDkpIcGFLcrEY0@pendragon.ideasonboard.com>\n\t<4348bd1d-15c4-46cb-0e78-49562d9ef5d1@ideasonboard.com>\n\t<YrmhorraByJ0t6fP@pendragon.ideasonboard.com>\n\t<21dd961e-feaa-6e10-b8e5-b15d8738d32b@ideasonboard.com>\n\t<YroWTianZr8FDSsL@pendragon.ideasonboard.com>","In-Reply-To":"<YroWTianZr8FDSsL@pendragon.ideasonboard.com>","Content-Type":"text/plain; charset=UTF-8; format=flowed","Content-Transfer-Encoding":"7bit","Subject":"Re: [libcamera-devel] [RFC v1 5/7] py: Add 'nonblocking' argument\n\tto get_ready_requests()","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>","Cc":"libcamera devel <libcamera-devel@lists.libcamera.org>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":23633,"web_url":"https://patchwork.libcamera.org/comment/23633/","msgid":"<CAHW6GYLo_4ERGLHuSmmO9_vpH6TCC1bc5_TyC7aMJn41g=2Dyg@mail.gmail.com>","date":"2022-06-28T08:16:24","subject":"Re: [libcamera-devel] [RFC v1 5/7] py: Add 'nonblocking' argument\n\tto get_ready_requests()","submitter":{"id":42,"url":"https://patchwork.libcamera.org/api/people/42/","name":"David Plowman","email":"david.plowman@raspberrypi.com"},"content":"Hi everyone\n\nSorry for not taking part in this discussion rather more, and thanks\nto those who have! I think I was asked further back if I had an\nopinion, so let me try and explain how I see things.\n\nActually I don't have any particularly strong opinions, other than\nthat I want things to work and to be easy to use. And if they stopped\nchanging, that would be nice too!!\n\nI was actually OK with the previous version where get_ready_requests\nwas non-blocking, it's only the more recent version that causes me\nsome trouble because I can't simply flush out any lurking requests\nafter stopping the camera - because there might not be any and I will\nsimply lock up the system.\n\nIt's perhaps worth noting that, like our C++ apps, I recycle requests\nback to libcamera just as soon as is humanly possible, as that's the\nbest way to avoid frame drops. The number of request objects that I\nmake is typically from 1 to about 8 (inclusive).\n\nI'm happy to go back to the non-blocking version, or I'm happy to have\na blocking version where I'm guaranteed not to get any more requests\nout once the camera has stopped. Once the camera is stopped I just\ndiscard all my requests and don't want to see them again! I suppose if\nthey came out later but were marked as \"cancelled\" that would be\nworkable, though it feels less tidy.\n\nI would dislike the approach where I have to keep track of which\nrequests I've sent and which ones haven't yet come back, so that I\nknow whether there are lurking requests that I have to wait for. Not\nthat it's difficult, it's just annoying, and I expect it would be a\nnuisance to very many Python users. It might also be slow if there are\nquite a few requests still to be fulfilled (depending on whether they\ncan be \"cancelled\" quickly).\n\nI guess there are other solutions where maybe I could test if the file\ndescriptor is readable and so on, but again, why would we make it\ncomplicated like this?\n\nI did notice the comment earlier that the Python bindings are far from\nstable. I certainly agree that where things are unfinished or untidy,\nthose things need to be sorted out, but in other areas we basically\nhave what we need for all our functionality, and so would be happy to\nsee less churn. I don't know if that's possible in the short term...\n\nSo maybe I did have some opinions after all!\n\nThanks everyone\nDavid\n\nOn Tue, 28 Jun 2022 at 08:08, Tomi Valkeinen\n<tomi.valkeinen@ideasonboard.com> wrote:\n>\n> On 27/06/2022 23:42, Laurent Pinchart wrote:\n> > Hi Tomi,\n> >\n> > On Mon, Jun 27, 2022 at 03:54:11PM +0300, Tomi Valkeinen wrote:\n> >> On 27/06/2022 15:25, Laurent Pinchart wrote:\n> >>> On Mon, Jun 27, 2022 at 01:51:36PM +0300, Tomi Valkeinen wrote:\n> >>>> On 27/06/2022 13:16, Laurent Pinchart wrote:\n> >>>>> On Mon, Jun 27, 2022 at 12:49:45PM +0300, Tomi Valkeinen wrote:\n> >>>>>> On 24/06/2022 16:53, Laurent Pinchart wrote:\n> >>>>>>> On Fri, Jun 24, 2022 at 11:26:18AM +0100, David Plowman wrote:\n> >>>>>>>> Hi everyone\n> >>>>>>>>\n> >>>>>>>> Just to add some background to this one...\n> >>>>>>>>\n> >>>>>>>> This has been causing me a little trouble in Picamera2 lately.\n> >>>>>>>> get_ready_requests used to be non-blocking so I would always call it\n> >>>>>>>> after stopping the camera to clear out any \"lurking\" requests. Since\n> >>>>>>>> it became blocking I've had to stop that but it does mean that a stray\n> >>>>>>>> request can be read out at an awkward time. This can lead to us\n> >>>>>>>> getting the \"wrong\" image (and probably falling over when it's the\n> >>>>>>>> wrong size or something), or even trying to queue it back to libcamera\n> >>>>>>>> (while the camera is still stopped).\n> >>>>>>>>\n> >>>>>>>> Anyway, either solution works for me. Either I can flush out those\n> >>>>>>>> requests after calling stop(), which is what I used to do. Or they\n> >>>>>>>> could disappear \"spontaneously\". Both work for me!!\n> >>>>>>>\n> >>>>>>> I'd like to make get_ready_requests() non-blocking unconditionally,\n> >>>>>>> could that be done ?\n> >>>>>>\n> >>>>>> I think we should have a blocking version too.\n> >>>>>\n> >>>>> Why is that ?\n> >>>>\n> >>>> It's the easiest and the most natural way to write a small script to get\n> >>>> something captured. Maybe we'll do it with a separate function, but\n> >>>> somehow we need to offer a way to capture without dealing with Selectors\n> >>>> or such.\n> >>>\n> >>> I'd prefer, if possible, to offer higher-level features on top of the\n> >>> core bindings. By excluding them from the core bindings, I think it will\n> >>> leave room for people to experiment with higher-level camera APIs, be it\n> >>> in the Raspberry Pi camera Python code, or in other implementations.\n> >>\n> >> That is a valid point, but I think mine is too =). Especially with a\n> >> feature like this, which doesn't hide or take anything away. I don't see\n> >> what a blocking version would take away from a higher level API.\n> >>\n> >> I'll do some experimenting, perhaps it's so trivial to use a\n> >> non-blocking version with Selector or something else that we can just\n> >> drop the blocking version.\n> >\n> > If it's not trivial then maybe it means the core bindings are not good\n> > enough :-) Implementing this purely in Python would be a good test.\n>\n> Oh, it's trivial in Python in the sense that it's a few lines of code.\n> But it's not trivial in the sense that you could just write\n>\n> while True:\n>         # This waits until there are requests\n>          reqs = cm.get_ready_requests()\n>          for req in reqs:\n>                 do something\n>\n> We can easily write a helper function on top of non-blocking API to\n> achieve the above.\n>\n> >> But I do think it's important to easily provide that feature, even with\n> >> the core bindings. Unless we want to target the core bindings only as a\n> >> base for higher level libraries, which I don't think is a good idea.\n> >\n> > It seems to be time to start discussing this. So far, I would prefer\n> > having the core bindings matching the C++ API as closely as possible,\n> > without additional features, and having convenience helpers developed on\n> > top. We could develop our own convenience helpers shipped with libcamera\n> > of course.\n>\n> I can't make my mind on this. On one hand, what you suggest is a clean\n> approach. On the other, if we have a core bindings module and a\n> convenience module on top, it brings up some questions:\n>\n> - Module naming. libcamera-core and libcamera? libcamera and\n> libcamera-for-dummies?\n>\n> - Is the convenience module just a sugar topping, i.e. helper\n> functions/classes here and there, or is it something that fully wraps\n> the core (somewhat like pilibcamera2)?\n>\n> - If it's just some helpers, what is the benefit of using the core module?\n>\n> - If it fully wraps the core, most likely it somewhat dummies down the\n> libcamera features. If so, there are always users for the core module.\n> Those users would most likely want to use simple helpers like blocking\n> wait or mmapped fb.\n>\n> - Perhaps a third module option would be something in between: a module\n> that \"pythonizes\" the classes, while still exposing everything. But are\n> the convenience features part of that, or yet another module on top?\n> Such a module also brings up the annoyance that you would access many\n> things via the higher level module (say, pylibcamera.Camera), but\n> probably many things would be just exposed from libcamera module if we\n> don't do a full wrap (say, camera.set_format(libcamera.formats.RGB123).\n>\n> So... I think it's clear that a fully wrapping module is obviously a new\n> module on top of the core bindings. But the simple helpers and possibly\n> the pythonization could be part of the core bindings, or on top.\n>\n> It's clear that features like mmapped fb class and blocking wait are\n> features that are needed by the users, so I think it's not a question of\n> should we have those, but where should they be.\n>\n> Also, not that even if the helpers would be part of the core bindings,\n> we could have internal split there: the bindings made in C++ would be\n> the core bindings, and in the same module we could have convenience\n> features written in Python (similar to the MappedFrameBuffer.py we have\n> now). However, while that sounds nice, I don't know if there's any real\n> logic to it. If something is easier/better written in the C++ bindings,\n> I don't see a point in forcing that feature to be written in Python instead.\n>\n> > Anyone else wants to chime in ?\n> >\n> >>>>>>>>>> Perhaps the camera.start() should go and discard any old Requests\n> >>>>>>>>>> related to that camera. For the exit issue I don't see any automatic\n> >>>>>>>>>> solution.\n> >>>>>>>>>\n> >>>>>>>>> At the end of camera.stop() we should validate and ensure that all\n> >>>>>>>>> Requests are released to the application. We should hold no internal\n> >>>>>>>>> requests when camera.stop() completes.\n> >>>>>>>>>\n> >>>>>>>>> I.e. ... if we have things to discard at camera.start() - that's a bug I\n> >>>>>>>>> believe.\n> >>>>>>>>>\n> >>>>>>>>> ahhh but here perhaps the issue is that the python code is the one that\n> >>>>>>>>> has to 'retrieve' those, while in C++ they are returned via a signal?\n> >>>>>>>>>\n> >>>>>>>>> Is there any harm in discarding the requests at the end of camera.stop()\n> >>>>>>>>> such that there is simply 'nothing left to process' after? Or does the\n> >>>>>>>>> python application have to end up owning the requests to correctly\n> >>>>>>>>> release them?\n> >>>>>>>\n> >>>>>>> Sounds like an idea to explore. What's the drawback of clearing in\n> >>>>>>> stop() ?\n> >>>>>>\n> >>>>>> Losing events that you expected to get, I think.\n> >>>>>>\n> >>>>>> I'm talking here about the event handling after adding the new event\n> >>>>>> handling, as I think it's more relevant than figuring out how to do\n> >>>>>> things with just the single event.\n> >>>>>>\n> >>>>>> We could dispatch the events (All events? Or just events related to\n> >>>>>> Requests for that camera?) automatically in stop(), but that would break\n> >>>>>> the backward compatibility.\n> >>>>>\n> >>>>> I don't recall if I've mentioned it in the review of another patch in\n> >>>>> the series, but I've been thinking about dispatching events at stop\n> >>>>> time, yes. This is how libcamera operates for buffer and request\n> >>>>> completion events, doing the same in Python would make the behaviour\n> >>>>> consistent. Backward compatibility isn't a concern, the Python bindings\n> >>>>> are experimental, we shouldn't let that block the design of a good API.\n> >>>>\n> >>>> With C++, it sounds fine as the signals are fired behind the scenes. In\n> >>>> the Python bindings there's a specific call to dispatch the events.\n> >>>> Implicitly dispatching the events elsewhere can be confusing.\n> >>>\n> >>> The explicit dispatching call is needed to work around a Python\n> >>> limitation related to threads. I'm fine with that, but I'd like to keep\n> >>> it as much as an internal detail as possible, thus minimizing its\n> >>> explicit usage from applications. I get your point about this being\n> >>> possibly confusing for users. I'd be interested in feedback from said\n> >>> users :-)\n> >>\n> >> Me too, but this is a rather difficult question to answer, so I don't\n> >> really expect to get help here =).\n> >\n> > Maybe David could shine some light here, as our mean user of the core\n> > bindings at this point ?\n> >\n> >> I do like the idea of somehow forcibly making the events handled at\n> >> camera.stop() time, though.\n> >>\n> >> Although there may be other events queued anyway. Say, camera_added.\n> >> Those will stay in the event queue, holding references to the relevant\n> >> objects, until the user calls dispatch_events().\n> >\n> > We could only dispatch buffer and request completion events in stop()\n> > for the camera being stopped, that would be fine with me. I'm not sure\n> > if we would gain much from such a selective dispatch though, but it\n> > would certainly mimic the C++ API.\n> >\n> >> Then again those don't cause similar problems as getting \"old\" Request\n> >> events after restarting a camera, so maybe they are fine.\n> >>\n> >> If the user wants a clean exit, he needs to either dispatch or discard\n> >> those events, otherwise the cameras and camera managers will be kept\n> >> alive at the app exit time.\n> >\n> > Maybe a cleanup function on the camera manager would do the job ? We're\n> > going back to explicit start/stop then though :-)\n>\n> The discard_events() is essentially a cleanup function.\n>\n> Perhaps we can do some clever weak-ref tricks there, though... I think\n> the events should not keep anything alive. Oh, but we depend on the\n> event keeping the Request alive, so that doesn't work.\n>\n>   Tomi","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 AB78BBD808\n\tfor <parsemail@patchwork.libcamera.org>;\n\tTue, 28 Jun 2022 08:16:38 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id DEF8A65637;\n\tTue, 28 Jun 2022 10:16:37 +0200 (CEST)","from mail-ej1-x62d.google.com (mail-ej1-x62d.google.com\n\t[IPv6:2a00:1450:4864:20::62d])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id CAA846559A\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 28 Jun 2022 10:16:35 +0200 (CEST)","by mail-ej1-x62d.google.com with SMTP id ge10so24102534ejb.7\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 28 Jun 2022 01:16:35 -0700 (PDT)"],"DKIM-Signature":["v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org;\n\ts=mail; t=1656404197;\n\tbh=EjhtjiBi8PbEUwoaa2B2QhE8puJ4RaK7z883PG2qBnU=;\n\th=References:In-Reply-To:Date:To:Subject:List-Id:List-Unsubscribe:\n\tList-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc:\n\tFrom;\n\tb=OZkaaCqqEVQKkbkJMWQw6yi4hjSokHOvAxiy1y7oHj4UIu7aQauyytw8SuCcNU06B\n\tkvRrEWVOjFNl0zLQ0ixGfnwFdKk/md3+uPyVoPZMzs/J0V7CBCp0JYBPOJkALcQQFS\n\tJAkFrtG8MXBV1WkV1HcQK+0BTo1KMeBgI2kl8+AmUrbcAIB7dMc89WguGVCHxsFP4P\n\tlxrujKwYOJBlVCXbJH1YhFeydY9zl62LdCjGcmJv2sYF6xvilOZynT3CbU3I1IXRYH\n\tbpMbXlqGHZgV3UrT5vKgqSbMopZAhowx2RZCuzl7nVmSD4mKqryuF+js7qbkCo8ENR\n\td8BSInrI+NVTg==","v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=raspberrypi.com; s=google;\n\th=mime-version:references:in-reply-to:from:date:message-id:subject:to\n\t:cc; bh=aghnDGST8S7vwOTTOR5nA0iyR6BrEGvZIjPlxN0s0+Y=;\n\tb=K8YzZ+FLuDuWTwZ1GnBVVGodlgEYhEWwDubE91vTqMyJQ0Q63Xwz5uR0VCl4v6JpRZ\n\tNUYS57ebvlehAVR0wJ552bm/xUjSGDo/zc5d8zAuIRW805ejGJ/J/Z8Pq1lZ4bTtosyy\n\tr+EGfEeOcwZQkfZw5RCEc716Yd/a5cjgirVXStZ/DE1q27HZtf3X/VST1vP7uoOfgnks\n\t1NuJbioq3PM5oQDPOysx73CMNi9VAvRjpyvfJG/OgN4GZJAy2jp5CSAWwGo+MDWlD36L\n\tbYSdSVK7tZVEUTJcr47vY5zGEoIcT04eHEaEZv+uD4LK2vU+RUNevNDhKsl0Jrw2W1wR\n\to6CA=="],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (2048-bit key; \n\tunprotected) header.d=raspberrypi.com\n\theader.i=@raspberrypi.com\n\theader.b=\"K8YzZ+FL\"; dkim-atps=neutral","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20210112;\n\th=x-gm-message-state:mime-version:references:in-reply-to:from:date\n\t:message-id:subject:to:cc;\n\tbh=aghnDGST8S7vwOTTOR5nA0iyR6BrEGvZIjPlxN0s0+Y=;\n\tb=LX50B4fLm5cVXsd+BgjcbNS4Pn9WHA2yyaHk/VCzIsxrfO+mUCWx5TXcZPsQWlMCqj\n\txSPrAUsu2gThZ7NryrGrZfFHDsU8MknJBeN9k83W4GfALh8K0p4VavgL943ZW+noYULL\n\tBVIgIgh2j8JNHTs/jTF6Trr/nDSzjkE6c2y+gJnDfCWSYvhHVvhdDDwyKWs39T+aBtB9\n\tCGQK7tBm5SQMQt4eNg0xJHvesChdoAW3+Go2lAwyb6CjLXNjjDXJTwKrW/RhT7UdQh6A\n\tbebsCZ6FO8MQs8JXOt0MNmz2T/gCGIAE0bFruApP35Xdig6fBRKdXK8ok9XXIF0TzutO\n\tw4Xg==","X-Gm-Message-State":"AJIora8YvJUhGg3lCeFRqVTZZinD3R+pZdlw7y1seorCLI7AmDcBSBoq\n\tALfEKD3kFu2jlqcIjmTlnnnKh08oeeogpPOJubYaRC/XVvlmQA==","X-Google-Smtp-Source":"AGRyM1t6I4lIx28GZyZIAKAop0XAIRTvF6vSiikUGN8FSh2aEZzaZdPGDoEW6n4iq8p5e5Y1sTUJFZvh481Gb3gbJDU=","X-Received":"by 2002:a17:906:a383:b0:6f5:132c:1a14 with SMTP id\n\tk3-20020a170906a38300b006f5132c1a14mr17315702ejz.21.1656404195186;\n\tTue, 28 Jun 2022 01:16:35 -0700 (PDT)","MIME-Version":"1.0","References":"<20220623144736.78537-1-tomi.valkeinen@ideasonboard.com>\n\t<20220623144736.78537-6-tomi.valkeinen@ideasonboard.com>\n\t<165606562844.1149771.15547198942218026607@Monstersaurus>\n\t<CAHW6GYJ16vLOrELLE8YCayRQ-T8Sg+0SFxP8g0LXu99478a9zw@mail.gmail.com>\n\t<YrXBxMP4cOdEUI/Y@pendragon.ideasonboard.com>\n\t<ad43e5f9-e683-01d9-6c24-82cfd5ab06ce@ideasonboard.com>\n\t<YrmDkpIcGFLcrEY0@pendragon.ideasonboard.com>\n\t<4348bd1d-15c4-46cb-0e78-49562d9ef5d1@ideasonboard.com>\n\t<YrmhorraByJ0t6fP@pendragon.ideasonboard.com>\n\t<21dd961e-feaa-6e10-b8e5-b15d8738d32b@ideasonboard.com>\n\t<YroWTianZr8FDSsL@pendragon.ideasonboard.com>\n\t<4e58f214-08ff-65ff-2449-911d81d99ac2@ideasonboard.com>","In-Reply-To":"<4e58f214-08ff-65ff-2449-911d81d99ac2@ideasonboard.com>","Date":"Tue, 28 Jun 2022 09:16:24 +0100","Message-ID":"<CAHW6GYLo_4ERGLHuSmmO9_vpH6TCC1bc5_TyC7aMJn41g=2Dyg@mail.gmail.com>","To":"Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>","Content-Type":"text/plain; charset=\"UTF-8\"","Subject":"Re: [libcamera-devel] [RFC v1 5/7] py: Add 'nonblocking' argument\n\tto get_ready_requests()","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":"David Plowman via libcamera-devel <libcamera-devel@lists.libcamera.org>","Reply-To":"David Plowman <david.plowman@raspberrypi.com>","Cc":"libcamera devel <libcamera-devel@lists.libcamera.org>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":23654,"web_url":"https://patchwork.libcamera.org/comment/23654/","msgid":"<0380ce87-ac2c-dbe9-44ea-55f085769e26@ideasonboard.com>","date":"2022-06-29T07:11:56","subject":"Re: [libcamera-devel] [RFC v1 5/7] py: Add 'nonblocking' argument\n\tto get_ready_requests()","submitter":{"id":109,"url":"https://patchwork.libcamera.org/api/people/109/","name":"Tomi Valkeinen","email":"tomi.valkeinen@ideasonboard.com"},"content":"On 28/06/2022 11:16, David Plowman wrote:\n> Hi everyone\n> \n> Sorry for not taking part in this discussion rather more, and thanks\n> to those who have! I think I was asked further back if I had an\n> opinion, so let me try and explain how I see things.\n> \n> Actually I don't have any particularly strong opinions, other than\n> that I want things to work and to be easy to use. And if they stopped\n> changing, that would be nice too!!\n\nValid requests, but I think I can promise you only the first one =). The \neasy-to-use would be nice, but as we've discussed, perhaps the core \nbindings should be, well, core, which doesn't always equal easy to use.\n\nAnd the third one... I'll try to keep backward compatibility when \npossible (at least for a period of time), but that's just not always the \ncase.\n\n> I was actually OK with the previous version where get_ready_requests\n> was non-blocking, it's only the more recent version that causes me\n> some trouble because I can't simply flush out any lurking requests\n> after stopping the camera - because there might not be any and I will\n> simply lock up the system.\n\nThe v2 series goes back to that, although the code behind is a bit \ndifferent.\n\n  Tomi","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 C6342BD808\n\tfor <parsemail@patchwork.libcamera.org>;\n\tWed, 29 Jun 2022 07:12:02 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 3B61D65631;\n\tWed, 29 Jun 2022 09:12:02 +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 9237D60552\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 29 Jun 2022 09:12:00 +0200 (CEST)","from [192.168.1.111] (91-158-154-79.elisa-laajakaista.fi\n\t[91.158.154.79])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id AE2164A8;\n\tWed, 29 Jun 2022 09:11:59 +0200 (CEST)"],"DKIM-Signature":["v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org;\n\ts=mail; t=1656486722;\n\tbh=Tphgo3BfiZEwkPfXTEXgPHHxDyr3wTTMtVZwjhht/U4=;\n\th=Date:To:References:In-Reply-To:Subject:List-Id:List-Unsubscribe:\n\tList-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc:\n\tFrom;\n\tb=1GH4LhKutAuzHnbdAkVV4TCsHPRJGKv5EvmEZbcCPdGwxvnUeJYseoKajVidoknUq\n\t9Azh6NMrS4+ltGhf3/I5COvJruB0F7Uoz5SHQgELwBdOZ+SBTrJguNsl0h1AzJeFmT\n\tZabfLkS1qT3NEbfuSZALBmccZr1ow8Gj804TCOog/kEn7vkk2SbkEyayR1bEwPxG6e\n\tCI05aglfKnxfMUJNrC/FdFHrcZGoq3gtdsyb5V7xHOuSV0WtmfNYsd/8s2LZtmjLEh\n\tJvvqeVcS6KLZIS4qdmdI6x7mrObQh3PoXtRO471O9nrwQHr49RPCIHu+GIpbl5Vb1y\n\tQNltj+s0an+Og==","v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1656486720;\n\tbh=Tphgo3BfiZEwkPfXTEXgPHHxDyr3wTTMtVZwjhht/U4=;\n\th=Date:Subject:To:Cc:References:From:In-Reply-To:From;\n\tb=CAHQtX8jXtPQ4co8MYnMxrw1CvJe8kX6oV0dgiVza9Ijj8WrnpIs6wM8eUWPOH2oM\n\tT80xRtfTHhwGbxlw8gkx+5c6fqqjwGBh2cyiAfvMBA0pITkgguZdJfBqw3WwYKv5ev\n\tDtNwTbGqZ6/PB5x/HsLnLOIYfWc3xZn2+eGjqHp0="],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key; \n\tunprotected) header.d=ideasonboard.com\n\theader.i=@ideasonboard.com\n\theader.b=\"CAHQtX8j\"; dkim-atps=neutral","Message-ID":"<0380ce87-ac2c-dbe9-44ea-55f085769e26@ideasonboard.com>","Date":"Wed, 29 Jun 2022 10:11:56 +0300","MIME-Version":"1.0","User-Agent":"Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101\n\tThunderbird/91.9.1","Content-Language":"en-US","To":"David Plowman <david.plowman@raspberrypi.com>","References":"<20220623144736.78537-1-tomi.valkeinen@ideasonboard.com>\n\t<20220623144736.78537-6-tomi.valkeinen@ideasonboard.com>\n\t<165606562844.1149771.15547198942218026607@Monstersaurus>\n\t<CAHW6GYJ16vLOrELLE8YCayRQ-T8Sg+0SFxP8g0LXu99478a9zw@mail.gmail.com>\n\t<YrXBxMP4cOdEUI/Y@pendragon.ideasonboard.com>\n\t<ad43e5f9-e683-01d9-6c24-82cfd5ab06ce@ideasonboard.com>\n\t<YrmDkpIcGFLcrEY0@pendragon.ideasonboard.com>\n\t<4348bd1d-15c4-46cb-0e78-49562d9ef5d1@ideasonboard.com>\n\t<YrmhorraByJ0t6fP@pendragon.ideasonboard.com>\n\t<21dd961e-feaa-6e10-b8e5-b15d8738d32b@ideasonboard.com>\n\t<YroWTianZr8FDSsL@pendragon.ideasonboard.com>\n\t<4e58f214-08ff-65ff-2449-911d81d99ac2@ideasonboard.com>\n\t<CAHW6GYLo_4ERGLHuSmmO9_vpH6TCC1bc5_TyC7aMJn41g=2Dyg@mail.gmail.com>","In-Reply-To":"<CAHW6GYLo_4ERGLHuSmmO9_vpH6TCC1bc5_TyC7aMJn41g=2Dyg@mail.gmail.com>","Content-Type":"text/plain; charset=UTF-8; format=flowed","Content-Transfer-Encoding":"7bit","Subject":"Re: [libcamera-devel] [RFC v1 5/7] py: Add 'nonblocking' argument\n\tto get_ready_requests()","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>","Cc":"libcamera devel <libcamera-devel@lists.libcamera.org>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":23669,"web_url":"https://patchwork.libcamera.org/comment/23669/","msgid":"<294b598a-a82d-e65a-1020-b282fb91f93e@ideasonboard.com>","date":"2022-06-30T06:13:15","subject":"Re: [libcamera-devel] [RFC v1 5/7] py: Add 'nonblocking' argument\n\tto get_ready_requests()","submitter":{"id":109,"url":"https://patchwork.libcamera.org/api/people/109/","name":"Tomi Valkeinen","email":"tomi.valkeinen@ideasonboard.com"},"content":"On 28/06/2022 11:16, David Plowman wrote:\n> Hi everyone\n> \n> Sorry for not taking part in this discussion rather more, and thanks\n> to those who have! I think I was asked further back if I had an\n> opinion, so let me try and explain how I see things.\n> \n> Actually I don't have any particularly strong opinions, other than\n> that I want things to work and to be easy to use. And if they stopped\n> changing, that would be nice too!!\n> \n> I was actually OK with the previous version where get_ready_requests\n> was non-blocking, it's only the more recent version that causes me\n> some trouble because I can't simply flush out any lurking requests\n> after stopping the camera - because there might not be any and I will\n> simply lock up the system.\n\nBtw, while we're discussing and fixing this issue, you can also do a \ncheck in Python:\n\n         import selectors\n         sel = selectors.DefaultSelector()\n         sel.register(cm.event_fd, selectors.EVENT_READ)\n         events = sel.select(0)\n         if events:\n             print(\"get_ready_requests doesn't block\")\n         else:\n             print(\"get_ready_requests may block\")\n\nThis could be used to avoid calling get_ready_requests when it may block.\n\n  Tomi","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 DE9C8BE173\n\tfor <parsemail@patchwork.libcamera.org>;\n\tThu, 30 Jun 2022 06:13:21 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 0A3126564E;\n\tThu, 30 Jun 2022 08:13:21 +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 EC12360403\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 30 Jun 2022 08:13:18 +0200 (CEST)","from [192.168.1.111] (91-158-154-79.elisa-laajakaista.fi\n\t[91.158.154.79])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id C9E6B45F;\n\tThu, 30 Jun 2022 08:13:17 +0200 (CEST)"],"DKIM-Signature":["v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org;\n\ts=mail; t=1656569601;\n\tbh=FRbYV8K8cqiJWmyJsfmlRMeRSdTJza8b3oT8xUmH0q4=;\n\th=Date:To:References:In-Reply-To:Subject:List-Id:List-Unsubscribe:\n\tList-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc:\n\tFrom;\n\tb=UBP0UhFk8Gt4uNW3Q4+avKuJcSZimoEwdWmLgftVp8s6dLmyI0PpuS4uqY+44wofj\n\trRkYx5jdHPNWr5+x5BOFUYjNXnFNn59G2yy8czTYZXI5CTpDGTBkyfyCButfYg7r+2\n\tRh+MTWrdaEvfKfSPweS3uFBU4Rqw2t15iCmUDWlrnzIv2rUb6kaVRkJPHK+6FTEPlZ\n\taMaXiqUhFRJO+76cDGFyth6P6LDBjdfubt8gx7lR8+fMr8ReHNgQHWVfz2ezAXyVPa\n\tgnpva6TVKyA6T6tVD2MgyqrZSl8ImqkQEMLTPYwxRcz+EtnqowToYEMHL51LrAy5Zy\n\tFmQzZFZ/K8u1w==","v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1656569598;\n\tbh=FRbYV8K8cqiJWmyJsfmlRMeRSdTJza8b3oT8xUmH0q4=;\n\th=Date:Subject:To:Cc:References:From:In-Reply-To:From;\n\tb=aZ3fzeK51y/VWZIjVXqRVM6OyMji/UIzlkg9Tg6ScB7acEvFaDS0iZz/DQJ5naCZg\n\tkw6REWNt1+74sVinqIpe7pPBPGdi91lrDMk1e89Sk2ndh9vtdFm0swl/EsbR3btdT6\n\tNyTCtGAzSQFuazmhODjpHwtZTUm7Ird1hUdTS4Eg="],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key; \n\tunprotected) header.d=ideasonboard.com\n\theader.i=@ideasonboard.com\n\theader.b=\"aZ3fzeK5\"; dkim-atps=neutral","Message-ID":"<294b598a-a82d-e65a-1020-b282fb91f93e@ideasonboard.com>","Date":"Thu, 30 Jun 2022 09:13:15 +0300","MIME-Version":"1.0","User-Agent":"Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101\n\tThunderbird/91.9.1","Content-Language":"en-US","To":"David Plowman <david.plowman@raspberrypi.com>","References":"<20220623144736.78537-1-tomi.valkeinen@ideasonboard.com>\n\t<20220623144736.78537-6-tomi.valkeinen@ideasonboard.com>\n\t<165606562844.1149771.15547198942218026607@Monstersaurus>\n\t<CAHW6GYJ16vLOrELLE8YCayRQ-T8Sg+0SFxP8g0LXu99478a9zw@mail.gmail.com>\n\t<YrXBxMP4cOdEUI/Y@pendragon.ideasonboard.com>\n\t<ad43e5f9-e683-01d9-6c24-82cfd5ab06ce@ideasonboard.com>\n\t<YrmDkpIcGFLcrEY0@pendragon.ideasonboard.com>\n\t<4348bd1d-15c4-46cb-0e78-49562d9ef5d1@ideasonboard.com>\n\t<YrmhorraByJ0t6fP@pendragon.ideasonboard.com>\n\t<21dd961e-feaa-6e10-b8e5-b15d8738d32b@ideasonboard.com>\n\t<YroWTianZr8FDSsL@pendragon.ideasonboard.com>\n\t<4e58f214-08ff-65ff-2449-911d81d99ac2@ideasonboard.com>\n\t<CAHW6GYLo_4ERGLHuSmmO9_vpH6TCC1bc5_TyC7aMJn41g=2Dyg@mail.gmail.com>","In-Reply-To":"<CAHW6GYLo_4ERGLHuSmmO9_vpH6TCC1bc5_TyC7aMJn41g=2Dyg@mail.gmail.com>","Content-Type":"text/plain; charset=UTF-8; format=flowed","Content-Transfer-Encoding":"7bit","Subject":"Re: [libcamera-devel] [RFC v1 5/7] py: Add 'nonblocking' argument\n\tto get_ready_requests()","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>","Cc":"libcamera devel <libcamera-devel@lists.libcamera.org>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":23671,"web_url":"https://patchwork.libcamera.org/comment/23671/","msgid":"<CAHW6GYK3yRHwPq28rccJaH-ZRjEHLY0Nm2Si9y=nO3RsF4Gxkw@mail.gmail.com>","date":"2022-06-30T07:57:49","subject":"Re: [libcamera-devel] [RFC v1 5/7] py: Add 'nonblocking' argument\n\tto get_ready_requests()","submitter":{"id":42,"url":"https://patchwork.libcamera.org/api/people/42/","name":"David Plowman","email":"david.plowman@raspberrypi.com"},"content":"Ah, I was just thinking of finding out how to do that, I'll give it a\ntry. Thanks!\n\nDavid\n\nOn Thu, 30 Jun 2022 at 07:13, Tomi Valkeinen\n<tomi.valkeinen@ideasonboard.com> wrote:\n>\n> On 28/06/2022 11:16, David Plowman wrote:\n> > Hi everyone\n> >\n> > Sorry for not taking part in this discussion rather more, and thanks\n> > to those who have! I think I was asked further back if I had an\n> > opinion, so let me try and explain how I see things.\n> >\n> > Actually I don't have any particularly strong opinions, other than\n> > that I want things to work and to be easy to use. And if they stopped\n> > changing, that would be nice too!!\n> >\n> > I was actually OK with the previous version where get_ready_requests\n> > was non-blocking, it's only the more recent version that causes me\n> > some trouble because I can't simply flush out any lurking requests\n> > after stopping the camera - because there might not be any and I will\n> > simply lock up the system.\n>\n> Btw, while we're discussing and fixing this issue, you can also do a\n> check in Python:\n>\n>          import selectors\n>          sel = selectors.DefaultSelector()\n>          sel.register(cm.event_fd, selectors.EVENT_READ)\n>          events = sel.select(0)\n>          if events:\n>              print(\"get_ready_requests doesn't block\")\n>          else:\n>              print(\"get_ready_requests may block\")\n>\n> This could be used to avoid calling get_ready_requests when it may block.\n>\n>   Tomi","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 149DCBD808\n\tfor <parsemail@patchwork.libcamera.org>;\n\tThu, 30 Jun 2022 07:58:03 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 566A66564E;\n\tThu, 30 Jun 2022 09:58:02 +0200 (CEST)","from mail-ej1-x62d.google.com (mail-ej1-x62d.google.com\n\t[IPv6:2a00:1450:4864:20::62d])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id EF3C56054C\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 30 Jun 2022 09:58:00 +0200 (CEST)","by mail-ej1-x62d.google.com with SMTP id q6so37273534eji.13\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 30 Jun 2022 00:58:00 -0700 (PDT)"],"DKIM-Signature":["v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org;\n\ts=mail; t=1656575882;\n\tbh=QPFEtt/ZZ23h0nI1IjmvIAqYD25rDNQjSoONNxVBEME=;\n\th=References:In-Reply-To:Date:To:Subject:List-Id:List-Unsubscribe:\n\tList-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc:\n\tFrom;\n\tb=zooIva9uP6O3sy8DlsekdwhWeScwakilgX+iTNMaCiBmgbQIU3J/Zf9zaJDXbv++6\n\tOV5Z7pbbFFesduiyUt6TbLOtpNBToFXN3l2lCneSlV7YTf7sdjpqNV1jcBAGmF9/cT\n\tZzy0A2VtnbLsvwhvJH6uoV0gbxhurJ1SUm2XXMxisP0Cv0Fh7ycD1Xwy9oUirTNXlb\n\txkAkIPGt2tcl67PSUGUtpeWULH3tGBZShHKMRIVLp4jkV1J+C8CNcoCn4+rYaeugJP\n\tPxyOitF57XhpDthteiZtrVGiaCgtZYNY/sB4SPY2/EkP8p/hoNgVPDUmwSZENp4RRr\n\tg9kC9o71ppF3w==","v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=raspberrypi.com; s=google;\n\th=mime-version:references:in-reply-to:from:date:message-id:subject:to\n\t:cc; bh=9AXQ9A7wPeUwBEFNbW1437KM95Y70fQBrxendZwdhjM=;\n\tb=GLOftO/1LLOedXhhvnsKV91CNHccAV20DRYvCu5VM2TjPnLGy2AjeETG2Cl3KRPco/\n\tq4HeiODwqMHFK2LahYIJuBCh3EHn031voJzonpQxvHTSGj4ck8kbD8O5KUWS3g1IzeZi\n\tGd172bG7+ufyY/RkoG7hmHoL0wVYJqHvi9T6ha0flZhiZxBJVDGVk0Q8v3SeriSIyIY7\n\tYlR/G5wb+SUZ1GE/98pR/X2TQHmjYyDvWvr+PaU0WwEmRP5Wl6OzXM/GjQ6+r0ZzTRCW\n\t8iV2yiAp/Ik988SJQF8Oo2XrQsTa7EE9dWPQ7NPiarAJlvCo81u5WsLhI2MShHfg/5Rr\n\t6hBQ=="],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (2048-bit key; \n\tunprotected) header.d=raspberrypi.com\n\theader.i=@raspberrypi.com\n\theader.b=\"GLOftO/1\"; dkim-atps=neutral","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20210112;\n\th=x-gm-message-state:mime-version:references:in-reply-to:from:date\n\t:message-id:subject:to:cc;\n\tbh=9AXQ9A7wPeUwBEFNbW1437KM95Y70fQBrxendZwdhjM=;\n\tb=oyAhzt0uP/hvn7guW+e4oNWPQqqqZect9EH+0p386btbdr18hqnv3AdF/73dJIH1zP\n\t2vIMDsjEHRGVmIUCvjeFnrV/mCFqbOYBfPSA+ujL6sfSfv1RM23Usenj6qY7ZH3+0MXB\n\tPMVa/tna5gVaiLs+BOmV9M2VKcH1/dKwGR4osaZxslsm7Cv5woJD+IL9XGqEKFpC/NNP\n\tLCZToVGfLklTOlePxuVMhbCc0/koyhKurv1QHoo5dA51ezwnFF8RbhPKajLP4A2OkdYg\n\taPPt9VFom3bieUdfSPDEmWQBMlO24d8jOjw+9cQ07ObwkKiWc0eIDJOSvau7UEdRKLPH\n\tPwdg==","X-Gm-Message-State":"AJIora/OMP9Va32Bhjt4IgMJteD/qStExq70ZKgRWj81vtvMHylsmaVb\n\tTToQRkE6MbKS3Suz50msMoAxXkm0eNyS0by1pnjQMQ==","X-Google-Smtp-Source":"AGRyM1umVm/xKg8SvJRj8iu70Uuz+b+yblXMnNMLyTcRWGvH/fzX1+Vz4ixkGt+6jH2RaCJyx5ha5aZz0o4fC3Y49eI=","X-Received":"by 2002:a17:906:9bd1:b0:72a:5b6f:a3c8 with SMTP id\n\tde17-20020a1709069bd100b0072a5b6fa3c8mr2433196ejc.21.1656575880500;\n\tThu, 30 Jun 2022 00:58:00 -0700 (PDT)","MIME-Version":"1.0","References":"<20220623144736.78537-1-tomi.valkeinen@ideasonboard.com>\n\t<20220623144736.78537-6-tomi.valkeinen@ideasonboard.com>\n\t<165606562844.1149771.15547198942218026607@Monstersaurus>\n\t<CAHW6GYJ16vLOrELLE8YCayRQ-T8Sg+0SFxP8g0LXu99478a9zw@mail.gmail.com>\n\t<YrXBxMP4cOdEUI/Y@pendragon.ideasonboard.com>\n\t<ad43e5f9-e683-01d9-6c24-82cfd5ab06ce@ideasonboard.com>\n\t<YrmDkpIcGFLcrEY0@pendragon.ideasonboard.com>\n\t<4348bd1d-15c4-46cb-0e78-49562d9ef5d1@ideasonboard.com>\n\t<YrmhorraByJ0t6fP@pendragon.ideasonboard.com>\n\t<21dd961e-feaa-6e10-b8e5-b15d8738d32b@ideasonboard.com>\n\t<YroWTianZr8FDSsL@pendragon.ideasonboard.com>\n\t<4e58f214-08ff-65ff-2449-911d81d99ac2@ideasonboard.com>\n\t<CAHW6GYLo_4ERGLHuSmmO9_vpH6TCC1bc5_TyC7aMJn41g=2Dyg@mail.gmail.com>\n\t<294b598a-a82d-e65a-1020-b282fb91f93e@ideasonboard.com>","In-Reply-To":"<294b598a-a82d-e65a-1020-b282fb91f93e@ideasonboard.com>","Date":"Thu, 30 Jun 2022 08:57:49 +0100","Message-ID":"<CAHW6GYK3yRHwPq28rccJaH-ZRjEHLY0Nm2Si9y=nO3RsF4Gxkw@mail.gmail.com>","To":"Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>","Content-Type":"text/plain; charset=\"UTF-8\"","Subject":"Re: [libcamera-devel] [RFC v1 5/7] py: Add 'nonblocking' argument\n\tto get_ready_requests()","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":"David Plowman via libcamera-devel <libcamera-devel@lists.libcamera.org>","Reply-To":"David Plowman <david.plowman@raspberrypi.com>","Cc":"libcamera devel <libcamera-devel@lists.libcamera.org>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}}]