[libcamera-devel] [PATCH v2 1/8] cam: event_loop: Add support for file descriptor events
Laurent Pinchart
laurent.pinchart at ideasonboard.com
Tue Aug 3 12:43:15 CEST 2021
Hi Kieran,
On Tue, Aug 03, 2021 at 11:35:34AM +0100, Kieran Bingham wrote:
> Hi Laurent,
Yes ? :-)
> On 30/07/2021 02:02, Laurent Pinchart wrote:
> > Extend the EventLoop class to support watching file descriptors for
> > read and write events.
> >
> > Signed-off-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
> > ---
> > src/cam/event_loop.cpp | 44 ++++++++++++++++++++++++++++++++++++++++++
> > src/cam/event_loop.h | 20 +++++++++++++++++++
> > 2 files changed, 64 insertions(+)
> >
> > diff --git a/src/cam/event_loop.cpp b/src/cam/event_loop.cpp
> > index 6a4c47f287d0..e25784c083cf 100644
> > --- a/src/cam/event_loop.cpp
> > +++ b/src/cam/event_loop.cpp
> > @@ -10,6 +10,7 @@
> > #include <assert.h>
> > #include <event2/event.h>
> > #include <event2/thread.h>
> > +#include <iostream>
> >
> > EventLoop *EventLoop::instance_ = nullptr;
> >
> > @@ -26,6 +27,7 @@ EventLoop::~EventLoop()
> > {
> > instance_ = nullptr;
> >
> > + events_.clear();
> > event_base_free(base_);
> > libevent_global_shutdown();
> > }
> > @@ -58,6 +60,30 @@ void EventLoop::callLater(const std::function<void()> &func)
> > event_base_once(base_, -1, EV_TIMEOUT, dispatchCallback, this, nullptr);
> > }
> >
> > +void EventLoop::addEvent(int fd, EventType type,
> > + const std::function<void()> &callback)
> > +{
> > + std::unique_ptr<Event> event = std::make_unique<Event>(callback);
> > + short events = (type & Read ? EV_READ : 0)
> > + | (type & Write ? EV_WRITE : 0)
> > + | EV_PERSIST;
> > +
> > + event->event_ = event_new(base_, fd, events, &EventLoop::Event::dispatch,
> > + event.get());
> > + if (!event->event_) {
> > + std::cerr << "Failed to create event for fd " << fd << std::endl;
> > + return;
> > + }
> > +
> > + int ret = event_add(event->event_, nullptr);
> > + if (ret < 0) {
> > + std::cerr << "Failed to add event for fd " << fd << std::endl;
> > + return;
> > + }
> > +
> > + events_.push_back(std::move(event));
> > +}
> > +
> > void EventLoop::dispatchCallback([[maybe_unused]] evutil_socket_t fd,
> > [[maybe_unused]] short flags, void *param)
> > {
> > @@ -80,3 +106,21 @@ void EventLoop::dispatchCall()
> >
> > call();
> > }
> > +
> > +EventLoop::Event::Event(const std::function<void()> &callback)
> > + : callback_(callback), event_(nullptr)
> > +{
> > +}
> > +
> > +EventLoop::Event::~Event()
> > +{
> > + event_del(event_);
> > + event_free(event_);
> > +}
> > +
> > +void EventLoop::Event::dispatch([[maybe_unused]] int fd,
> > + [[maybe_unused]] short events, void *arg)
> > +{
> > + Event *event = static_cast<Event *>(arg);
> > + event->callback_();
> > +}
> > diff --git a/src/cam/event_loop.h b/src/cam/event_loop.h
> > index ba3ba3a4a675..57bb6fb34aa7 100644
> > --- a/src/cam/event_loop.h
> > +++ b/src/cam/event_loop.h
> > @@ -8,6 +8,7 @@
> > #define __CAM_EVENT_LOOP_H__
> >
> > #include <functional>
> > +#include <memory>
> > #include <list>
> > #include <mutex>
> >
> > @@ -18,6 +19,11 @@ struct event_base;
> > class EventLoop
> > {
> > public:
> > + enum EventType {
> > + Read = 1,
> > + Write = 2,
> > + };
> > +
> > EventLoop();
> > ~EventLoop();
> >
> > @@ -28,13 +34,27 @@ public:
> >
> > void callLater(const std::function<void()> &func);
> >
> > + void addEvent(int fd, EventType type,
> > + const std::function<void()> &handler);
> > +
> > private:
> > + struct Event {
> > + Event(const std::function<void()> &callback);
> > + ~Event();
> > +
> > + static void dispatch(int fd, short events, void *arg);
> > +
> > + std::function<void()> callback_;
> > + struct event *event_;
> > + };
> > +
> > static EventLoop *instance_;
> >
> > struct event_base *base_;
> > int exitCode_;
> >
> > std::list<std::function<void()>> calls_;
> > + std::list<std::unique_ptr<Event>> events_;
> > std::mutex lock_;
> >
> > static void dispatchCallback(evutil_socket_t fd, short flags,
> >
--
Regards,
Laurent Pinchart
More information about the libcamera-devel
mailing list