event/Loop: set thread to current thread by default
Allows eliminating lots of complexity and workarounds for bogus assertion failures.
This commit is contained in:
parent
94525d3952
commit
5ac72211cd
@ -62,7 +62,7 @@ UpdateService::~UpdateService()
|
|||||||
void
|
void
|
||||||
UpdateService::CancelAllAsync()
|
UpdateService::CancelAllAsync()
|
||||||
{
|
{
|
||||||
assert(GetEventLoop().IsInsideOrNull());
|
assert(GetEventLoop().IsInside());
|
||||||
|
|
||||||
queue.Clear();
|
queue.Clear();
|
||||||
|
|
||||||
@ -144,7 +144,7 @@ UpdateService::Task()
|
|||||||
void
|
void
|
||||||
UpdateService::StartThread(UpdateQueueItem &&i)
|
UpdateService::StartThread(UpdateQueueItem &&i)
|
||||||
{
|
{
|
||||||
assert(GetEventLoop().IsInsideOrNull());
|
assert(GetEventLoop().IsInside());
|
||||||
assert(walk == nullptr);
|
assert(walk == nullptr);
|
||||||
|
|
||||||
modified = false;
|
modified = false;
|
||||||
@ -170,7 +170,7 @@ UpdateService::GenerateId()
|
|||||||
unsigned
|
unsigned
|
||||||
UpdateService::Enqueue(const char *path, bool discard)
|
UpdateService::Enqueue(const char *path, bool discard)
|
||||||
{
|
{
|
||||||
assert(GetEventLoop().IsInsideOrNull());
|
assert(GetEventLoop().IsInside());
|
||||||
|
|
||||||
/* determine which (mounted) database will be updated and what
|
/* determine which (mounted) database will be updated and what
|
||||||
storage will be scanned */
|
storage will be scanned */
|
||||||
|
@ -79,7 +79,7 @@ private:
|
|||||||
void
|
void
|
||||||
BlockingCall(EventLoop &loop, std::function<void()> &&f)
|
BlockingCall(EventLoop &loop, std::function<void()> &&f)
|
||||||
{
|
{
|
||||||
if (loop.IsInsideOrNull()) {
|
if (loop.IsInside()) {
|
||||||
/* we're already inside the loop - we can simply call
|
/* we're already inside the loop - we can simply call
|
||||||
the function */
|
the function */
|
||||||
f();
|
f();
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
void
|
void
|
||||||
IdleMonitor::Cancel()
|
IdleMonitor::Cancel()
|
||||||
{
|
{
|
||||||
assert(loop.IsInsideOrNull());
|
assert(loop.IsInside());
|
||||||
|
|
||||||
if (!IsActive())
|
if (!IsActive())
|
||||||
return;
|
return;
|
||||||
@ -38,7 +38,7 @@ IdleMonitor::Cancel()
|
|||||||
void
|
void
|
||||||
IdleMonitor::Schedule()
|
IdleMonitor::Schedule()
|
||||||
{
|
{
|
||||||
assert(loop.IsInsideOrVirgin());
|
assert(loop.IsInside());
|
||||||
|
|
||||||
if (IsActive())
|
if (IsActive())
|
||||||
/* already scheduled */
|
/* already scheduled */
|
||||||
|
@ -27,8 +27,8 @@
|
|||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
EventLoop::EventLoop()
|
EventLoop::EventLoop(ThreadId _thread)
|
||||||
:SocketMonitor(*this)
|
:SocketMonitor(*this), thread(_thread)
|
||||||
{
|
{
|
||||||
SocketMonitor::Open(SocketDescriptor(wake_fd.Get()));
|
SocketMonitor::Open(SocketDescriptor(wake_fd.Get()));
|
||||||
}
|
}
|
||||||
@ -52,7 +52,7 @@ EventLoop::Break()
|
|||||||
bool
|
bool
|
||||||
EventLoop::Abandon(int _fd, SocketMonitor &m)
|
EventLoop::Abandon(int _fd, SocketMonitor &m)
|
||||||
{
|
{
|
||||||
assert(IsInsideOrVirgin());
|
assert(IsInside());
|
||||||
|
|
||||||
poll_result.Clear(&m);
|
poll_result.Clear(&m);
|
||||||
return poll_group.Abandon(_fd);
|
return poll_group.Abandon(_fd);
|
||||||
@ -61,7 +61,7 @@ EventLoop::Abandon(int _fd, SocketMonitor &m)
|
|||||||
bool
|
bool
|
||||||
EventLoop::RemoveFD(int _fd, SocketMonitor &m)
|
EventLoop::RemoveFD(int _fd, SocketMonitor &m)
|
||||||
{
|
{
|
||||||
assert(IsInsideOrNull());
|
assert(IsInside());
|
||||||
|
|
||||||
poll_result.Clear(&m);
|
poll_result.Clear(&m);
|
||||||
return poll_group.Remove(_fd);
|
return poll_group.Remove(_fd);
|
||||||
@ -70,7 +70,7 @@ EventLoop::RemoveFD(int _fd, SocketMonitor &m)
|
|||||||
void
|
void
|
||||||
EventLoop::AddIdle(IdleMonitor &i)
|
EventLoop::AddIdle(IdleMonitor &i)
|
||||||
{
|
{
|
||||||
assert(IsInsideOrVirgin());
|
assert(IsInside());
|
||||||
assert(std::find(idle.begin(), idle.end(), &i) == idle.end());
|
assert(std::find(idle.begin(), idle.end(), &i) == idle.end());
|
||||||
|
|
||||||
idle.push_back(&i);
|
idle.push_back(&i);
|
||||||
@ -80,7 +80,7 @@ EventLoop::AddIdle(IdleMonitor &i)
|
|||||||
void
|
void
|
||||||
EventLoop::RemoveIdle(IdleMonitor &i)
|
EventLoop::RemoveIdle(IdleMonitor &i)
|
||||||
{
|
{
|
||||||
assert(IsInsideOrVirgin());
|
assert(IsInside());
|
||||||
|
|
||||||
auto it = std::find(idle.begin(), idle.end(), &i);
|
auto it = std::find(idle.begin(), idle.end(), &i);
|
||||||
assert(it != idle.end());
|
assert(it != idle.end());
|
||||||
@ -91,9 +91,7 @@ EventLoop::RemoveIdle(IdleMonitor &i)
|
|||||||
void
|
void
|
||||||
EventLoop::AddTimer(TimeoutMonitor &t, std::chrono::steady_clock::duration d)
|
EventLoop::AddTimer(TimeoutMonitor &t, std::chrono::steady_clock::duration d)
|
||||||
{
|
{
|
||||||
/* can't use IsInsideOrVirgin() here because libavahi-client
|
assert(IsInside());
|
||||||
modifies the timeout during avahi_client_free() */
|
|
||||||
assert(IsInsideOrNull());
|
|
||||||
|
|
||||||
timers.insert(TimerRecord(t, now + d));
|
timers.insert(TimerRecord(t, now + d));
|
||||||
again = true;
|
again = true;
|
||||||
@ -102,7 +100,7 @@ EventLoop::AddTimer(TimeoutMonitor &t, std::chrono::steady_clock::duration d)
|
|||||||
void
|
void
|
||||||
EventLoop::CancelTimer(TimeoutMonitor &t)
|
EventLoop::CancelTimer(TimeoutMonitor &t)
|
||||||
{
|
{
|
||||||
assert(IsInsideOrNull());
|
assert(IsInside());
|
||||||
|
|
||||||
for (auto i = timers.begin(), end = timers.end(); i != end; ++i) {
|
for (auto i = timers.begin(), end = timers.end(); i != end; ++i) {
|
||||||
if (&i->timer == &t) {
|
if (&i->timer == &t) {
|
||||||
@ -128,15 +126,10 @@ ExportTimeoutMS(std::chrono::steady_clock::duration timeout)
|
|||||||
void
|
void
|
||||||
EventLoop::Run()
|
EventLoop::Run()
|
||||||
{
|
{
|
||||||
assert(thread.IsNull());
|
if (thread.IsNull())
|
||||||
assert(virgin);
|
|
||||||
|
|
||||||
#ifndef NDEBUG
|
|
||||||
virgin = false;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
thread = ThreadId::GetCurrent();
|
thread = ThreadId::GetCurrent();
|
||||||
|
|
||||||
|
assert(IsInside());
|
||||||
assert(!quit);
|
assert(!quit);
|
||||||
assert(busy);
|
assert(busy);
|
||||||
|
|
||||||
@ -226,8 +219,6 @@ EventLoop::Run()
|
|||||||
assert(busy);
|
assert(busy);
|
||||||
assert(thread.IsInside());
|
assert(thread.IsInside());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
thread = ThreadId::Null();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -98,14 +98,6 @@ class EventLoop final : SocketMonitor
|
|||||||
*/
|
*/
|
||||||
bool busy = true;
|
bool busy = true;
|
||||||
|
|
||||||
#ifndef NDEBUG
|
|
||||||
/**
|
|
||||||
* True if Run() was never called. This is used for assert()
|
|
||||||
* calls.
|
|
||||||
*/
|
|
||||||
bool virgin = true;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
PollGroup poll_group;
|
PollGroup poll_group;
|
||||||
PollResult poll_result;
|
PollResult poll_result;
|
||||||
|
|
||||||
@ -115,7 +107,9 @@ class EventLoop final : SocketMonitor
|
|||||||
ThreadId thread = ThreadId::Null();
|
ThreadId thread = ThreadId::Null();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
EventLoop();
|
explicit EventLoop(ThreadId _thread);
|
||||||
|
EventLoop():EventLoop(ThreadId::GetCurrent()) {}
|
||||||
|
|
||||||
~EventLoop();
|
~EventLoop();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -135,7 +129,7 @@ public:
|
|||||||
void Break();
|
void Break();
|
||||||
|
|
||||||
bool AddFD(int _fd, unsigned flags, SocketMonitor &m) {
|
bool AddFD(int _fd, unsigned flags, SocketMonitor &m) {
|
||||||
assert(thread.IsNull() || thread.IsInside());
|
assert(IsInside());
|
||||||
|
|
||||||
return poll_group.Add(_fd, flags, &m);
|
return poll_group.Add(_fd, flags, &m);
|
||||||
}
|
}
|
||||||
@ -200,28 +194,8 @@ public:
|
|||||||
*/
|
*/
|
||||||
gcc_pure
|
gcc_pure
|
||||||
bool IsInside() const noexcept {
|
bool IsInside() const noexcept {
|
||||||
assert(!thread.IsNull());
|
|
||||||
|
|
||||||
return thread.IsInside();
|
return thread.IsInside();
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef NDEBUG
|
|
||||||
gcc_pure
|
|
||||||
bool IsInsideOrVirgin() const noexcept {
|
|
||||||
return virgin || IsInside();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Like IsInside(), but also returns true if the thread has
|
|
||||||
* already ended (or was not started yet). This is useful for
|
|
||||||
* code which may run during startup or shutdown, when events
|
|
||||||
* are not yet/anymore handled.
|
|
||||||
*/
|
|
||||||
gcc_pure
|
|
||||||
bool IsInsideOrNull() const noexcept {
|
|
||||||
return thread.IsNull() || thread.IsInside();
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* MAIN_NOTIFY_H */
|
#endif /* MAIN_NOTIFY_H */
|
||||||
|
@ -34,7 +34,7 @@ MultiSocketMonitor::MultiSocketMonitor(EventLoop &_loop)
|
|||||||
void
|
void
|
||||||
MultiSocketMonitor::Reset()
|
MultiSocketMonitor::Reset()
|
||||||
{
|
{
|
||||||
assert(GetEventLoop().IsInsideOrNull());
|
assert(GetEventLoop().IsInside());
|
||||||
|
|
||||||
fds.clear();
|
fds.clear();
|
||||||
IdleMonitor::Cancel();
|
IdleMonitor::Cancel();
|
||||||
@ -45,7 +45,7 @@ MultiSocketMonitor::Reset()
|
|||||||
void
|
void
|
||||||
MultiSocketMonitor::ClearSocketList()
|
MultiSocketMonitor::ClearSocketList()
|
||||||
{
|
{
|
||||||
assert(GetEventLoop().IsInsideOrNull());
|
assert(GetEventLoop().IsInside());
|
||||||
|
|
||||||
fds.clear();
|
fds.clear();
|
||||||
}
|
}
|
||||||
|
@ -34,7 +34,7 @@ class EventThread final {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
EventThread()
|
EventThread()
|
||||||
:thread(BIND_THIS_METHOD(Run)) {}
|
:event_loop(ThreadId::Null()), thread(BIND_THIS_METHOD(Run)) {}
|
||||||
|
|
||||||
~EventThread() {
|
~EventThread() {
|
||||||
Stop();
|
Stop();
|
||||||
|
Loading…
Reference in New Issue
Block a user