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:
parent
54055dd0c2
commit
234eb60546
2 changed files with 25 additions and 28 deletions
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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();
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue