Message ID | 20250130115001.1129305-7-pobrn@protonmail.com |
---|---|
State | New |
Headers | show |
Series |
|
Related | show |
Hi Barnabás On Thu, Jan 30, 2025 at 11:50:32AM +0000, Barnabás Pőcze wrote: > Store a cookie value of `std::uintptr_t` with the callback to > make later cancellation of the callback possible. > > Signed-off-by: Barnabás Pőcze <pobrn@protonmail.com> > --- > src/apps/common/event_loop.cpp | 18 ++++++++++++++---- > src/apps/common/event_loop.h | 6 ++++-- > 2 files changed, 18 insertions(+), 6 deletions(-) > > diff --git a/src/apps/common/event_loop.cpp b/src/apps/common/event_loop.cpp > index b6230f4ba..0d7a4a024 100644 > --- a/src/apps/common/event_loop.cpp > +++ b/src/apps/common/event_loop.cpp > @@ -10,6 +10,7 @@ > #include <assert.h> > #include <event2/event.h> > #include <event2/thread.h> > +#include <algorithm> > #include <iostream> > > EventLoop *EventLoop::instance_ = nullptr; > @@ -33,7 +34,7 @@ EventLoop::EventLoop() > if (self->calls_.empty()) > break; > > - call = std::move(self->calls_.front()); > + call = std::move(self->calls_.front().first); > self->calls_.pop_front(); > } > > @@ -73,16 +74,25 @@ void EventLoop::exit(int code) > event_base_loopbreak(base_); > } > > -void EventLoop::callLater(std::function<void()> &&func) > +void EventLoop::callLater(std::function<void()> &&func, std::optional<std::uintptr_t> cookie) Is this a good idea to make cookie optional ? As far as I can see !cookie means all pending callbacks are deleted > { > { > - std::unique_lock<std::mutex> locker(lock_); > - calls_.push_back(std::move(func)); > + std::lock_guard locker(lock_); > + calls_.emplace_back(std::move(func), cookie); > } > > event_active(callsTrigger_, 0, 0); > } > > +void EventLoop::cancelLater(std::optional<std::uintptr_t> cookie) > +{ > + std::lock_guard locker(lock_); > + > + calls_.erase(std::remove_if(calls_.begin(), calls_.end(), > + [&](const auto &x) { return !cookie || x.second == *cookie; }), Can x.second be invalid ? I guess so looking at the call of src/apps/cam/camera_session.cpp: EventLoop::instance()->callLater([this, request]() { processRequest(request); }); Making the cookie (which is a reference to the caller, that's it) mandatory would make the code simpler ? Also why do you need to dereference cookie here ? Can't you just compare the two optional<> ? Thanks j > + calls_.end()); > +} > + > void EventLoop::addFdEvent(int fd, EventType type, > std::function<void()> &&callback) > { > diff --git a/src/apps/common/event_loop.h b/src/apps/common/event_loop.h > index 507023996..6d7d0497a 100644 > --- a/src/apps/common/event_loop.h > +++ b/src/apps/common/event_loop.h > @@ -13,6 +13,7 @@ > #include <list> > #include <memory> > #include <mutex> > +#include <optional> > > #include <libcamera/base/class.h> > > @@ -36,7 +37,8 @@ public: > int exec(); > void exit(int code = 0); > > - void callLater(std::function<void()> &&func); > + void callLater(std::function<void()> &&func, std::optional<std::uintptr_t> cookie = {}); > + void cancelLater(std::optional<std::uintptr_t> cookie = {}); > > void addFdEvent(int fd, EventType type, > std::function<void()> &&handler); > @@ -63,7 +65,7 @@ private: > struct event_base *base_; > int exitCode_; > > - std::deque<std::function<void()>> calls_; > + std::deque<std::pair<std::function<void()>, std::optional<std::uintptr_t>>> calls_; > ::event *callsTrigger_ = nullptr; > > std::list<std::unique_ptr<Event>> events_; > -- > 2.48.1 > >
diff --git a/src/apps/common/event_loop.cpp b/src/apps/common/event_loop.cpp index b6230f4ba..0d7a4a024 100644 --- a/src/apps/common/event_loop.cpp +++ b/src/apps/common/event_loop.cpp @@ -10,6 +10,7 @@ #include <assert.h> #include <event2/event.h> #include <event2/thread.h> +#include <algorithm> #include <iostream> EventLoop *EventLoop::instance_ = nullptr; @@ -33,7 +34,7 @@ EventLoop::EventLoop() if (self->calls_.empty()) break; - call = std::move(self->calls_.front()); + call = std::move(self->calls_.front().first); self->calls_.pop_front(); } @@ -73,16 +74,25 @@ void EventLoop::exit(int code) event_base_loopbreak(base_); } -void EventLoop::callLater(std::function<void()> &&func) +void EventLoop::callLater(std::function<void()> &&func, std::optional<std::uintptr_t> cookie) { { - std::unique_lock<std::mutex> locker(lock_); - calls_.push_back(std::move(func)); + std::lock_guard locker(lock_); + calls_.emplace_back(std::move(func), cookie); } event_active(callsTrigger_, 0, 0); } +void EventLoop::cancelLater(std::optional<std::uintptr_t> cookie) +{ + std::lock_guard locker(lock_); + + calls_.erase(std::remove_if(calls_.begin(), calls_.end(), + [&](const auto &x) { return !cookie || x.second == *cookie; }), + calls_.end()); +} + void EventLoop::addFdEvent(int fd, EventType type, std::function<void()> &&callback) { diff --git a/src/apps/common/event_loop.h b/src/apps/common/event_loop.h index 507023996..6d7d0497a 100644 --- a/src/apps/common/event_loop.h +++ b/src/apps/common/event_loop.h @@ -13,6 +13,7 @@ #include <list> #include <memory> #include <mutex> +#include <optional> #include <libcamera/base/class.h> @@ -36,7 +37,8 @@ public: int exec(); void exit(int code = 0); - void callLater(std::function<void()> &&func); + void callLater(std::function<void()> &&func, std::optional<std::uintptr_t> cookie = {}); + void cancelLater(std::optional<std::uintptr_t> cookie = {}); void addFdEvent(int fd, EventType type, std::function<void()> &&handler); @@ -63,7 +65,7 @@ private: struct event_base *base_; int exitCode_; - std::deque<std::function<void()>> calls_; + std::deque<std::pair<std::function<void()>, std::optional<std::uintptr_t>>> calls_; ::event *callsTrigger_ = nullptr; std::list<std::unique_ptr<Event>> events_;
Store a cookie value of `std::uintptr_t` with the callback to make later cancellation of the callback possible. Signed-off-by: Barnabás Pőcze <pobrn@protonmail.com> --- src/apps/common/event_loop.cpp | 18 ++++++++++++++---- src/apps/common/event_loop.h | 6 ++++-- 2 files changed, 18 insertions(+), 6 deletions(-)