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>
This commit is contained in:
Laurent Pinchart
2020-11-13 06:14:49 +02:00
parent 2c18ebb859
commit cb45af8a9e
2 changed files with 64 additions and 0 deletions
+44
View File
@@ -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_();
}