Big refactoring step.

- Moves a lot of stuff from vibe.core.core to vibe.core.task
- Introduces TaskScheduler to unify the scheduling process
- Refines how tasks are scheduled and processed (can push to the front of the task queue and uses a marker task to keep track of the spot up to which to process)
- Start to add proper support for task interrupts and timeouts by properly cancelling in-flight async operations
- Work on ManualEvent - still not functional for the shared case
- Implement proper IP address parsing in NetworkAddress
This commit is contained in:
Sönke Ludwig 2016-06-14 08:01:03 +02:00
parent c3857d1bc9
commit 3b0e4e0452
6 changed files with 1097 additions and 678 deletions

View file

@ -2,15 +2,39 @@ module vibe.internal.async;
import std.traits : ParameterTypeTuple;
import std.typecons : tuple;
import vibe.core.core;
import vibe.core.core : hibernate, switchToTask;
import vibe.core.task : InterruptException, Task;
import vibe.core.log;
import core.time : Duration, seconds;
auto asyncAwait(string method, Object, ARGS...)(Object object, ARGS args)
auto asyncAwait(Callback, alias action, alias cancel, string func = __FUNCTION__)()
if (!is(Object == Duration)) {
return asyncAwaitImpl!(true, Callback, action, cancel, func)(Duration.max);
}
auto asyncAwait(Callback, alias action, alias cancel, string func = __FUNCTION__)(Duration timeout)
{
alias CB = ParameterTypeTuple!(__traits(getMember, Object, method))[$-1];
alias CBTypes = ParameterTypeTuple!CB;
return asyncAwaitImpl!(true, Callback, action, cancel, func)(timeout);
}
auto asyncAwaitUninterruptible(Callback, alias action, string func = __FUNCTION__)()
nothrow {
return asyncAwaitImpl!(false, Callback, action, (cb) { assert(false); }, func)(Duration.max);
}
auto asyncAwaitUninterruptible(Callback, alias action, alias cancel, string func = __FUNCTION__)(Duration timeout)
nothrow {
assert(timeout >= 0.seconds);
asyncAwaitImpl!(false, Callback, action, cancel, func)(timeout);
}
private auto asyncAwaitImpl(bool interruptible, Callback, alias action, alias cancel, string func)(Duration timeout)
@safe if (!is(Object == Duration)) {
alias CBTypes = ParameterTypeTuple!Callback;
assert(timeout >= 0.seconds);
assert(timeout == Duration.max, "TODO!");
bool fired = false;
CBTypes ret;
@ -21,25 +45,28 @@ auto asyncAwait(string method, Object, ARGS...)(Object object, ARGS args)
logTrace("Got result.");
fired = true;
ret = params;
if (t != Task.init)
resumeTask(t);
if (t != Task.init) switchToTask(t);
}
logTrace("Calling %s...", method);
__traits(getMember, object, method)(args, &callback);
scope cbdel = &callback;
logTrace("Calling async function in "~func);
action(cbdel);
if (!fired) {
logTrace("Need to wait...");
t = Task.getThis();
do yieldForEvent();
while (!fired);
do {
static if (interruptible) {
bool interrupted = false;
hibernate(() @safe nothrow {
cancel(cbdel);
interrupted = true;
});
if (interrupted)
throw new InterruptException; // FIXME: the original operation needs to be stopped! or the callback will still be called"
} else hibernate();
} while (!fired);
}
logTrace("Return result.");
return tuple(ret);
}
auto asyncAwait(string method, Object, ARGS...)(Duration timeout, Object object, ARGS args)
{
assert(timeout >= 0.seconds);
if (timeout == Duration.max) return asyncAwait(object, args);
else assert(false, "TODO!");
}