[RFC PATCH v3 04/21] apps: common: event_loop: Use single event source for deferred calls
Jacopo Mondi
jacopo.mondi at ideasonboard.com
Mon Feb 3 20:25:27 CET 2025
Hi Barnabás
On Thu, Jan 30, 2025 at 11:50:23AM +0000, Barnabás Pőcze wrote:
> 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 at protonmail.com>
Sorry, I've not replied to the previous version.
Now that I understand it better I really like this
Reviewed-by: Jacopo Mondi <jacopo.mondi at ideasonboard.com>
> ---
> src/apps/common/event_loop.cpp | 48 +++++++++++++++++-----------------
> src/apps/common/event_loop.h | 5 +---
> 2 files changed, 25 insertions(+), 28 deletions(-)
>
> diff --git a/src/apps/common/event_loop.cpp b/src/apps/common/event_loop.cpp
> index bc8cf17ab..b6230f4ba 100644
> --- a/src/apps/common/event_loop.cpp
> +++ b/src/apps/common/event_loop.cpp
> @@ -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)
> {
> diff --git a/src/apps/common/event_loop.h b/src/apps/common/event_loop.h
> index 760075885..aac5ed3cc 100644
> --- a/src/apps/common/event_loop.h
> +++ b/src/apps/common/event_loop.h
> @@ -65,11 +65,8 @@ private:
> int exitCode_;
>
> std::deque<std::function<void()>> calls_;
> + ::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();
> };
> --
> 2.48.1
>
>
More information about the libcamera-devel
mailing list