From ed36531bd2f0c746bcf3ac00f9a7e728e07b9bd9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6nke=20Ludwig?= Date: Thu, 16 Jun 2016 10:44:55 +0200 Subject: [PATCH] Add runEventLoopOnce() and fix hibernate() to block outside of a task. --- source/vibe/core/core.d | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/source/vibe/core/core.d b/source/vibe/core/core.d index a7e22c2..534ce4a 100644 --- a/source/vibe/core/core.d +++ b/source/vibe/core/core.d @@ -102,12 +102,19 @@ int runEventLoop() runTask(toDelegate(&watchExitFlag)); } (); - while (s_scheduler.scheduledTaskCount || eventDriver.waiterCount) { - if (eventDriver.processEvents() == ExitReason.exited) + while ((s_scheduler.scheduledTaskCount || eventDriver.waiterCount) && !s_exitEventLoop) { + logTrace("process events"); + if (eventDriver.processEvents() == ExitReason.exited) { 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; } @@ -149,11 +156,20 @@ void exitEventLoop(bool shutdown_all_threads = false) */ bool processEvents() @safe nothrow { - if (!eventDriver.processEvents(Duration.max)) return false; + if (!eventDriver.processEvents(0.seconds)) return false; performIdleProcessing(); 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. @@ -602,10 +618,12 @@ version (linux) static if (__VERSION__ <= 2066) private extern(C) int get_nprocs the calling task. */ void yield() -@safe nothrow { +@safe { auto t = Task.getThis(); if (t != Task.init) { + t.taskFiber.handleInterrupt(); s_scheduler.yield(); + t.taskFiber.handleInterrupt(); } else { // Let yielded tasks execute () @safe nothrow { performIdleProcessing(); } (); @@ -629,7 +647,7 @@ void hibernate(scope void delegate() @safe nothrow on_interrupt = null) @safe nothrow { auto t = Task.getThis(); if (t == Task.init) { - processEvents(); + runEventLoopOnce(); } else { t.taskFiber.handleInterrupt(on_interrupt); s_scheduler.hibernate();