Message ID | 20210730010306.19956-2-laurent.pinchart@ideasonboard.com |
---|---|
State | Accepted |
Headers | show |
Series |
|
Related | show |
Hi Laurent, Thanks for your work. On 2021-07-30 04:02:59 +0300, Laurent Pinchart wrote: > Extend the EventLoop class to support watching file descriptors for > read and write events. > > Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se> > --- > 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 >
Hi Laurent, On Fri, Jul 30, 2021 at 04:02:59AM +0300, Laurent Pinchart wrote: > Extend the EventLoop class to support watching file descriptors for > read and write events. > > Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Paul Elder <paul.elder@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 >
Hi Laurent, 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@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, >
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@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, > >
On 03/08/2021 11:43, Laurent Pinchart wrote: > Hi Kieran, > > On Tue, Aug 03, 2021 at 11:35:34AM +0100, Kieran Bingham wrote: >> Hi Laurent, > > Yes ? :-) Agreed. ... ;-) > >> 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@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@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, >>> >
Hi Laurent, On 7/30/21 6:32 AM, Laurent Pinchart wrote: > Extend the EventLoop class to support watching file descriptors for > read and write events. > > Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Umang Jain <umang.jain@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,
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,
Extend the EventLoop class to support watching file descriptors for read and write events. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> --- src/cam/event_loop.cpp | 44 ++++++++++++++++++++++++++++++++++++++++++ src/cam/event_loop.h | 20 +++++++++++++++++++ 2 files changed, 64 insertions(+)