apps: common: event_loop: Use single event source for deferred calls

Instead of calling `event_base_once()` every time a deferred call
is added to the loop, create an event source at construction, and
simply trigger that when a new deferred call is scheduled.

Signed-off-by: Barnabás Pőcze <pobrn@protonmail.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
This commit is contained in:
Barnabás Pőcze 2025-01-14 16:42:31 +01:00
parent 54055dd0c2
commit 234eb60546
2 changed files with 25 additions and 28 deletions

View file

@ -21,12 +21,35 @@ EventLoop::EventLoop()
evthread_use_pthreads();
base_ = event_base_new();
instance_ = this;
callsTrigger_ = event_new(base_, -1, EV_PERSIST, [](evutil_socket_t, short, void *closure) {
auto *self = static_cast<EventLoop *>(closure);
for (;;) {
std::function<void()> call;
{
std::lock_guard locker(self->lock_);
if (self->calls_.empty())
break;
call = std::move(self->calls_.front());
self->calls_.pop_front();
}
call();
}
}, this);
assert(callsTrigger_);
event_add(callsTrigger_, nullptr);
}
EventLoop::~EventLoop()
{
instance_ = nullptr;
event_free(callsTrigger_);
events_.clear();
event_base_free(base_);
libevent_global_shutdown();
@ -57,7 +80,7 @@ void EventLoop::callLater(std::function<void()> &&func)
calls_.push_back(std::move(func));
}
event_base_once(base_, -1, EV_TIMEOUT, dispatchCallback, this, nullptr);
event_active(callsTrigger_, 0, 0);
}
void EventLoop::addFdEvent(int fd, EventType type,
@ -108,29 +131,6 @@ void EventLoop::addTimerEvent(const std::chrono::microseconds period,
events_.push_back(std::move(event));
}
void EventLoop::dispatchCallback([[maybe_unused]] evutil_socket_t fd,
[[maybe_unused]] short flags, void *param)
{
EventLoop *loop = static_cast<EventLoop *>(param);
loop->dispatchCall();
}
void EventLoop::dispatchCall()
{
std::function<void()> call;
{
std::unique_lock<std::mutex> locker(lock_);
if (calls_.empty())
return;
call = calls_.front();
calls_.pop_front();
}
call();
}
EventLoop::Event::Event(std::function<void()> &&callback)
: callback_(std::move(callback)), event_(nullptr)
{

View file

@ -65,11 +65,8 @@ private:
int exitCode_;
std::deque<std::function<void()>> calls_;
struct event *callsTrigger_ = nullptr;
std::list<std::unique_ptr<Event>> events_;
std::mutex lock_;
static void dispatchCallback(evutil_socket_t fd, short flags,
void *param);
void dispatchCall();
};