[{"id":523,"web_url":"https://patchwork.libcamera.org/comment/523/","msgid":"<98105b45-e869-7fb7-27f0-6d3f9660170e@ideasonboard.com>","date":"2019-01-23T11:43:21","subject":"Re: [libcamera-devel] [PATCH 3/4] libcamera: event_dispatcher: Add\n\tinterrupt() function","submitter":{"id":4,"url":"https://patchwork.libcamera.org/api/people/4/","name":"Kieran Bingham","email":"kieran.bingham@ideasonboard.com"},"content":"Hi Laurent,\n\nOn 23/01/2019 08:59, Laurent Pinchart wrote:\n> The new interrupt() function allows interrupting in-progress blocking\n> processEvents() calls. This is useful to stop running event loops.\n\n\nReviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n\n> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n> ---\n>  include/libcamera/event_dispatcher.h          |  2 ++\n>  src/libcamera/event_dispatcher.cpp            | 10 ++++++\n>  src/libcamera/event_dispatcher_poll.cpp       | 32 ++++++++++++++++++-\n>  src/libcamera/include/event_dispatcher_poll.h |  3 ++\n>  4 files changed, 46 insertions(+), 1 deletion(-)\n> \n> diff --git a/include/libcamera/event_dispatcher.h b/include/libcamera/event_dispatcher.h\n> index c20518c6866d..cb06bf208e12 100644\n> --- a/include/libcamera/event_dispatcher.h\n> +++ b/include/libcamera/event_dispatcher.h\n> @@ -26,6 +26,8 @@ public:\n>  \tvirtual void unregisterTimer(Timer *timer) = 0;\n>  \n>  \tvirtual void processEvents() = 0;\n> +\n> +\tvirtual void interrupt() = 0;\n>  };\n>  \n>  } /* namespace libcamera */\n> diff --git a/src/libcamera/event_dispatcher.cpp b/src/libcamera/event_dispatcher.cpp\n> index f7c40734095e..b82c59c3f5dc 100644\n> --- a/src/libcamera/event_dispatcher.cpp\n> +++ b/src/libcamera/event_dispatcher.cpp\n> @@ -104,4 +104,14 @@ EventDispatcher::~EventDispatcher()\n>   * it before returning.\n>   */\n>  \n> +/**\n> + * \\fn EventDispatcher::interrupt()\n> + * \\brief Interrupt any running processEvents() call as soon as possible\n> + *\n> + * Calling this function interrupts any blocking processEvents() call in\n> + * progress. The processEvents() function will return as soon as possible,\n> + * after processing pending timers and events. If processEvents() isn't in\n> + * progress, it will be interrupted immediately the next time it gets called.\n> + */\n> +\n>  } /* namespace libcamera */\n> diff --git a/src/libcamera/event_dispatcher_poll.cpp b/src/libcamera/event_dispatcher_poll.cpp\n> index 6e0609c34ddc..a2674ab31135 100644\n> --- a/src/libcamera/event_dispatcher_poll.cpp\n> +++ b/src/libcamera/event_dispatcher_poll.cpp\n> @@ -8,7 +8,10 @@\n>  #include <algorithm>\n>  #include <iomanip>\n>  #include <poll.h>\n> +#include <stdint.h>\n>  #include <string.h>\n> +#include <sys/eventfd.h>\n> +#include <unistd.h>\n>  \n>  #include <libcamera/event_notifier.h>\n>  #include <libcamera/timer.h>\n> @@ -43,10 +46,18 @@ static const char *notifierType(EventNotifier::Type type)\n>  \n>  EventDispatcherPoll::EventDispatcherPoll()\n>  {\n> +\t/*\n> +\t * Create the event fd. Failures are fatal as we can't implement an\n> +\t * interruptible dispatcher without the fd.\n> +\t */\n> +\teventfd_ = eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK);\n\nHrm ... I didn't know about eventfd. I'd always used a pair of pipes.\n\nEvery day's a school day :)\n\nThe man page says it's linux-specific - but I think we're OK with that :-)\n\n\n> +\tif (eventfd_ < 0)\n> +\t\tLOG(Event, Fatal) << \"Unable to create eventfd\";\n>  }\n>  \n>  EventDispatcherPoll::~EventDispatcherPoll()\n>  {\n> +\tclose(eventfd_);\n>  }\n>  \n>  void EventDispatcherPoll::registerEventNotifier(EventNotifier *notifier)\n> @@ -123,11 +134,13 @@ void EventDispatcherPoll::processEvents()\n>  \n>  \t/* Create the pollfd array. */\n>  \tstd::vector<struct pollfd> pollfds;\n> -\tpollfds.reserve(notifiers_.size());\n> +\tpollfds.reserve(notifiers_.size() + 1);\n>  \n>  \tfor (auto notifier : notifiers_)\n>  \t\tpollfds.push_back({ notifier.first, notifier.second.events(), 0 });\n>  \n> +\tpollfds.push_back({ eventfd_, POLLIN, 0 });\n> +\n>  \t/* Wait for events and process notifiers and timers. */\n>  \tdo {\n>  \t\tret = poll(&pollfds);\n> @@ -137,12 +150,20 @@ void EventDispatcherPoll::processEvents()\n>  \t\tret = -errno;\n>  \t\tLOG(Event, Warning) << \"poll() failed with \" << strerror(-ret);\n>  \t} else if (ret > 0) {\n> +\t\tprocessInterrupt(pollfds.back());\n> +\t\tpollfds.pop_back();\n>  \t\tprocessNotifiers(pollfds);\n>  \t}\n>  \n>  \tprocessTimers();\n>  }\n>  \n> +void EventDispatcherPoll::interrupt()\n> +{\n> +\tuint64_t value = 1;\n> +\twrite(eventfd_, &value, sizeof(value));\n> +}\n> +\n>  short EventDispatcherPoll::EventNotifierSetPoll::events() const\n>  {\n>  \tshort events = 0;\n> @@ -186,6 +207,15 @@ int EventDispatcherPoll::poll(std::vector<struct pollfd> *pollfds)\n>  \t\t     nextTimer ? &timeout : nullptr, nullptr);\n>  }\n>  \n> +void EventDispatcherPoll::processInterrupt(const struct pollfd &pfd)\n> +{\n> +\tif (!pfd.revents & POLLIN)\n> +\t\treturn;\n> +\n> +\tuint64_t value;\n> +\tread(eventfd_, &value, sizeof(value));\n\nShould we check that the value read was expected?\n\nI guess this could be expanded upon to use an events bitfield or enum to\nactually pass meaningful messages too.\n\nI'm not sure what those event messages would be yet - so I don't think\nwe need to implement without a use-case.\n\n--\nRegards\n\nKieran\n\n\n> +}\n> +\n>  void EventDispatcherPoll::processNotifiers(const std::vector<struct pollfd> &pollfds)\n>  {\n>  \tstatic const struct {\n> diff --git a/src/libcamera/include/event_dispatcher_poll.h b/src/libcamera/include/event_dispatcher_poll.h\n> index ac3efde082b4..1c0066c24dc8 100644\n> --- a/src/libcamera/include/event_dispatcher_poll.h\n> +++ b/src/libcamera/include/event_dispatcher_poll.h\n> @@ -31,6 +31,7 @@ public:\n>  \tvoid unregisterTimer(Timer *timer);\n>  \n>  \tvoid processEvents();\n> +\tvoid interrupt();\n>  \n>  private:\n>  \tstruct EventNotifierSetPoll {\n> @@ -40,8 +41,10 @@ private:\n>  \n>  \tstd::map<int, EventNotifierSetPoll> notifiers_;\n>  \tstd::list<Timer *> timers_;\n> +\tint eventfd_;\n>  \n>  \tint poll(std::vector<struct pollfd> *pollfds);\n> +\tvoid processInterrupt(const struct pollfd &pfd);\n>  \tvoid processNotifiers(const std::vector<struct pollfd> &pollfds);\n>  \tvoid processTimers();\n>  };\n>","headers":{"Return-Path":"<kieran.bingham@ideasonboard.com>","Received":["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 91EA560C7D\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 23 Jan 2019 12:43:24 +0100 (CET)","from [192.168.0.21]\n\t(cpc89242-aztw30-2-0-cust488.18-1.cable.virginm.net [86.31.129.233])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id E785723D;\n\tWed, 23 Jan 2019 12:43:23 +0100 (CET)"],"DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1548243804;\n\tbh=DWUwMOfjeWBICZ2ijplbBbCFG1qIU8um3gZLp7RiIUc=;\n\th=Reply-To:Subject:To:References:From:Date:In-Reply-To:From;\n\tb=rQgFukHr2QbhW0VR/LJcRvJXyfe2gQa69lLDqxu84gPk5kS2e/9HWcoWoCJS/Dv4u\n\tz/ea8yuv1LzuarBKnYMSRadNP1A4SjTlCqdSDw1UojuMPQ/gLqDKXmx/P3FnriFRL/\n\t86C//ZO9D5TFaWKFyeTbH4Xp6V3toLJ3Ll9IpZYY=","Reply-To":"kieran.bingham@ideasonboard.com","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>,\n\tlibcamera-devel@lists.libcamera.org","References":"<20190123085923.12524-1-laurent.pinchart@ideasonboard.com>\n\t<20190123085923.12524-4-laurent.pinchart@ideasonboard.com>","From":"Kieran Bingham <kieran.bingham@ideasonboard.com>","Openpgp":"preference=signencrypt","Autocrypt":"addr=kieran.bingham@ideasonboard.com; keydata=\n\t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\n\tsbsRB8KNNvVXBOVNwko86rQqF9drZuw=","Organization":"Ideas on Board","Message-ID":"<98105b45-e869-7fb7-27f0-6d3f9660170e@ideasonboard.com>","Date":"Wed, 23 Jan 2019 11:43:21 +0000","User-Agent":"Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101\n\tThunderbird/60.2.1","MIME-Version":"1.0","In-Reply-To":"<20190123085923.12524-4-laurent.pinchart@ideasonboard.com>","Content-Type":"text/plain; charset=utf-8","Content-Language":"en-GB","Content-Transfer-Encoding":"8bit","Subject":"Re: [libcamera-devel] [PATCH 3/4] libcamera: event_dispatcher: Add\n\tinterrupt() function","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.23","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>","X-List-Received-Date":"Wed, 23 Jan 2019 11:43:24 -0000"}},{"id":545,"web_url":"https://patchwork.libcamera.org/comment/545/","msgid":"<20190123164822.GI31885@pendragon.ideasonboard.com>","date":"2019-01-23T16:48:22","subject":"Re: [libcamera-devel] [PATCH 3/4] libcamera: event_dispatcher: Add\n\tinterrupt() function","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"Hi Kieran,\n\nOn Wed, Jan 23, 2019 at 11:43:21AM +0000, Kieran Bingham wrote:\n> On 23/01/2019 08:59, Laurent Pinchart wrote:\n> > The new interrupt() function allows interrupting in-progress blocking\n> > processEvents() calls. This is useful to stop running event loops.\n> \n> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n> \n> > Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n> > ---\n> >  include/libcamera/event_dispatcher.h          |  2 ++\n> >  src/libcamera/event_dispatcher.cpp            | 10 ++++++\n> >  src/libcamera/event_dispatcher_poll.cpp       | 32 ++++++++++++++++++-\n> >  src/libcamera/include/event_dispatcher_poll.h |  3 ++\n> >  4 files changed, 46 insertions(+), 1 deletion(-)\n> > \n> > diff --git a/include/libcamera/event_dispatcher.h b/include/libcamera/event_dispatcher.h\n> > index c20518c6866d..cb06bf208e12 100644\n> > --- a/include/libcamera/event_dispatcher.h\n> > +++ b/include/libcamera/event_dispatcher.h\n> > @@ -26,6 +26,8 @@ public:\n> >  \tvirtual void unregisterTimer(Timer *timer) = 0;\n> >  \n> >  \tvirtual void processEvents() = 0;\n> > +\n> > +\tvirtual void interrupt() = 0;\n> >  };\n> >  \n> >  } /* namespace libcamera */\n> > diff --git a/src/libcamera/event_dispatcher.cpp b/src/libcamera/event_dispatcher.cpp\n> > index f7c40734095e..b82c59c3f5dc 100644\n> > --- a/src/libcamera/event_dispatcher.cpp\n> > +++ b/src/libcamera/event_dispatcher.cpp\n> > @@ -104,4 +104,14 @@ EventDispatcher::~EventDispatcher()\n> >   * it before returning.\n> >   */\n> >  \n> > +/**\n> > + * \\fn EventDispatcher::interrupt()\n> > + * \\brief Interrupt any running processEvents() call as soon as possible\n> > + *\n> > + * Calling this function interrupts any blocking processEvents() call in\n> > + * progress. The processEvents() function will return as soon as possible,\n> > + * after processing pending timers and events. If processEvents() isn't in\n> > + * progress, it will be interrupted immediately the next time it gets called.\n> > + */\n> > +\n> >  } /* namespace libcamera */\n> > diff --git a/src/libcamera/event_dispatcher_poll.cpp b/src/libcamera/event_dispatcher_poll.cpp\n> > index 6e0609c34ddc..a2674ab31135 100644\n> > --- a/src/libcamera/event_dispatcher_poll.cpp\n> > +++ b/src/libcamera/event_dispatcher_poll.cpp\n> > @@ -8,7 +8,10 @@\n> >  #include <algorithm>\n> >  #include <iomanip>\n> >  #include <poll.h>\n> > +#include <stdint.h>\n> >  #include <string.h>\n> > +#include <sys/eventfd.h>\n> > +#include <unistd.h>\n> >  \n> >  #include <libcamera/event_notifier.h>\n> >  #include <libcamera/timer.h>\n> > @@ -43,10 +46,18 @@ static const char *notifierType(EventNotifier::Type type)\n> >  \n> >  EventDispatcherPoll::EventDispatcherPoll()\n> >  {\n> > +\t/*\n> > +\t * Create the event fd. Failures are fatal as we can't implement an\n> > +\t * interruptible dispatcher without the fd.\n> > +\t */\n> > +\teventfd_ = eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK);\n> \n> Hrm ... I didn't know about eventfd. I'd always used a pair of pipes.\n> \n> Every day's a school day :)\n> \n> The man page says it's linux-specific - but I think we're OK with that :-)\n\nWhen we'll start supporting other operating systems we'll abstract this\nin a class :-)\n\n> > +\tif (eventfd_ < 0)\n> > +\t\tLOG(Event, Fatal) << \"Unable to create eventfd\";\n> >  }\n> >  \n> >  EventDispatcherPoll::~EventDispatcherPoll()\n> >  {\n> > +\tclose(eventfd_);\n> >  }\n> >  \n> >  void EventDispatcherPoll::registerEventNotifier(EventNotifier *notifier)\n> > @@ -123,11 +134,13 @@ void EventDispatcherPoll::processEvents()\n> >  \n> >  \t/* Create the pollfd array. */\n> >  \tstd::vector<struct pollfd> pollfds;\n> > -\tpollfds.reserve(notifiers_.size());\n> > +\tpollfds.reserve(notifiers_.size() + 1);\n> >  \n> >  \tfor (auto notifier : notifiers_)\n> >  \t\tpollfds.push_back({ notifier.first, notifier.second.events(), 0 });\n> >  \n> > +\tpollfds.push_back({ eventfd_, POLLIN, 0 });\n> > +\n> >  \t/* Wait for events and process notifiers and timers. */\n> >  \tdo {\n> >  \t\tret = poll(&pollfds);\n> > @@ -137,12 +150,20 @@ void EventDispatcherPoll::processEvents()\n> >  \t\tret = -errno;\n> >  \t\tLOG(Event, Warning) << \"poll() failed with \" << strerror(-ret);\n> >  \t} else if (ret > 0) {\n> > +\t\tprocessInterrupt(pollfds.back());\n> > +\t\tpollfds.pop_back();\n> >  \t\tprocessNotifiers(pollfds);\n> >  \t}\n> >  \n> >  \tprocessTimers();\n> >  }\n> >  \n> > +void EventDispatcherPoll::interrupt()\n> > +{\n> > +\tuint64_t value = 1;\n> > +\twrite(eventfd_, &value, sizeof(value));\n> > +}\n> > +\n> >  short EventDispatcherPoll::EventNotifierSetPoll::events() const\n> >  {\n> >  \tshort events = 0;\n> > @@ -186,6 +207,15 @@ int EventDispatcherPoll::poll(std::vector<struct pollfd> *pollfds)\n> >  \t\t     nextTimer ? &timeout : nullptr, nullptr);\n> >  }\n> >  \n> > +void EventDispatcherPoll::processInterrupt(const struct pollfd &pfd)\n> > +{\n> > +\tif (!pfd.revents & POLLIN)\n> > +\t\treturn;\n> > +\n> > +\tuint64_t value;\n> > +\tread(eventfd_, &value, sizeof(value));\n> \n> Should we check that the value read was expected?\n> \n> I guess this could be expanded upon to use an events bitfield or enum to\n> actually pass meaningful messages too.\n> \n> I'm not sure what those event messages would be yet - so I don't think\n> we need to implement without a use-case.\n\neventfd creates an internal counter, initialized to 0. The write() call\nadds the value of the data to the internal counter, and the read() call\nreturns the value of the counter and resets if to 0. The poll() call\nwill block until the counter is non-zero. I don't think there's anything\nmeaningful we could do we the read value here.\n\n> > +}\n> > +\n> >  void EventDispatcherPoll::processNotifiers(const std::vector<struct pollfd> &pollfds)\n> >  {\n> >  \tstatic const struct {\n> > diff --git a/src/libcamera/include/event_dispatcher_poll.h b/src/libcamera/include/event_dispatcher_poll.h\n> > index ac3efde082b4..1c0066c24dc8 100644\n> > --- a/src/libcamera/include/event_dispatcher_poll.h\n> > +++ b/src/libcamera/include/event_dispatcher_poll.h\n> > @@ -31,6 +31,7 @@ public:\n> >  \tvoid unregisterTimer(Timer *timer);\n> >  \n> >  \tvoid processEvents();\n> > +\tvoid interrupt();\n> >  \n> >  private:\n> >  \tstruct EventNotifierSetPoll {\n> > @@ -40,8 +41,10 @@ private:\n> >  \n> >  \tstd::map<int, EventNotifierSetPoll> notifiers_;\n> >  \tstd::list<Timer *> timers_;\n> > +\tint eventfd_;\n> >  \n> >  \tint poll(std::vector<struct pollfd> *pollfds);\n> > +\tvoid processInterrupt(const struct pollfd &pfd);\n> >  \tvoid processNotifiers(const std::vector<struct pollfd> &pollfds);\n> >  \tvoid processTimers();\n> >  };","headers":{"Return-Path":"<laurent.pinchart@ideasonboard.com>","Received":["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 1B30B60B2D\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 23 Jan 2019 17:48:24 +0100 (CET)","from pendragon.ideasonboard.com\n\t(dfj612yhrgyx302h3jwwy-3.rev.dnainternet.fi\n\t[IPv6:2001:14ba:21f5:5b00:ce28:277f:58d7:3ca4])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 82DDA23D;\n\tWed, 23 Jan 2019 17:48:23 +0100 (CET)"],"DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1548262103;\n\tbh=EV/c0VHbmIFOgrLyxGIUIECKmS8aH2RPp0mWdONDh5c=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=l571+ySB3wWuXV9aGWUYxN8On8tDEzMByTkgg6qS5gVbgR9uff6ObldK+xeRixdtR\n\t9z1OF49K6IUlurrHM4D/hNUnISo1cC1qzlJ8fjb2KAUNXgRd0A32JNiPriSo4dfm5q\n\tXqefzuvQH8L4rk0HBbTrJuMNYR2oDXERFusYYv3g=","Date":"Wed, 23 Jan 2019 18:48:22 +0200","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"Kieran Bingham <kieran.bingham@ideasonboard.com>","Cc":"libcamera-devel@lists.libcamera.org","Message-ID":"<20190123164822.GI31885@pendragon.ideasonboard.com>","References":"<20190123085923.12524-1-laurent.pinchart@ideasonboard.com>\n\t<20190123085923.12524-4-laurent.pinchart@ideasonboard.com>\n\t<98105b45-e869-7fb7-27f0-6d3f9660170e@ideasonboard.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","In-Reply-To":"<98105b45-e869-7fb7-27f0-6d3f9660170e@ideasonboard.com>","User-Agent":"Mutt/1.10.1 (2018-07-13)","Subject":"Re: [libcamera-devel] [PATCH 3/4] libcamera: event_dispatcher: Add\n\tinterrupt() function","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.23","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>","X-List-Received-Date":"Wed, 23 Jan 2019 16:48:24 -0000"}}]