Add runEventLoopOnce() and fix hibernate() to block outside of a task.

This commit is contained in:
Sönke Ludwig 2016-06-16 10:44:55 +02:00
parent e8ba981263
commit ed36531bd2

View file

@ -102,12 +102,19 @@ int runEventLoop()
runTask(toDelegate(&watchExitFlag)); runTask(toDelegate(&watchExitFlag));
} (); } ();
while (s_scheduler.scheduledTaskCount || eventDriver.waiterCount) { while ((s_scheduler.scheduledTaskCount || eventDriver.waiterCount) && !s_exitEventLoop) {
if (eventDriver.processEvents() == ExitReason.exited) logTrace("process events");
if (eventDriver.processEvents() == ExitReason.exited) {
break; break;
} }
logTrace("idle processing");
performIdleProcessing();
}
logDebug("Event loop done (%s).", eventDriver.waiterCount); logDebug("Event loop done (scheduled tasks=%s, waiters=%s, thread exit=%s).",
s_scheduler.scheduledTaskCount, eventDriver.waiterCount, s_exitEventLoop);
eventDriver.clearExitFlag();
s_exitEventLoop = false;
return 0; return 0;
} }
@ -149,11 +156,20 @@ void exitEventLoop(bool shutdown_all_threads = false)
*/ */
bool processEvents() bool processEvents()
@safe nothrow { @safe nothrow {
if (!eventDriver.processEvents(Duration.max)) return false; if (!eventDriver.processEvents(0.seconds)) return false;
performIdleProcessing(); performIdleProcessing();
return true; return true;
} }
/**
Wait once for events and process them.
*/
void runEventLoopOnce()
@safe nothrow {
eventDriver.processEvents(Duration.max);
performIdleProcessing();
}
/** /**
Sets a callback that is called whenever no events are left in the event queue. Sets a callback that is called whenever no events are left in the event queue.
@ -602,10 +618,12 @@ version (linux) static if (__VERSION__ <= 2066) private extern(C) int get_nprocs
the calling task. the calling task.
*/ */
void yield() void yield()
@safe nothrow { @safe {
auto t = Task.getThis(); auto t = Task.getThis();
if (t != Task.init) { if (t != Task.init) {
t.taskFiber.handleInterrupt();
s_scheduler.yield(); s_scheduler.yield();
t.taskFiber.handleInterrupt();
} else { } else {
// Let yielded tasks execute // Let yielded tasks execute
() @safe nothrow { performIdleProcessing(); } (); () @safe nothrow { performIdleProcessing(); } ();
@ -629,7 +647,7 @@ void hibernate(scope void delegate() @safe nothrow on_interrupt = null)
@safe nothrow { @safe nothrow {
auto t = Task.getThis(); auto t = Task.getThis();
if (t == Task.init) { if (t == Task.init) {
processEvents(); runEventLoopOnce();
} else { } else {
t.taskFiber.handleInterrupt(on_interrupt); t.taskFiber.handleInterrupt(on_interrupt);
s_scheduler.hibernate(); s_scheduler.hibernate();