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:
parent
c3857d1bc9
commit
3b0e4e0452
6 changed files with 1097 additions and 678 deletions
|
@ -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!");
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue