From 61b938d6fad8211d68eb3921e4c68e38b016e7cc Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Thu, 9 Jan 2014 17:50:29 +0100 Subject: event/Loop: allow scheduling events before Run() Add the debug-only flag "virgin" which gets checked by assert() calls. Fixes assertion failures when using zeroconf/avahi. --- src/event/IdleMonitor.cxx | 2 +- src/event/Loop.cxx | 17 +++++++++++++---- src/event/Loop.hxx | 15 +++++++++++++++ 3 files changed, 29 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/event/IdleMonitor.cxx b/src/event/IdleMonitor.cxx index e791559a1..dd8d64f94 100644 --- a/src/event/IdleMonitor.cxx +++ b/src/event/IdleMonitor.cxx @@ -38,7 +38,7 @@ IdleMonitor::Cancel() void IdleMonitor::Schedule() { - assert(loop.IsInside()); + assert(loop.IsInsideOrVirgin()); if (IsActive()) /* already scheduled */ diff --git a/src/event/Loop.cxx b/src/event/Loop.cxx index 6e18b6bf8..8cd4cde72 100644 --- a/src/event/Loop.cxx +++ b/src/event/Loop.cxx @@ -32,6 +32,9 @@ EventLoop::EventLoop(Default) :SocketMonitor(*this), now_ms(::MonotonicClockMS()), quit(false), busy(true), +#ifndef NDEBUG + virgin(true), +#endif thread(ThreadId::Null()) { SocketMonitor::Open(wake_fd.Get()); @@ -58,7 +61,7 @@ EventLoop::Break() bool EventLoop::Abandon(int _fd, SocketMonitor &m) { - assert(IsInside()); + assert(IsInsideOrVirgin()); poll_result.Clear(&m); return poll_group.Abandon(_fd); @@ -76,7 +79,7 @@ EventLoop::RemoveFD(int _fd, SocketMonitor &m) void EventLoop::AddIdle(IdleMonitor &i) { - assert(IsInside()); + assert(IsInsideOrVirgin()); assert(std::find(idle.begin(), idle.end(), &i) == idle.end()); idle.push_back(&i); @@ -86,7 +89,7 @@ EventLoop::AddIdle(IdleMonitor &i) void EventLoop::RemoveIdle(IdleMonitor &i) { - assert(IsInside()); + assert(IsInsideOrVirgin()); auto it = std::find(idle.begin(), idle.end(), &i); assert(it != idle.end()); @@ -97,7 +100,7 @@ EventLoop::RemoveIdle(IdleMonitor &i) void EventLoop::AddTimer(TimeoutMonitor &t, unsigned ms) { - assert(IsInside()); + assert(IsInsideOrVirgin()); timers.insert(TimerRecord(t, now_ms + ms)); again = true; @@ -120,6 +123,12 @@ void EventLoop::Run() { assert(thread.IsNull()); + assert(virgin); + +#ifndef NDEBUG + virgin = false; +#endif + thread = ThreadId::GetCurrent(); assert(!quit); diff --git a/src/event/Loop.hxx b/src/event/Loop.hxx index 4bd2a3b2c..d03259fb0 100644 --- a/src/event/Loop.hxx +++ b/src/event/Loop.hxx @@ -98,6 +98,14 @@ class EventLoop final : SocketMonitor */ bool busy; +#ifndef NDEBUG + /** + * True if Run() was never called. This is used for assert() + * calls. + */ + bool virgin; +#endif + PollGroup poll_group; PollResult poll_result; @@ -198,6 +206,13 @@ public: return thread.IsInside(); } +#ifndef NDEBUG + gcc_pure + bool IsInsideOrVirgin() const { + return virgin || IsInside(); + } +#endif + #ifndef NDEBUG gcc_pure bool IsInsideOrNull() const { -- cgit v1.2.3