diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/event/Loop.cxx | 18 | ||||
-rw-r--r-- | src/event/Loop.hxx | 8 |
2 files changed, 24 insertions, 2 deletions
diff --git a/src/event/Loop.cxx b/src/event/Loop.cxx index 0e76afc25..58c25e040 100644 --- a/src/event/Loop.cxx +++ b/src/event/Loop.cxx @@ -31,7 +31,7 @@ EventLoop::EventLoop(Default) :SocketMonitor(*this), now_ms(::MonotonicClockMS()), - quit(false), + quit(false), busy(true), thread(ThreadId::Null()) { SocketMonitor::Open(wake_fd.Get()); @@ -122,6 +122,7 @@ EventLoop::Run() thread = ThreadId::GetCurrent(); assert(!quit); + assert(busy); do { now_ms = ::MonotonicClockMS(); @@ -161,6 +162,13 @@ EventLoop::Run() return; } + /* try to handle DeferredMonitors without WakeFD + overhead */ + mutex.lock(); + HandleDeferred(); + busy = false; + mutex.unlock(); + if (again) /* re-evaluate timers because one of the IdleMonitors may have added a new @@ -173,6 +181,10 @@ EventLoop::Run() now_ms = ::MonotonicClockMS(); + mutex.lock(); + busy = true; + mutex.unlock(); + /* invoke sockets */ for (int i = 0; i < poll_result.GetSize(); ++i) { auto events = poll_result.GetEvents(i); @@ -190,6 +202,7 @@ EventLoop::Run() } while (!quit); #ifndef NDEBUG + assert(busy); assert(thread.IsInside()); thread = ThreadId::Null(); #endif @@ -209,10 +222,11 @@ EventLoop::AddDeferred(DeferredMonitor &d) /* we don't need to wake up the EventLoop if another DeferredMonitor has already done it */ - const bool must_wake = deferred.empty(); + const bool must_wake = !busy && deferred.empty(); d.pending = true; deferred.push_back(&d); + again = true; mutex.unlock(); if (must_wake) diff --git a/src/event/Loop.hxx b/src/event/Loop.hxx index bfa8dc4a9..4bd2a3b2c 100644 --- a/src/event/Loop.hxx +++ b/src/event/Loop.hxx @@ -90,6 +90,14 @@ class EventLoop final : SocketMonitor */ bool again; + /** + * True when handling callbacks, false when waiting for I/O or + * timeout. + * + * Protected with #mutex. + */ + bool busy; + PollGroup poll_group; PollResult poll_result; |