event/Loop: split InjectBreak() from Break()
This commit is contained in:
parent
a57cf443ed
commit
a3b32819b1
|
@ -87,17 +87,6 @@ EventLoop::GetUring() noexcept
|
|||
|
||||
#endif
|
||||
|
||||
void
|
||||
EventLoop::Break() noexcept
|
||||
{
|
||||
if (quit.exchange(true))
|
||||
return;
|
||||
|
||||
#ifdef HAVE_THREADED_EVENT_LOOP
|
||||
wake_fd.Write();
|
||||
#endif
|
||||
}
|
||||
|
||||
bool
|
||||
EventLoop::AddFD(int fd, unsigned events, SocketEvent &event) noexcept
|
||||
{
|
||||
|
@ -286,6 +275,7 @@ EventLoop::Run() noexcept
|
|||
|
||||
assert(IsInside());
|
||||
assert(!quit);
|
||||
assert(!quit_injected);
|
||||
#ifdef HAVE_THREADED_EVENT_LOOP
|
||||
assert(alive);
|
||||
assert(busy);
|
||||
|
@ -437,6 +427,11 @@ EventLoop::OnSocketReady([[maybe_unused]] unsigned flags) noexcept
|
|||
|
||||
wake_fd.Read();
|
||||
|
||||
if (quit_injected) {
|
||||
Break();
|
||||
return;
|
||||
}
|
||||
|
||||
const std::scoped_lock<Mutex> lock(mutex);
|
||||
HandleInject();
|
||||
}
|
||||
|
|
|
@ -115,7 +115,7 @@ class EventLoop final
|
|||
bool alive;
|
||||
#endif
|
||||
|
||||
std::atomic_bool quit{false};
|
||||
bool quit = false;
|
||||
|
||||
/**
|
||||
* True when the object has been modified and another check is
|
||||
|
@ -124,6 +124,8 @@ class EventLoop final
|
|||
bool again;
|
||||
|
||||
#ifdef HAVE_THREADED_EVENT_LOOP
|
||||
bool quit_injected = false;
|
||||
|
||||
/**
|
||||
* True when handling callbacks, false when waiting for I/O or
|
||||
* timeout.
|
||||
|
@ -187,11 +189,30 @@ public:
|
|||
#endif
|
||||
|
||||
/**
|
||||
* Stop execution of this #EventLoop at the next chance. This
|
||||
* method is thread-safe and non-blocking: after returning, it
|
||||
* is not guaranteed that the EventLoop has really stopped.
|
||||
* Stop execution of this #EventLoop at the next chance.
|
||||
*
|
||||
* This method is not thread-safe. For stopping the
|
||||
* #EventLoop from within another thread, use InjectBreak().
|
||||
*/
|
||||
void Break() noexcept;
|
||||
void Break() noexcept {
|
||||
quit = true;
|
||||
}
|
||||
|
||||
#ifdef HAVE_THREADED_EVENT_LOOP
|
||||
/**
|
||||
* Like Break(), but thread-safe. It is also non-blocking:
|
||||
* after returning, it is not guaranteed that the EventLoop
|
||||
* has really stopped.
|
||||
*/
|
||||
void InjectBreak() noexcept {
|
||||
{
|
||||
const std::scoped_lock lock{mutex};
|
||||
quit_injected = true;
|
||||
}
|
||||
|
||||
wake_fd.Write();
|
||||
}
|
||||
#endif // HAVE_THREADED_EVENT_LOOP
|
||||
|
||||
bool AddFD(int fd, unsigned events, SocketEvent &event) noexcept;
|
||||
bool ModifyFD(int fd, unsigned events, SocketEvent &event) noexcept;
|
||||
|
|
|
@ -45,7 +45,7 @@ EventThread::Stop() noexcept
|
|||
assert(event_loop.IsAlive());
|
||||
event_loop.SetAlive(false);
|
||||
|
||||
event_loop.Break();
|
||||
event_loop.InjectBreak();
|
||||
thread.Join();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue