summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart@ideasonboard.com>2020-11-13 06:14:49 +0200
committerLaurent Pinchart <laurent.pinchart@ideasonboard.com>2021-08-05 16:23:10 +0300
commitcb45af8a9eba68a0da2fa9435a4ce82bbdf80f50 (patch)
tree87ee467771be1f4e3e2abc51e9decfc4b2c25578
parent2c18ebb859f54a5f6e620aebc6f3abf3648b7462 (diff)
cam: event_loop: Add support for file descriptor events
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> Reviewed-by: Paul Elder <paul.elder@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Reviewed-by: Umang Jain <umang.jain@ideasonboard.com>
-rw-r--r--src/cam/event_loop.cpp44
-rw-r--r--src/cam/event_loop.h20
2 files changed, 64 insertions, 0 deletions
diff --git a/src/cam/event_loop.cpp b/src/cam/event_loop.cpp
index 6a4c47f2..e25784c0 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 ba3ba3a4..57bb6fb3 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,