[{"id":18449,"web_url":"https://patchwork.libcamera.org/comment/18449/","msgid":"<YQXT1bzbzR78Omoa@oden.dyn.berto.se>","date":"2021-07-31T22:51:01","subject":"Re: [libcamera-devel] [PATCH v2 1/8] cam: event_loop: Add support\n\tfor file descriptor events","submitter":{"id":5,"url":"https://patchwork.libcamera.org/api/people/5/","name":"Niklas Söderlund","email":"niklas.soderlund@ragnatech.se"},"content":"Hi Laurent,\n\nThanks for your work.\n\nOn 2021-07-30 04:02:59 +0300, Laurent Pinchart wrote:\n> Extend the EventLoop class to support watching file descriptors for\n> read and write events.\n> \n> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n\nReviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>\n\n> ---\n>  src/cam/event_loop.cpp | 44 ++++++++++++++++++++++++++++++++++++++++++\n>  src/cam/event_loop.h   | 20 +++++++++++++++++++\n>  2 files changed, 64 insertions(+)\n> \n> diff --git a/src/cam/event_loop.cpp b/src/cam/event_loop.cpp\n> index 6a4c47f287d0..e25784c083cf 100644\n> --- a/src/cam/event_loop.cpp\n> +++ b/src/cam/event_loop.cpp\n> @@ -10,6 +10,7 @@\n>  #include <assert.h>\n>  #include <event2/event.h>\n>  #include <event2/thread.h>\n> +#include <iostream>\n>  \n>  EventLoop *EventLoop::instance_ = nullptr;\n>  \n> @@ -26,6 +27,7 @@ EventLoop::~EventLoop()\n>  {\n>  \tinstance_ = nullptr;\n>  \n> +\tevents_.clear();\n>  \tevent_base_free(base_);\n>  \tlibevent_global_shutdown();\n>  }\n> @@ -58,6 +60,30 @@ void EventLoop::callLater(const std::function<void()> &func)\n>  \tevent_base_once(base_, -1, EV_TIMEOUT, dispatchCallback, this, nullptr);\n>  }\n>  \n> +void EventLoop::addEvent(int fd, EventType type,\n> +\t\t\t const std::function<void()> &callback)\n> +{\n> +\tstd::unique_ptr<Event> event = std::make_unique<Event>(callback);\n> +\tshort events = (type & Read ? EV_READ : 0)\n> +\t\t     | (type & Write ? EV_WRITE : 0)\n> +\t\t     | EV_PERSIST;\n> +\n> +\tevent->event_ = event_new(base_, fd, events, &EventLoop::Event::dispatch,\n> +\t\t\t\t  event.get());\n> +\tif (!event->event_) {\n> +\t\tstd::cerr << \"Failed to create event for fd \" << fd << std::endl;\n> +\t\treturn;\n> +\t}\n> +\n> +\tint ret = event_add(event->event_, nullptr);\n> +\tif (ret < 0) {\n> +\t\tstd::cerr << \"Failed to add event for fd \" << fd << std::endl;\n> +\t\treturn;\n> +\t}\n> +\n> +\tevents_.push_back(std::move(event));\n> +}\n> +\n>  void EventLoop::dispatchCallback([[maybe_unused]] evutil_socket_t fd,\n>  \t\t\t\t [[maybe_unused]] short flags, void *param)\n>  {\n> @@ -80,3 +106,21 @@ void EventLoop::dispatchCall()\n>  \n>  \tcall();\n>  }\n> +\n> +EventLoop::Event::Event(const std::function<void()> &callback)\n> +\t: callback_(callback), event_(nullptr)\n> +{\n> +}\n> +\n> +EventLoop::Event::~Event()\n> +{\n> +\tevent_del(event_);\n> +\tevent_free(event_);\n> +}\n> +\n> +void EventLoop::Event::dispatch([[maybe_unused]] int fd,\n> +\t\t\t\t[[maybe_unused]] short events, void *arg)\n> +{\n> +\tEvent *event = static_cast<Event *>(arg);\n> +\tevent->callback_();\n> +}\n> diff --git a/src/cam/event_loop.h b/src/cam/event_loop.h\n> index ba3ba3a4a675..57bb6fb34aa7 100644\n> --- a/src/cam/event_loop.h\n> +++ b/src/cam/event_loop.h\n> @@ -8,6 +8,7 @@\n>  #define __CAM_EVENT_LOOP_H__\n>  \n>  #include <functional>\n> +#include <memory>\n>  #include <list>\n>  #include <mutex>\n>  \n> @@ -18,6 +19,11 @@ struct event_base;\n>  class EventLoop\n>  {\n>  public:\n> +\tenum EventType {\n> +\t\tRead = 1,\n> +\t\tWrite = 2,\n> +\t};\n> +\n>  \tEventLoop();\n>  \t~EventLoop();\n>  \n> @@ -28,13 +34,27 @@ public:\n>  \n>  \tvoid callLater(const std::function<void()> &func);\n>  \n> +\tvoid addEvent(int fd, EventType type,\n> +\t\t      const std::function<void()> &handler);\n> +\n>  private:\n> +\tstruct Event {\n> +\t\tEvent(const std::function<void()> &callback);\n> +\t\t~Event();\n> +\n> +\t\tstatic void dispatch(int fd, short events, void *arg);\n> +\n> +\t\tstd::function<void()> callback_;\n> +\t\tstruct event *event_;\n> +\t};\n> +\n>  \tstatic EventLoop *instance_;\n>  \n>  \tstruct event_base *base_;\n>  \tint exitCode_;\n>  \n>  \tstd::list<std::function<void()>> calls_;\n> +\tstd::list<std::unique_ptr<Event>> events_;\n>  \tstd::mutex lock_;\n>  \n>  \tstatic void dispatchCallback(evutil_socket_t fd, short flags,\n> -- \n> Regards,\n> \n> Laurent Pinchart\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 B1768C322E\n\tfor <parsemail@patchwork.libcamera.org>;\n\tSat, 31 Jul 2021 22:51:07 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 13F49687C3;\n\tSun,  1 Aug 2021 00:51:07 +0200 (CEST)","from mail-lf1-x136.google.com (mail-lf1-x136.google.com\n\t[IPv6:2a00:1450:4864:20::136])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id E3CE5687BE\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tSun,  1 Aug 2021 00:51:03 +0200 (CEST)","by mail-lf1-x136.google.com with SMTP id m13so25994070lfg.13\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tSat, 31 Jul 2021 15:51:03 -0700 (PDT)","from localhost (h-46-59-88-219.A463.priv.bahnhof.se.\n\t[46.59.88.219]) by smtp.gmail.com with ESMTPSA id\n\ta8sm505402lfi.51.2021.07.31.15.51.02\n\t(version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n\tSat, 31 Jul 2021 15:51:02 -0700 (PDT)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (2048-bit key;\n\tunprotected) header.d=ragnatech-se.20150623.gappssmtp.com\n\theader.i=@ragnatech-se.20150623.gappssmtp.com\n\theader.b=\"bfiOQXEr\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=ragnatech-se.20150623.gappssmtp.com; s=20150623;\n\th=date:from:to:cc:subject:message-id:references:mime-version\n\t:content-disposition:content-transfer-encoding:in-reply-to;\n\tbh=O4hnjieHm7Rj2r8qQFaHWtYWRHonIwgepW6mUIBi2Zs=;\n\tb=bfiOQXEr3Qc+PwI82pO4q3KmkGM75xJrUjMTM/AGjQI/I+am7GeQcfa5NXLvJnbBaz\n\tyFJHHMznoD4W1l3hjn9mDChkXflszXmiQpNj5N3nXEGq+gHZigYoxw3xhWbEt2AtKA38\n\t5NnLXHSCw76gpyakxJLjKP0velwflO/CBR6y5K/2CkHzQkHwJnPxVS/sYMceN2+oj43r\n\t2ouxm5s7TKfTBA79Ra0aMXzi2HdBJVZSw52LjVJwvS09gMrH7H/ZFMNntybTsXQrrOXG\n\tj9Vr/sg8WpviBmityA1rflvyr6AQtHjqMOsDntNzs3k1PHwwe/NJjAcvozHXDjWeFdIr\n\tqFkA==","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20161025;\n\th=x-gm-message-state:date:from:to:cc:subject:message-id:references\n\t:mime-version:content-disposition:content-transfer-encoding\n\t:in-reply-to;\n\tbh=O4hnjieHm7Rj2r8qQFaHWtYWRHonIwgepW6mUIBi2Zs=;\n\tb=VVK97yh6fSU5iulB0hjrDLjUsvJl+P7aBJ1//Co6OQvDbEVv6DpxFpLOjxV08qG56F\n\thRCM8lh6S62QLUX9PIkraATD8IAKnoyS6f4kbq/+JwwQ/3gaouconzVWbAwUrCa6z/Iw\n\tKmsCbcMGNQK705ebzVUu/oGi0toxidGqWW3LE4K4wMd5qkBn+U6+XUre2kBCURcGjs4g\n\t445+rvbBphcRfCZ92b0gVCg3kvQqtHrEgbjprUFzCd39+vrxqiPWhFPH6o2jn5IEIKy/\n\t7ZNPwXzXAk2lPgdw54nOBAccxGAU6PfC6+WxqzSo23NNynBO8iis4Sbdf/vC29mpSD/A\n\tMEKA==","X-Gm-Message-State":"AOAM5308XQDsfGicymQvWGiG6mpMiaF0PRAOb3bCinZiJorMgCG4XY28\n\tJn3lK/pGpt5huTuf/iBvYWmT3GbgsSt3hA==","X-Google-Smtp-Source":"ABdhPJxED5YY2WqIDMpm+IEJbYo6LHdp8sSvjWRB+AL5c+9U+UeaFtj+IurvvqgM6Oqs/cLSvS6koQ==","X-Received":"by 2002:ac2:55a7:: with SMTP id y7mr7126672lfg.179.1627771863064;\n\tSat, 31 Jul 2021 15:51:03 -0700 (PDT)","Date":"Sun, 1 Aug 2021 00:51:01 +0200","From":"Niklas =?iso-8859-1?q?S=F6derlund?= <niklas.soderlund@ragnatech.se>","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","Message-ID":"<YQXT1bzbzR78Omoa@oden.dyn.berto.se>","References":"<20210730010306.19956-1-laurent.pinchart@ideasonboard.com>\n\t<20210730010306.19956-2-laurent.pinchart@ideasonboard.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=iso-8859-1","Content-Disposition":"inline","Content-Transfer-Encoding":"8bit","In-Reply-To":"<20210730010306.19956-2-laurent.pinchart@ideasonboard.com>","Subject":"Re: [libcamera-devel] [PATCH v2 1/8] cam: event_loop: Add support\n\tfor file descriptor events","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>","Cc":"libcamera-devel@lists.libcamera.org","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":18502,"web_url":"https://patchwork.libcamera.org/comment/18502/","msgid":"<20210803064342.GY2167@pyrite.rasen.tech>","date":"2021-08-03T06:43:42","subject":"Re: [libcamera-devel] [PATCH v2 1/8] cam: event_loop: Add support\n\tfor file descriptor events","submitter":{"id":17,"url":"https://patchwork.libcamera.org/api/people/17/","name":"Paul Elder","email":"paul.elder@ideasonboard.com"},"content":"Hi Laurent,\n\nOn Fri, Jul 30, 2021 at 04:02:59AM +0300, Laurent Pinchart wrote:\n> Extend the EventLoop class to support watching file descriptors for\n> read and write events.\n> \n> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n\nReviewed-by: Paul Elder <paul.elder@ideasonboard.com>\n\n> ---\n>  src/cam/event_loop.cpp | 44 ++++++++++++++++++++++++++++++++++++++++++\n>  src/cam/event_loop.h   | 20 +++++++++++++++++++\n>  2 files changed, 64 insertions(+)\n> \n> diff --git a/src/cam/event_loop.cpp b/src/cam/event_loop.cpp\n> index 6a4c47f287d0..e25784c083cf 100644\n> --- a/src/cam/event_loop.cpp\n> +++ b/src/cam/event_loop.cpp\n> @@ -10,6 +10,7 @@\n>  #include <assert.h>\n>  #include <event2/event.h>\n>  #include <event2/thread.h>\n> +#include <iostream>\n>  \n>  EventLoop *EventLoop::instance_ = nullptr;\n>  \n> @@ -26,6 +27,7 @@ EventLoop::~EventLoop()\n>  {\n>  \tinstance_ = nullptr;\n>  \n> +\tevents_.clear();\n>  \tevent_base_free(base_);\n>  \tlibevent_global_shutdown();\n>  }\n> @@ -58,6 +60,30 @@ void EventLoop::callLater(const std::function<void()> &func)\n>  \tevent_base_once(base_, -1, EV_TIMEOUT, dispatchCallback, this, nullptr);\n>  }\n>  \n> +void EventLoop::addEvent(int fd, EventType type,\n> +\t\t\t const std::function<void()> &callback)\n> +{\n> +\tstd::unique_ptr<Event> event = std::make_unique<Event>(callback);\n> +\tshort events = (type & Read ? EV_READ : 0)\n> +\t\t     | (type & Write ? EV_WRITE : 0)\n> +\t\t     | EV_PERSIST;\n> +\n> +\tevent->event_ = event_new(base_, fd, events, &EventLoop::Event::dispatch,\n> +\t\t\t\t  event.get());\n> +\tif (!event->event_) {\n> +\t\tstd::cerr << \"Failed to create event for fd \" << fd << std::endl;\n> +\t\treturn;\n> +\t}\n> +\n> +\tint ret = event_add(event->event_, nullptr);\n> +\tif (ret < 0) {\n> +\t\tstd::cerr << \"Failed to add event for fd \" << fd << std::endl;\n> +\t\treturn;\n> +\t}\n> +\n> +\tevents_.push_back(std::move(event));\n> +}\n> +\n>  void EventLoop::dispatchCallback([[maybe_unused]] evutil_socket_t fd,\n>  \t\t\t\t [[maybe_unused]] short flags, void *param)\n>  {\n> @@ -80,3 +106,21 @@ void EventLoop::dispatchCall()\n>  \n>  \tcall();\n>  }\n> +\n> +EventLoop::Event::Event(const std::function<void()> &callback)\n> +\t: callback_(callback), event_(nullptr)\n> +{\n> +}\n> +\n> +EventLoop::Event::~Event()\n> +{\n> +\tevent_del(event_);\n> +\tevent_free(event_);\n> +}\n> +\n> +void EventLoop::Event::dispatch([[maybe_unused]] int fd,\n> +\t\t\t\t[[maybe_unused]] short events, void *arg)\n> +{\n> +\tEvent *event = static_cast<Event *>(arg);\n> +\tevent->callback_();\n> +}\n> diff --git a/src/cam/event_loop.h b/src/cam/event_loop.h\n> index ba3ba3a4a675..57bb6fb34aa7 100644\n> --- a/src/cam/event_loop.h\n> +++ b/src/cam/event_loop.h\n> @@ -8,6 +8,7 @@\n>  #define __CAM_EVENT_LOOP_H__\n>  \n>  #include <functional>\n> +#include <memory>\n>  #include <list>\n>  #include <mutex>\n>  \n> @@ -18,6 +19,11 @@ struct event_base;\n>  class EventLoop\n>  {\n>  public:\n> +\tenum EventType {\n> +\t\tRead = 1,\n> +\t\tWrite = 2,\n> +\t};\n> +\n>  \tEventLoop();\n>  \t~EventLoop();\n>  \n> @@ -28,13 +34,27 @@ public:\n>  \n>  \tvoid callLater(const std::function<void()> &func);\n>  \n> +\tvoid addEvent(int fd, EventType type,\n> +\t\t      const std::function<void()> &handler);\n> +\n>  private:\n> +\tstruct Event {\n> +\t\tEvent(const std::function<void()> &callback);\n> +\t\t~Event();\n> +\n> +\t\tstatic void dispatch(int fd, short events, void *arg);\n> +\n> +\t\tstd::function<void()> callback_;\n> +\t\tstruct event *event_;\n> +\t};\n> +\n>  \tstatic EventLoop *instance_;\n>  \n>  \tstruct event_base *base_;\n>  \tint exitCode_;\n>  \n>  \tstd::list<std::function<void()>> calls_;\n> +\tstd::list<std::unique_ptr<Event>> events_;\n>  \tstd::mutex lock_;\n>  \n>  \tstatic void dispatchCallback(evutil_socket_t fd, short flags,\n> -- \n> Regards,\n> \n> Laurent Pinchart\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 CBA50C3235\n\tfor <parsemail@patchwork.libcamera.org>;\n\tTue,  3 Aug 2021 06:43:52 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 26557687CC;\n\tTue,  3 Aug 2021 08:43:52 +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 7104A60269\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue,  3 Aug 2021 08:43:50 +0200 (CEST)","from pyrite.rasen.tech (unknown\n\t[IPv6:2400:4051:61:600:2c71:1b79:d06d:5032])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 050A54A3;\n\tTue,  3 Aug 2021 08:43:48 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"NowbJYsS\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1627973030;\n\tbh=lM+jm4M1tY0rVjA1NfihOBtYx6vVn80J8N75CTEgU2M=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=NowbJYsSIx+lNj5uF5cdS+yizGCcxaGvhk5RhuQhAvRwunXKF9s0j9JfvZ/zIVD0g\n\toXPSbMG1kMtX+X0iFVRre89YQ2Y7+zr0KLM58lWiWWmzMY0hd60eS3aa8rcxPoEm1z\n\tDnIN7aFXNtp8C7P1m95obyKakqy7zNTswt0FQr8g=","Date":"Tue, 3 Aug 2021 15:43:42 +0900","From":"paul.elder@ideasonboard.com","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","Message-ID":"<20210803064342.GY2167@pyrite.rasen.tech>","References":"<20210730010306.19956-1-laurent.pinchart@ideasonboard.com>\n\t<20210730010306.19956-2-laurent.pinchart@ideasonboard.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=us-ascii","Content-Disposition":"inline","In-Reply-To":"<20210730010306.19956-2-laurent.pinchart@ideasonboard.com>","Subject":"Re: [libcamera-devel] [PATCH v2 1/8] cam: event_loop: Add support\n\tfor file descriptor events","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>","Cc":"libcamera-devel@lists.libcamera.org","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":18509,"web_url":"https://patchwork.libcamera.org/comment/18509/","msgid":"<a063401f-1af2-5584-6a13-c6905bd6b0e8@ideasonboard.com>","date":"2021-08-03T10:35:34","subject":"Re: [libcamera-devel] [PATCH v2 1/8] cam: event_loop: Add support\n\tfor file descriptor events","submitter":{"id":4,"url":"https://patchwork.libcamera.org/api/people/4/","name":"Kieran Bingham","email":"kieran.bingham@ideasonboard.com"},"content":"Hi Laurent,\n\nOn 30/07/2021 02:02, Laurent Pinchart wrote:\n> Extend the EventLoop class to support watching file descriptors for\n> read and write events.\n> \n> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n> ---\n>  src/cam/event_loop.cpp | 44 ++++++++++++++++++++++++++++++++++++++++++\n>  src/cam/event_loop.h   | 20 +++++++++++++++++++\n>  2 files changed, 64 insertions(+)\n> \n> diff --git a/src/cam/event_loop.cpp b/src/cam/event_loop.cpp\n> index 6a4c47f287d0..e25784c083cf 100644\n> --- a/src/cam/event_loop.cpp\n> +++ b/src/cam/event_loop.cpp\n> @@ -10,6 +10,7 @@\n>  #include <assert.h>\n>  #include <event2/event.h>\n>  #include <event2/thread.h>\n> +#include <iostream>\n>  \n>  EventLoop *EventLoop::instance_ = nullptr;\n>  \n> @@ -26,6 +27,7 @@ EventLoop::~EventLoop()\n>  {\n>  \tinstance_ = nullptr;\n>  \n> +\tevents_.clear();\n>  \tevent_base_free(base_);\n>  \tlibevent_global_shutdown();\n>  }\n> @@ -58,6 +60,30 @@ void EventLoop::callLater(const std::function<void()> &func)\n>  \tevent_base_once(base_, -1, EV_TIMEOUT, dispatchCallback, this, nullptr);\n>  }\n>  \n> +void EventLoop::addEvent(int fd, EventType type,\n> +\t\t\t const std::function<void()> &callback)\n> +{\n> +\tstd::unique_ptr<Event> event = std::make_unique<Event>(callback);\n> +\tshort events = (type & Read ? EV_READ : 0)\n> +\t\t     | (type & Write ? EV_WRITE : 0)\n> +\t\t     | EV_PERSIST;\n> +\n> +\tevent->event_ = event_new(base_, fd, events, &EventLoop::Event::dispatch,\n> +\t\t\t\t  event.get());\n> +\tif (!event->event_) {\n> +\t\tstd::cerr << \"Failed to create event for fd \" << fd << std::endl;\n> +\t\treturn;\n> +\t}\n> +\n> +\tint ret = event_add(event->event_, nullptr);\n> +\tif (ret < 0) {\n> +\t\tstd::cerr << \"Failed to add event for fd \" << fd << std::endl;\n> +\t\treturn;\n> +\t}\n> +\n> +\tevents_.push_back(std::move(event));\n> +}\n> +\n>  void EventLoop::dispatchCallback([[maybe_unused]] evutil_socket_t fd,\n>  \t\t\t\t [[maybe_unused]] short flags, void *param)\n>  {\n> @@ -80,3 +106,21 @@ void EventLoop::dispatchCall()\n>  \n>  \tcall();\n>  }\n> +\n> +EventLoop::Event::Event(const std::function<void()> &callback)\n> +\t: callback_(callback), event_(nullptr)\n> +{\n> +}\n> +\n> +EventLoop::Event::~Event()\n> +{\n> +\tevent_del(event_);\n> +\tevent_free(event_);\n> +}\n> +\n> +void EventLoop::Event::dispatch([[maybe_unused]] int fd,\n> +\t\t\t\t[[maybe_unused]] short events, void *arg)\n> +{\n> +\tEvent *event = static_cast<Event *>(arg);\n> +\tevent->callback_();\n> +}\n> diff --git a/src/cam/event_loop.h b/src/cam/event_loop.h\n> index ba3ba3a4a675..57bb6fb34aa7 100644\n> --- a/src/cam/event_loop.h\n> +++ b/src/cam/event_loop.h\n> @@ -8,6 +8,7 @@\n>  #define __CAM_EVENT_LOOP_H__\n>  \n>  #include <functional>\n> +#include <memory>\n>  #include <list>\n>  #include <mutex>\n>  \n> @@ -18,6 +19,11 @@ struct event_base;\n>  class EventLoop\n>  {\n>  public:\n> +\tenum EventType {\n> +\t\tRead = 1,\n> +\t\tWrite = 2,\n> +\t};\n> +\n>  \tEventLoop();\n>  \t~EventLoop();\n>  \n> @@ -28,13 +34,27 @@ public:\n>  \n>  \tvoid callLater(const std::function<void()> &func);\n>  \n> +\tvoid addEvent(int fd, EventType type,\n> +\t\t      const std::function<void()> &handler);\n> +\n>  private:\n> +\tstruct Event {\n> +\t\tEvent(const std::function<void()> &callback);\n> +\t\t~Event();\n> +\n> +\t\tstatic void dispatch(int fd, short events, void *arg);\n> +\n> +\t\tstd::function<void()> callback_;\n> +\t\tstruct event *event_;\n> +\t};\n> +\n>  \tstatic EventLoop *instance_;\n>  \n>  \tstruct event_base *base_;\n>  \tint exitCode_;\n>  \n>  \tstd::list<std::function<void()>> calls_;\n> +\tstd::list<std::unique_ptr<Event>> events_;\n>  \tstd::mutex lock_;\n>  \n>  \tstatic void dispatchCallback(evutil_socket_t fd, short flags,\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 30457C3232\n\tfor <parsemail@patchwork.libcamera.org>;\n\tTue,  3 Aug 2021 10:35:40 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 86127687CC;\n\tTue,  3 Aug 2021 12:35:39 +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 11D606026A\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue,  3 Aug 2021 12:35:38 +0200 (CEST)","from [192.168.0.20]\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 596C83F0;\n\tTue,  3 Aug 2021 12:35:37 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"Rf1M6nEC\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1627986937;\n\tbh=JgEUqwYh+pwnHCTVhI7i+iXhfwShffWdXAUnAXyj2A0=;\n\th=Subject:To:References:From:Date:In-Reply-To:From;\n\tb=Rf1M6nECkpC0E+QS9oDAtT/d68/Hiw7IlB5J/k4XX6yTAzoGdi5ucSQRhMkx2u8bq\n\tOPugGKegaRf6JEgv3lZEPxBEMzIfLzaTYY/2i1cPoDQLJFJUXQhDBQ9oA6M54jVsfV\n\tBFRTaQkqHgJJx3LweOqBYdxY1eL2sv0JmXN05eow=","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>,\n\tlibcamera-devel@lists.libcamera.org","References":"<20210730010306.19956-1-laurent.pinchart@ideasonboard.com>\n\t<20210730010306.19956-2-laurent.pinchart@ideasonboard.com>","From":"Kieran Bingham <kieran.bingham@ideasonboard.com>","Message-ID":"<a063401f-1af2-5584-6a13-c6905bd6b0e8@ideasonboard.com>","Date":"Tue, 3 Aug 2021 11:35:34 +0100","User-Agent":"Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101\n\tThunderbird/78.11.0","MIME-Version":"1.0","In-Reply-To":"<20210730010306.19956-2-laurent.pinchart@ideasonboard.com>","Content-Type":"text/plain; charset=utf-8","Content-Language":"en-GB","Content-Transfer-Encoding":"7bit","Subject":"Re: [libcamera-devel] [PATCH v2 1/8] cam: event_loop: Add support\n\tfor file descriptor events","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":18510,"web_url":"https://patchwork.libcamera.org/comment/18510/","msgid":"<YQkdw/5E3ENHFlH7@pendragon.ideasonboard.com>","date":"2021-08-03T10:43:15","subject":"Re: [libcamera-devel] [PATCH v2 1/8] cam: event_loop: Add support\n\tfor file descriptor events","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"Hi Kieran,\n\nOn Tue, Aug 03, 2021 at 11:35:34AM +0100, Kieran Bingham wrote:\n> Hi Laurent,\n\nYes ? :-)\n\n> On 30/07/2021 02:02, Laurent Pinchart wrote:\n> > Extend the EventLoop class to support watching file descriptors for\n> > read and write events.\n> > \n> > Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n> > ---\n> >  src/cam/event_loop.cpp | 44 ++++++++++++++++++++++++++++++++++++++++++\n> >  src/cam/event_loop.h   | 20 +++++++++++++++++++\n> >  2 files changed, 64 insertions(+)\n> > \n> > diff --git a/src/cam/event_loop.cpp b/src/cam/event_loop.cpp\n> > index 6a4c47f287d0..e25784c083cf 100644\n> > --- a/src/cam/event_loop.cpp\n> > +++ b/src/cam/event_loop.cpp\n> > @@ -10,6 +10,7 @@\n> >  #include <assert.h>\n> >  #include <event2/event.h>\n> >  #include <event2/thread.h>\n> > +#include <iostream>\n> >  \n> >  EventLoop *EventLoop::instance_ = nullptr;\n> >  \n> > @@ -26,6 +27,7 @@ EventLoop::~EventLoop()\n> >  {\n> >  \tinstance_ = nullptr;\n> >  \n> > +\tevents_.clear();\n> >  \tevent_base_free(base_);\n> >  \tlibevent_global_shutdown();\n> >  }\n> > @@ -58,6 +60,30 @@ void EventLoop::callLater(const std::function<void()> &func)\n> >  \tevent_base_once(base_, -1, EV_TIMEOUT, dispatchCallback, this, nullptr);\n> >  }\n> >  \n> > +void EventLoop::addEvent(int fd, EventType type,\n> > +\t\t\t const std::function<void()> &callback)\n> > +{\n> > +\tstd::unique_ptr<Event> event = std::make_unique<Event>(callback);\n> > +\tshort events = (type & Read ? EV_READ : 0)\n> > +\t\t     | (type & Write ? EV_WRITE : 0)\n> > +\t\t     | EV_PERSIST;\n> > +\n> > +\tevent->event_ = event_new(base_, fd, events, &EventLoop::Event::dispatch,\n> > +\t\t\t\t  event.get());\n> > +\tif (!event->event_) {\n> > +\t\tstd::cerr << \"Failed to create event for fd \" << fd << std::endl;\n> > +\t\treturn;\n> > +\t}\n> > +\n> > +\tint ret = event_add(event->event_, nullptr);\n> > +\tif (ret < 0) {\n> > +\t\tstd::cerr << \"Failed to add event for fd \" << fd << std::endl;\n> > +\t\treturn;\n> > +\t}\n> > +\n> > +\tevents_.push_back(std::move(event));\n> > +}\n> > +\n> >  void EventLoop::dispatchCallback([[maybe_unused]] evutil_socket_t fd,\n> >  \t\t\t\t [[maybe_unused]] short flags, void *param)\n> >  {\n> > @@ -80,3 +106,21 @@ void EventLoop::dispatchCall()\n> >  \n> >  \tcall();\n> >  }\n> > +\n> > +EventLoop::Event::Event(const std::function<void()> &callback)\n> > +\t: callback_(callback), event_(nullptr)\n> > +{\n> > +}\n> > +\n> > +EventLoop::Event::~Event()\n> > +{\n> > +\tevent_del(event_);\n> > +\tevent_free(event_);\n> > +}\n> > +\n> > +void EventLoop::Event::dispatch([[maybe_unused]] int fd,\n> > +\t\t\t\t[[maybe_unused]] short events, void *arg)\n> > +{\n> > +\tEvent *event = static_cast<Event *>(arg);\n> > +\tevent->callback_();\n> > +}\n> > diff --git a/src/cam/event_loop.h b/src/cam/event_loop.h\n> > index ba3ba3a4a675..57bb6fb34aa7 100644\n> > --- a/src/cam/event_loop.h\n> > +++ b/src/cam/event_loop.h\n> > @@ -8,6 +8,7 @@\n> >  #define __CAM_EVENT_LOOP_H__\n> >  \n> >  #include <functional>\n> > +#include <memory>\n> >  #include <list>\n> >  #include <mutex>\n> >  \n> > @@ -18,6 +19,11 @@ struct event_base;\n> >  class EventLoop\n> >  {\n> >  public:\n> > +\tenum EventType {\n> > +\t\tRead = 1,\n> > +\t\tWrite = 2,\n> > +\t};\n> > +\n> >  \tEventLoop();\n> >  \t~EventLoop();\n> >  \n> > @@ -28,13 +34,27 @@ public:\n> >  \n> >  \tvoid callLater(const std::function<void()> &func);\n> >  \n> > +\tvoid addEvent(int fd, EventType type,\n> > +\t\t      const std::function<void()> &handler);\n> > +\n> >  private:\n> > +\tstruct Event {\n> > +\t\tEvent(const std::function<void()> &callback);\n> > +\t\t~Event();\n> > +\n> > +\t\tstatic void dispatch(int fd, short events, void *arg);\n> > +\n> > +\t\tstd::function<void()> callback_;\n> > +\t\tstruct event *event_;\n> > +\t};\n> > +\n> >  \tstatic EventLoop *instance_;\n> >  \n> >  \tstruct event_base *base_;\n> >  \tint exitCode_;\n> >  \n> >  \tstd::list<std::function<void()>> calls_;\n> > +\tstd::list<std::unique_ptr<Event>> events_;\n> >  \tstd::mutex lock_;\n> >  \n> >  \tstatic void dispatchCallback(evutil_socket_t fd, short flags,\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 8D9A6C3235\n\tfor <parsemail@patchwork.libcamera.org>;\n\tTue,  3 Aug 2021 10:43:32 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 76E9568536;\n\tTue,  3 Aug 2021 12:43:29 +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 D0E936026A\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue,  3 Aug 2021 12:43:27 +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 4A4F83F0;\n\tTue,  3 Aug 2021 12:43:27 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"YrKEBYG3\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1627987407;\n\tbh=kAERB8C83Zbdg2Ug7rnjPaglq82hd4xzG14q7N/o++Q=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=YrKEBYG33Fs0XHPpZ4/K3gVMzBUFCZoJWrMdUE53yYlOQUx6dkAVx2KuYKyZgkJCp\n\tpX7fuJCex/fQCZt4CvL80g4jdJHMgI/gOkkntodEeVqxfBB6BfyDIuX2usxdgp8XdT\n\t0FP7aaRb+qRkyg1r8ecc8775vp1954BDHNOXwKe0=","Date":"Tue, 3 Aug 2021 13:43:15 +0300","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"Kieran Bingham <kieran.bingham@ideasonboard.com>","Message-ID":"<YQkdw/5E3ENHFlH7@pendragon.ideasonboard.com>","References":"<20210730010306.19956-1-laurent.pinchart@ideasonboard.com>\n\t<20210730010306.19956-2-laurent.pinchart@ideasonboard.com>\n\t<a063401f-1af2-5584-6a13-c6905bd6b0e8@ideasonboard.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","In-Reply-To":"<a063401f-1af2-5584-6a13-c6905bd6b0e8@ideasonboard.com>","Subject":"Re: [libcamera-devel] [PATCH v2 1/8] cam: event_loop: Add support\n\tfor file descriptor events","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>","Cc":"libcamera-devel@lists.libcamera.org","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":18511,"web_url":"https://patchwork.libcamera.org/comment/18511/","msgid":"<6f9cff83-8e6f-5564-f838-a704e4669d29@ideasonboard.com>","date":"2021-08-03T10:44:29","subject":"Re: [libcamera-devel] [PATCH v2 1/8] cam: event_loop: Add support\n\tfor file descriptor events","submitter":{"id":4,"url":"https://patchwork.libcamera.org/api/people/4/","name":"Kieran Bingham","email":"kieran.bingham@ideasonboard.com"},"content":"On 03/08/2021 11:43, Laurent Pinchart wrote:\n> Hi Kieran,\n> \n> On Tue, Aug 03, 2021 at 11:35:34AM +0100, Kieran Bingham wrote:\n>> Hi Laurent,\n> \n> Yes ? :-)\n\nAgreed. ... ;-)\n\n\n> \n>> On 30/07/2021 02:02, Laurent Pinchart wrote:\n>>> Extend the EventLoop class to support watching file descriptors for\n>>> read and write events.\n>>>\n>>> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n\nReviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n\n>>> ---\n>>>  src/cam/event_loop.cpp | 44 ++++++++++++++++++++++++++++++++++++++++++\n>>>  src/cam/event_loop.h   | 20 +++++++++++++++++++\n>>>  2 files changed, 64 insertions(+)\n>>>\n>>> diff --git a/src/cam/event_loop.cpp b/src/cam/event_loop.cpp\n>>> index 6a4c47f287d0..e25784c083cf 100644\n>>> --- a/src/cam/event_loop.cpp\n>>> +++ b/src/cam/event_loop.cpp\n>>> @@ -10,6 +10,7 @@\n>>>  #include <assert.h>\n>>>  #include <event2/event.h>\n>>>  #include <event2/thread.h>\n>>> +#include <iostream>\n>>>  \n>>>  EventLoop *EventLoop::instance_ = nullptr;\n>>>  \n>>> @@ -26,6 +27,7 @@ EventLoop::~EventLoop()\n>>>  {\n>>>  \tinstance_ = nullptr;\n>>>  \n>>> +\tevents_.clear();\n>>>  \tevent_base_free(base_);\n>>>  \tlibevent_global_shutdown();\n>>>  }\n>>> @@ -58,6 +60,30 @@ void EventLoop::callLater(const std::function<void()> &func)\n>>>  \tevent_base_once(base_, -1, EV_TIMEOUT, dispatchCallback, this, nullptr);\n>>>  }\n>>>  \n>>> +void EventLoop::addEvent(int fd, EventType type,\n>>> +\t\t\t const std::function<void()> &callback)\n>>> +{\n>>> +\tstd::unique_ptr<Event> event = std::make_unique<Event>(callback);\n>>> +\tshort events = (type & Read ? EV_READ : 0)\n>>> +\t\t     | (type & Write ? EV_WRITE : 0)\n>>> +\t\t     | EV_PERSIST;\n>>> +\n>>> +\tevent->event_ = event_new(base_, fd, events, &EventLoop::Event::dispatch,\n>>> +\t\t\t\t  event.get());\n>>> +\tif (!event->event_) {\n>>> +\t\tstd::cerr << \"Failed to create event for fd \" << fd << std::endl;\n>>> +\t\treturn;\n>>> +\t}\n>>> +\n>>> +\tint ret = event_add(event->event_, nullptr);\n>>> +\tif (ret < 0) {\n>>> +\t\tstd::cerr << \"Failed to add event for fd \" << fd << std::endl;\n>>> +\t\treturn;\n>>> +\t}\n>>> +\n>>> +\tevents_.push_back(std::move(event));\n>>> +}\n>>> +\n>>>  void EventLoop::dispatchCallback([[maybe_unused]] evutil_socket_t fd,\n>>>  \t\t\t\t [[maybe_unused]] short flags, void *param)\n>>>  {\n>>> @@ -80,3 +106,21 @@ void EventLoop::dispatchCall()\n>>>  \n>>>  \tcall();\n>>>  }\n>>> +\n>>> +EventLoop::Event::Event(const std::function<void()> &callback)\n>>> +\t: callback_(callback), event_(nullptr)\n>>> +{\n>>> +}\n>>> +\n>>> +EventLoop::Event::~Event()\n>>> +{\n>>> +\tevent_del(event_);\n>>> +\tevent_free(event_);\n>>> +}\n>>> +\n>>> +void EventLoop::Event::dispatch([[maybe_unused]] int fd,\n>>> +\t\t\t\t[[maybe_unused]] short events, void *arg)\n>>> +{\n>>> +\tEvent *event = static_cast<Event *>(arg);\n>>> +\tevent->callback_();\n>>> +}\n>>> diff --git a/src/cam/event_loop.h b/src/cam/event_loop.h\n>>> index ba3ba3a4a675..57bb6fb34aa7 100644\n>>> --- a/src/cam/event_loop.h\n>>> +++ b/src/cam/event_loop.h\n>>> @@ -8,6 +8,7 @@\n>>>  #define __CAM_EVENT_LOOP_H__\n>>>  \n>>>  #include <functional>\n>>> +#include <memory>\n>>>  #include <list>\n>>>  #include <mutex>\n>>>  \n>>> @@ -18,6 +19,11 @@ struct event_base;\n>>>  class EventLoop\n>>>  {\n>>>  public:\n>>> +\tenum EventType {\n>>> +\t\tRead = 1,\n>>> +\t\tWrite = 2,\n>>> +\t};\n>>> +\n>>>  \tEventLoop();\n>>>  \t~EventLoop();\n>>>  \n>>> @@ -28,13 +34,27 @@ public:\n>>>  \n>>>  \tvoid callLater(const std::function<void()> &func);\n>>>  \n>>> +\tvoid addEvent(int fd, EventType type,\n>>> +\t\t      const std::function<void()> &handler);\n>>> +\n>>>  private:\n>>> +\tstruct Event {\n>>> +\t\tEvent(const std::function<void()> &callback);\n>>> +\t\t~Event();\n>>> +\n>>> +\t\tstatic void dispatch(int fd, short events, void *arg);\n>>> +\n>>> +\t\tstd::function<void()> callback_;\n>>> +\t\tstruct event *event_;\n>>> +\t};\n>>> +\n>>>  \tstatic EventLoop *instance_;\n>>>  \n>>>  \tstruct event_base *base_;\n>>>  \tint exitCode_;\n>>>  \n>>>  \tstd::list<std::function<void()>> calls_;\n>>> +\tstd::list<std::unique_ptr<Event>> events_;\n>>>  \tstd::mutex lock_;\n>>>  \n>>>  \tstatic void dispatchCallback(evutil_socket_t fd, short flags,\n>>>\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 41CA9C3235\n\tfor <parsemail@patchwork.libcamera.org>;\n\tTue,  3 Aug 2021 10:44:34 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id E276E687CC;\n\tTue,  3 Aug 2021 12:44:33 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 4B9036026A\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue,  3 Aug 2021 12:44:32 +0200 (CEST)","from [192.168.0.20]\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 DE4C93F0;\n\tTue,  3 Aug 2021 12:44:31 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"mT4A9g/Z\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1627987472;\n\tbh=9WrhSY47S3jApQMb4bthtNcctBIJq1clcxCOO5F3+ac=;\n\th=From:Subject:To:Cc:References:Date:In-Reply-To:From;\n\tb=mT4A9g/ZR6tL32VAtwlHPpFwSQSs9Nsf16VGiWH0AaiI0LRenGaTAOkYvmjweJ1ed\n\tQLelRb9mXeZHKHAeFWsgkR2HoVY3/mJIYuu4URfzk+FXWCkPe77TwGcVJS9NbqBQU+\n\tBZ0uBEWWvQIoFSEkdzf6wbmNDhTqWwLW4b591lhs=","From":"Kieran Bingham <kieran.bingham@ideasonboard.com>","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","References":"<20210730010306.19956-1-laurent.pinchart@ideasonboard.com>\n\t<20210730010306.19956-2-laurent.pinchart@ideasonboard.com>\n\t<a063401f-1af2-5584-6a13-c6905bd6b0e8@ideasonboard.com>\n\t<YQkdw/5E3ENHFlH7@pendragon.ideasonboard.com>","Message-ID":"<6f9cff83-8e6f-5564-f838-a704e4669d29@ideasonboard.com>","Date":"Tue, 3 Aug 2021 11:44:29 +0100","User-Agent":"Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101\n\tThunderbird/78.11.0","MIME-Version":"1.0","In-Reply-To":"<YQkdw/5E3ENHFlH7@pendragon.ideasonboard.com>","Content-Type":"text/plain; charset=utf-8","Content-Language":"en-GB","Content-Transfer-Encoding":"7bit","Subject":"Re: [libcamera-devel] [PATCH v2 1/8] cam: event_loop: Add support\n\tfor file descriptor events","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>","Cc":"libcamera-devel@lists.libcamera.org","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":18531,"web_url":"https://patchwork.libcamera.org/comment/18531/","msgid":"<5ecd9c80-a51a-091b-9735-738b377ea62a@ideasonboard.com>","date":"2021-08-04T05:32:45","subject":"Re: [libcamera-devel] [PATCH v2 1/8] cam: event_loop: Add support\n\tfor file descriptor events","submitter":{"id":86,"url":"https://patchwork.libcamera.org/api/people/86/","name":"Umang Jain","email":"umang.jain@ideasonboard.com"},"content":"Hi Laurent,\n\nOn 7/30/21 6:32 AM, Laurent Pinchart wrote:\n> Extend the EventLoop class to support watching file descriptors for\n> read and write events.\n>\n> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\nReviewed-by: Umang Jain <umang.jain@ideasonboard.com>\n> ---\n>   src/cam/event_loop.cpp | 44 ++++++++++++++++++++++++++++++++++++++++++\n>   src/cam/event_loop.h   | 20 +++++++++++++++++++\n>   2 files changed, 64 insertions(+)\n>\n> diff --git a/src/cam/event_loop.cpp b/src/cam/event_loop.cpp\n> index 6a4c47f287d0..e25784c083cf 100644\n> --- a/src/cam/event_loop.cpp\n> +++ b/src/cam/event_loop.cpp\n> @@ -10,6 +10,7 @@\n>   #include <assert.h>\n>   #include <event2/event.h>\n>   #include <event2/thread.h>\n> +#include <iostream>\n>   \n>   EventLoop *EventLoop::instance_ = nullptr;\n>   \n> @@ -26,6 +27,7 @@ EventLoop::~EventLoop()\n>   {\n>   \tinstance_ = nullptr;\n>   \n> +\tevents_.clear();\n>   \tevent_base_free(base_);\n>   \tlibevent_global_shutdown();\n>   }\n> @@ -58,6 +60,30 @@ void EventLoop::callLater(const std::function<void()> &func)\n>   \tevent_base_once(base_, -1, EV_TIMEOUT, dispatchCallback, this, nullptr);\n>   }\n>   \n> +void EventLoop::addEvent(int fd, EventType type,\n> +\t\t\t const std::function<void()> &callback)\n> +{\n> +\tstd::unique_ptr<Event> event = std::make_unique<Event>(callback);\n> +\tshort events = (type & Read ? EV_READ : 0)\n> +\t\t     | (type & Write ? EV_WRITE : 0)\n> +\t\t     | EV_PERSIST;\n> +\n> +\tevent->event_ = event_new(base_, fd, events, &EventLoop::Event::dispatch,\n> +\t\t\t\t  event.get());\n> +\tif (!event->event_) {\n> +\t\tstd::cerr << \"Failed to create event for fd \" << fd << std::endl;\n> +\t\treturn;\n> +\t}\n> +\n> +\tint ret = event_add(event->event_, nullptr);\n> +\tif (ret < 0) {\n> +\t\tstd::cerr << \"Failed to add event for fd \" << fd << std::endl;\n> +\t\treturn;\n> +\t}\n> +\n> +\tevents_.push_back(std::move(event));\n> +}\n> +\n>   void EventLoop::dispatchCallback([[maybe_unused]] evutil_socket_t fd,\n>   \t\t\t\t [[maybe_unused]] short flags, void *param)\n>   {\n> @@ -80,3 +106,21 @@ void EventLoop::dispatchCall()\n>   \n>   \tcall();\n>   }\n> +\n> +EventLoop::Event::Event(const std::function<void()> &callback)\n> +\t: callback_(callback), event_(nullptr)\n> +{\n> +}\n> +\n> +EventLoop::Event::~Event()\n> +{\n> +\tevent_del(event_);\n> +\tevent_free(event_);\n> +}\n> +\n> +void EventLoop::Event::dispatch([[maybe_unused]] int fd,\n> +\t\t\t\t[[maybe_unused]] short events, void *arg)\n> +{\n> +\tEvent *event = static_cast<Event *>(arg);\n> +\tevent->callback_();\n> +}\n> diff --git a/src/cam/event_loop.h b/src/cam/event_loop.h\n> index ba3ba3a4a675..57bb6fb34aa7 100644\n> --- a/src/cam/event_loop.h\n> +++ b/src/cam/event_loop.h\n> @@ -8,6 +8,7 @@\n>   #define __CAM_EVENT_LOOP_H__\n>   \n>   #include <functional>\n> +#include <memory>\n>   #include <list>\n>   #include <mutex>\n>   \n> @@ -18,6 +19,11 @@ struct event_base;\n>   class EventLoop\n>   {\n>   public:\n> +\tenum EventType {\n> +\t\tRead = 1,\n> +\t\tWrite = 2,\n> +\t};\n> +\n>   \tEventLoop();\n>   \t~EventLoop();\n>   \n> @@ -28,13 +34,27 @@ public:\n>   \n>   \tvoid callLater(const std::function<void()> &func);\n>   \n> +\tvoid addEvent(int fd, EventType type,\n> +\t\t      const std::function<void()> &handler);\n> +\n>   private:\n> +\tstruct Event {\n> +\t\tEvent(const std::function<void()> &callback);\n> +\t\t~Event();\n> +\n> +\t\tstatic void dispatch(int fd, short events, void *arg);\n> +\n> +\t\tstd::function<void()> callback_;\n> +\t\tstruct event *event_;\n> +\t};\n> +\n>   \tstatic EventLoop *instance_;\n>   \n>   \tstruct event_base *base_;\n>   \tint exitCode_;\n>   \n>   \tstd::list<std::function<void()>> calls_;\n> +\tstd::list<std::unique_ptr<Event>> events_;\n>   \tstd::mutex lock_;\n>   \n>   \tstatic void dispatchCallback(evutil_socket_t fd, short flags,","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 63710C3232\n\tfor <parsemail@patchwork.libcamera.org>;\n\tWed,  4 Aug 2021 05:32:52 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id B5B3968811;\n\tWed,  4 Aug 2021 07:32: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 B628860268\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed,  4 Aug 2021 07:32:50 +0200 (CEST)","from [192.168.1.104] (unknown [103.251.226.40])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id BD79D24F;\n\tWed,  4 Aug 2021 07:32:49 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"DpeiSe6R\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1628055170;\n\tbh=Rxx85XVm+H/HC52QRZNpO6g8wkuKPfITGvXzEHWBFRk=;\n\th=Subject:To:References:From:Date:In-Reply-To:From;\n\tb=DpeiSe6RQ8ZzA/IYg9jeozFKhtW4tUZM1NA1g+L00GDBEJU13Bix+6iLPciwy8i8x\n\tBEPz4SiSCPuHpZXvfR6++8hZhAcnLS+v6Dxr6UNvq2IATgWs1q3pDQpmkapLMn321j\n\tFyzV3ytjgo6sb8+JWopme8iL9leH6Giit7CCsAx0=","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>,\n\tlibcamera-devel@lists.libcamera.org","References":"<20210730010306.19956-1-laurent.pinchart@ideasonboard.com>\n\t<20210730010306.19956-2-laurent.pinchart@ideasonboard.com>","From":"Umang Jain <umang.jain@ideasonboard.com>","Message-ID":"<5ecd9c80-a51a-091b-9735-738b377ea62a@ideasonboard.com>","Date":"Wed, 4 Aug 2021 11:02:45 +0530","User-Agent":"Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101\n\tThunderbird/78.10.2","MIME-Version":"1.0","In-Reply-To":"<20210730010306.19956-2-laurent.pinchart@ideasonboard.com>","Content-Type":"text/plain; charset=utf-8; format=flowed","Content-Transfer-Encoding":"7bit","Content-Language":"en-US","Subject":"Re: [libcamera-devel] [PATCH v2 1/8] cam: event_loop: Add support\n\tfor file descriptor events","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}}]