diff --git a/src/cam/event_loop.cpp b/src/cam/event_loop.cpp index 3a2b665a..6a4c47f2 100644 --- a/src/cam/event_loop.cpp +++ b/src/cam/event_loop.cpp @@ -38,25 +38,13 @@ EventLoop *EventLoop::instance() int EventLoop::exec() { exitCode_ = -1; - exit_.store(false, std::memory_order_release); - - while (!exit_.load(std::memory_order_acquire)) { - dispatchCalls(); - event_base_loop(base_, EVLOOP_NO_EXIT_ON_EMPTY); - } - + event_base_loop(base_, EVLOOP_NO_EXIT_ON_EMPTY); return exitCode_; } void EventLoop::exit(int code) { exitCode_ = code; - exit_.store(true, std::memory_order_release); - interrupt(); -} - -void EventLoop::interrupt() -{ event_base_loopbreak(base_); } @@ -67,20 +55,28 @@ void EventLoop::callLater(const std::function &func) calls_.push_back(func); } - interrupt(); + event_base_once(base_, -1, EV_TIMEOUT, dispatchCallback, this, nullptr); } -void EventLoop::dispatchCalls() +void EventLoop::dispatchCallback([[maybe_unused]] evutil_socket_t fd, + [[maybe_unused]] short flags, void *param) { - std::unique_lock locker(lock_); - - for (auto iter = calls_.begin(); iter != calls_.end(); ) { - std::function call = std::move(*iter); - - iter = calls_.erase(iter); - - locker.unlock(); - call(); - locker.lock(); - } + EventLoop *loop = static_cast(param); + loop->dispatchCall(); +} + +void EventLoop::dispatchCall() +{ + std::function call; + + { + std::unique_lock locker(lock_); + if (calls_.empty()) + return; + + call = calls_.front(); + calls_.pop_front(); + } + + call(); } diff --git a/src/cam/event_loop.h b/src/cam/event_loop.h index d0d5b5a5..ba3ba3a4 100644 --- a/src/cam/event_loop.h +++ b/src/cam/event_loop.h @@ -7,11 +7,12 @@ #ifndef __CAM_EVENT_LOOP_H__ #define __CAM_EVENT_LOOP_H__ -#include #include #include #include +#include + struct event_base; class EventLoop @@ -31,14 +32,14 @@ private: static EventLoop *instance_; struct event_base *base_; - std::atomic exit_; int exitCode_; std::list> calls_; std::mutex lock_; - void interrupt(); - void dispatchCalls(); + static void dispatchCallback(evutil_socket_t fd, short flags, + void *param); + void dispatchCall(); }; #endif /* __CAM_EVENT_LOOP_H__ */