event/DeferEvent: add ScheduleNext()
This commit is contained in:
parent
4bb379a218
commit
5e107c33d9
@ -21,3 +21,12 @@ DeferEvent::ScheduleIdle() noexcept
|
|||||||
|
|
||||||
assert(IsPending());
|
assert(IsPending());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
DeferEvent::ScheduleNext() noexcept
|
||||||
|
{
|
||||||
|
if (!IsPending())
|
||||||
|
loop.AddNext(*this);
|
||||||
|
|
||||||
|
assert(IsPending());
|
||||||
|
}
|
||||||
|
@ -49,6 +49,15 @@ public:
|
|||||||
*/
|
*/
|
||||||
void ScheduleIdle() noexcept;
|
void ScheduleIdle() noexcept;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Schedule this event, but only after the next #EventLoop
|
||||||
|
* iteration (i.e. after the epoll_wait() call, after handling
|
||||||
|
* all pending I/O events). This is useful for repeated I/O
|
||||||
|
* operations that should not occupy the whole #EventLoop,
|
||||||
|
* starving all other I/O events.
|
||||||
|
*/
|
||||||
|
void ScheduleNext() noexcept;
|
||||||
|
|
||||||
void Cancel() noexcept {
|
void Cancel() noexcept {
|
||||||
if (IsPending())
|
if (IsPending())
|
||||||
unlink();
|
unlink();
|
||||||
|
@ -45,6 +45,7 @@ EventLoop::~EventLoop() noexcept
|
|||||||
|
|
||||||
assert(defer.empty());
|
assert(defer.empty());
|
||||||
assert(idle.empty());
|
assert(idle.empty());
|
||||||
|
assert(next.empty());
|
||||||
#ifdef HAVE_THREADED_EVENT_LOOP
|
#ifdef HAVE_THREADED_EVENT_LOOP
|
||||||
assert(inject.empty());
|
assert(inject.empty());
|
||||||
#endif
|
#endif
|
||||||
@ -201,6 +202,14 @@ EventLoop::AddIdle(DeferEvent &e) noexcept
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
EventLoop::AddNext(DeferEvent &e) noexcept
|
||||||
|
{
|
||||||
|
assert(IsInside());
|
||||||
|
|
||||||
|
next.push_back(e);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
EventLoop::RunDeferred() noexcept
|
EventLoop::RunDeferred() noexcept
|
||||||
{
|
{
|
||||||
@ -295,7 +304,7 @@ EventLoop::Run() noexcept
|
|||||||
|
|
||||||
/* invoke timers */
|
/* invoke timers */
|
||||||
|
|
||||||
const auto timeout = HandleTimers();
|
Event::Duration timeout = HandleTimers();
|
||||||
if (quit)
|
if (quit)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -331,8 +340,13 @@ EventLoop::Run() noexcept
|
|||||||
|
|
||||||
/* wait for new event */
|
/* wait for new event */
|
||||||
|
|
||||||
|
if (!next.empty())
|
||||||
|
timeout = Event::Duration{0};
|
||||||
|
|
||||||
Wait(timeout);
|
Wait(timeout);
|
||||||
|
|
||||||
|
idle.splice(std::next(idle.begin()), next);
|
||||||
|
|
||||||
FlushClockCaches();
|
FlushClockCaches();
|
||||||
|
|
||||||
#ifdef HAVE_THREADED_EVENT_LOOP
|
#ifdef HAVE_THREADED_EVENT_LOOP
|
||||||
|
@ -67,6 +67,12 @@ class EventLoop final
|
|||||||
*/
|
*/
|
||||||
DeferList idle;
|
DeferList idle;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is like #idle, but gets invoked after the next
|
||||||
|
* epoll_wait() call.
|
||||||
|
*/
|
||||||
|
DeferList next;
|
||||||
|
|
||||||
#ifdef HAVE_THREADED_EVENT_LOOP
|
#ifdef HAVE_THREADED_EVENT_LOOP
|
||||||
Mutex mutex;
|
Mutex mutex;
|
||||||
|
|
||||||
@ -226,6 +232,7 @@ public:
|
|||||||
*/
|
*/
|
||||||
void AddDefer(DeferEvent &e) noexcept;
|
void AddDefer(DeferEvent &e) noexcept;
|
||||||
void AddIdle(DeferEvent &e) noexcept;
|
void AddIdle(DeferEvent &e) noexcept;
|
||||||
|
void AddNext(DeferEvent &e) noexcept;
|
||||||
|
|
||||||
#ifdef HAVE_THREADED_EVENT_LOOP
|
#ifdef HAVE_THREADED_EVENT_LOOP
|
||||||
/**
|
/**
|
||||||
|
Loading…
x
Reference in New Issue
Block a user