summaryrefslogtreecommitdiff
path: root/src/cam/event_loop.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/cam/event_loop.cpp')
-rw-r--r--src/cam/event_loop.cpp67
1 files changed, 55 insertions, 12 deletions
diff --git a/src/cam/event_loop.cpp b/src/cam/event_loop.cpp
index e8ab8617..6a4c47f2 100644
--- a/src/cam/event_loop.cpp
+++ b/src/cam/event_loop.cpp
@@ -5,35 +5,78 @@
* event_loop.cpp - cam - Event loop
*/
-#include <libcamera/event_dispatcher.h>
-
#include "event_loop.h"
-using namespace libcamera;
+#include <assert.h>
+#include <event2/event.h>
+#include <event2/thread.h>
+
+EventLoop *EventLoop::instance_ = nullptr;
-EventLoop::EventLoop(EventDispatcher *dispatcher)
- : dispatcher_(dispatcher)
+EventLoop::EventLoop()
{
+ assert(!instance_);
+
+ evthread_use_pthreads();
+ base_ = event_base_new();
+ instance_ = this;
}
EventLoop::~EventLoop()
{
+ instance_ = nullptr;
+
+ event_base_free(base_);
+ libevent_global_shutdown();
+}
+
+EventLoop *EventLoop::instance()
+{
+ return instance_;
}
int EventLoop::exec()
{
exitCode_ = -1;
- exit_.store(false, std::memory_order_release);
-
- while (!exit_.load(std::memory_order_acquire))
- dispatcher_->processEvents();
-
+ 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);
- dispatcher_->interrupt();
+ event_base_loopbreak(base_);
+}
+
+void EventLoop::callLater(const std::function<void()> &func)
+{
+ {
+ std::unique_lock<std::mutex> locker(lock_);
+ calls_.push_back(func);
+ }
+
+ event_base_once(base_, -1, EV_TIMEOUT, dispatchCallback, this, nullptr);
+}
+
+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();
}