Merge pull request #81 from vibe-d/fix_no_loop_message_processing

Fix event processing when calling yield() outside of an event loop.
This commit is contained in:
Sönke Ludwig 2018-06-05 12:44:12 +02:00 committed by GitHub
commit 61bfbbbac3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -192,8 +192,10 @@ int runEventLoop()
logDebug("Starting event loop."); logDebug("Starting event loop.");
s_eventLoopRunning = true; s_eventLoopRunning = true;
scope (exit) { scope (exit) {
eventDriver.core.clearExitFlag();
s_eventLoopRunning = false; s_eventLoopRunning = false;
s_exitEventLoop = false; s_exitEventLoop = false;
if (s_isMainThread) atomicStore(st_term, false);
() @trusted nothrow { () @trusted nothrow {
scope (failure) assert(false); // notifyAll is not marked nothrow scope (failure) assert(false); // notifyAll is not marked nothrow
st_threadShutdownCondition.notifyAll(); st_threadShutdownCondition.notifyAll();
@ -231,8 +233,6 @@ int runEventLoop()
logDebug("Event loop done (scheduled tasks=%s, waiters=%s, thread exit=%s).", logDebug("Event loop done (scheduled tasks=%s, waiters=%s, thread exit=%s).",
s_scheduler.scheduledTaskCount, eventDriver.core.waiterCount, s_exitEventLoop); s_scheduler.scheduledTaskCount, eventDriver.core.waiterCount, s_exitEventLoop);
eventDriver.core.clearExitFlag();
s_exitEventLoop = false;
return 0; return 0;
} }
@ -647,7 +647,7 @@ void yield()
} else { } else {
// Let yielded tasks execute // Let yielded tasks execute
assert(TaskFiber.getThis().m_yieldLockCount == 0, "May not yield within an active yieldLock()!"); assert(TaskFiber.getThis().m_yieldLockCount == 0, "May not yield within an active yieldLock()!");
() @safe nothrow { performIdleProcessing(); } (); () @safe nothrow { performIdleProcessing(true); } ();
} }
} }
@ -1152,24 +1152,26 @@ private void setupGcTimer()
s_gcCollectTimeout = dur!"seconds"(2); s_gcCollectTimeout = dur!"seconds"(2);
} }
package(vibe) void performIdleProcessing() package(vibe) void performIdleProcessing(bool force_process_events = false)
@safe nothrow { @safe nothrow {
bool again = !getExitFlag(); bool again = !getExitFlag();
while (again) { while (again) {
if (force_process_events) {
auto er = eventDriver.core.processEvents(0.seconds);
if (er.among!(ExitReason.exited, ExitReason.outOfWaiters) && s_scheduler.scheduledTaskCount == 0) {
if (s_eventLoopRunning) {
logDebug("Setting exit flag due to driver signalling exit: %s", er);
s_exitEventLoop = true;
}
return;
}
} else force_process_events = true;
if (s_idleHandler) if (s_idleHandler)
again = s_idleHandler(); again = s_idleHandler();
else again = false; else again = false;
again = (s_scheduler.schedule() == ScheduleStatus.busy || again) && !getExitFlag(); again = (s_scheduler.schedule() == ScheduleStatus.busy || again) && !getExitFlag();
if (again) {
auto er = eventDriver.core.processEvents(0.seconds);
if (er.among!(ExitReason.exited, ExitReason.outOfWaiters) && s_scheduler.scheduledTaskCount == 0) {
logDebug("Setting exit flag due to driver signalling exit: %s", er);
s_exitEventLoop = true;
return;
}
}
} }
if (s_scheduler.scheduledTaskCount) logDebug("Exiting from idle processing although there are still yielded tasks"); if (s_scheduler.scheduledTaskCount) logDebug("Exiting from idle processing although there are still yielded tasks");