Add setTaskCreationCallback() for better remote debugger integration.
This commit is contained in:
parent
719c62d6c9
commit
4f69b1eaf3
|
@ -373,6 +373,13 @@ package Task runTask_internal(alias TFI_SETUP)()
|
||||||
f.bumpTaskCounter();
|
f.bumpTaskCounter();
|
||||||
auto handle = f.task();
|
auto handle = f.task();
|
||||||
|
|
||||||
|
debug if (TaskFiber.ms_taskCreationCallback) {
|
||||||
|
TaskCreationInfo info;
|
||||||
|
info.handle = handle;
|
||||||
|
info.functionPointer = () @trusted { return cast(void*)f.m_taskFunc.functionPointer; } ();
|
||||||
|
() @trusted { TaskFiber.ms_taskCreationCallback(info); } ();
|
||||||
|
}
|
||||||
|
|
||||||
debug if (TaskFiber.ms_taskEventCallback) {
|
debug if (TaskFiber.ms_taskEventCallback) {
|
||||||
() @trusted { TaskFiber.ms_taskEventCallback(TaskEvent.preStart, handle); } ();
|
() @trusted { TaskFiber.ms_taskEventCallback(TaskEvent.preStart, handle); } ();
|
||||||
}
|
}
|
||||||
|
@ -916,6 +923,21 @@ void setTaskEventCallback(TaskEventCallback func)
|
||||||
debug TaskFiber.ms_taskEventCallback = func;
|
debug TaskFiber.ms_taskEventCallback = func;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Sets a callback that is invoked whenever new task is created.
|
||||||
|
|
||||||
|
The callback is guaranteed to be invoked before the one set by
|
||||||
|
`setTaskEventCallback` for the same task handle.
|
||||||
|
|
||||||
|
This function is useful mostly for implementing debuggers that
|
||||||
|
analyze the life time of tasks, including task switches. Note that
|
||||||
|
the callback will only be called for debug builds.
|
||||||
|
*/
|
||||||
|
void setTaskCreationCallback(TaskCreationCallback func)
|
||||||
|
{
|
||||||
|
debug TaskFiber.ms_taskCreationCallback = func;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
A version string representing the current vibe version
|
A version string representing the current vibe version
|
||||||
|
|
|
@ -262,7 +262,13 @@ enum TaskEvent {
|
||||||
fail /// Ended with an exception
|
fail /// Ended with an exception
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct TaskCreationInfo {
|
||||||
|
Task handle;
|
||||||
|
const(void)* functionPointer;
|
||||||
|
}
|
||||||
|
|
||||||
alias TaskEventCallback = void function(TaskEvent, Task) nothrow;
|
alias TaskEventCallback = void function(TaskEvent, Task) nothrow;
|
||||||
|
alias TaskCreationCallback = void function(ref TaskCreationInfo) nothrow @safe;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
The maximum combined size of all parameters passed to a task delegate
|
The maximum combined size of all parameters passed to a task delegate
|
||||||
|
@ -314,6 +320,7 @@ final package class TaskFiber : Fiber {
|
||||||
package TaskFuncInfo m_taskFunc;
|
package TaskFuncInfo m_taskFunc;
|
||||||
package __gshared size_t ms_taskStackSize = defaultTaskStackSize;
|
package __gshared size_t ms_taskStackSize = defaultTaskStackSize;
|
||||||
package __gshared debug TaskEventCallback ms_taskEventCallback;
|
package __gshared debug TaskEventCallback ms_taskEventCallback;
|
||||||
|
package __gshared debug TaskCreationCallback ms_taskCreationCallback;
|
||||||
|
|
||||||
this()
|
this()
|
||||||
@trusted nothrow {
|
@trusted nothrow {
|
||||||
|
@ -323,9 +330,7 @@ final package class TaskFiber : Fiber {
|
||||||
|
|
||||||
static TaskFiber getThis()
|
static TaskFiber getThis()
|
||||||
@safe nothrow {
|
@safe nothrow {
|
||||||
auto f = () @trusted nothrow {
|
auto f = () @trusted nothrow { return Fiber.getThis(); } ();
|
||||||
return Fiber.getThis();
|
|
||||||
} ();
|
|
||||||
if (auto tf = cast(TaskFiber)f) return tf;
|
if (auto tf = cast(TaskFiber)f) return tf;
|
||||||
if (!ms_globalDummyFiber) ms_globalDummyFiber = new TaskFiber;
|
if (!ms_globalDummyFiber) ms_globalDummyFiber = new TaskFiber;
|
||||||
return ms_globalDummyFiber;
|
return ms_globalDummyFiber;
|
||||||
|
@ -508,6 +513,7 @@ package struct TaskFuncInfo {
|
||||||
void function(ref TaskFuncInfo) func;
|
void function(ref TaskFuncInfo) func;
|
||||||
void[2*size_t.sizeof] callable;
|
void[2*size_t.sizeof] callable;
|
||||||
void[maxTaskParameterSize] args;
|
void[maxTaskParameterSize] args;
|
||||||
|
debug ulong functionPointer;
|
||||||
|
|
||||||
void set(CALLABLE, ARGS...)(ref CALLABLE callable, ref ARGS args)
|
void set(CALLABLE, ARGS...)(ref CALLABLE callable, ref ARGS args)
|
||||||
{
|
{
|
||||||
|
@ -525,6 +531,8 @@ package struct TaskFuncInfo {
|
||||||
"The arguments passed to run(Worker)Task must not exceed "~
|
"The arguments passed to run(Worker)Task must not exceed "~
|
||||||
maxTaskParameterSize.to!string~" bytes in total size: "~TARGS.sizeof.stringof~" bytes");
|
maxTaskParameterSize.to!string~" bytes in total size: "~TARGS.sizeof.stringof~" bytes");
|
||||||
|
|
||||||
|
debug functionPointer = callPointer(callable);
|
||||||
|
|
||||||
static void callDelegate(ref TaskFuncInfo tfi) {
|
static void callDelegate(ref TaskFuncInfo tfi) {
|
||||||
assert(tfi.func is &callDelegate, "Wrong callDelegate called!?");
|
assert(tfi.func is &callDelegate, "Wrong callDelegate called!?");
|
||||||
|
|
||||||
|
@ -584,6 +592,16 @@ package struct TaskFuncInfo {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ulong callPointer(C)(ref C callable)
|
||||||
|
@trusted nothrow @nogc {
|
||||||
|
alias IP = ulong;
|
||||||
|
static if (is(C == function)) return cast(IP)cast(void*)callable;
|
||||||
|
else static if (is(C == delegate)) return cast(IP)callable.funcptr;
|
||||||
|
else static if (is(typeof(&callable.opCall) == function)) return cast(IP)cast(void*)&callable.opCall;
|
||||||
|
else static if (is(typeof(&callable.opCall) == delegate)) return cast(IP)(&callable.opCall).funcptr;
|
||||||
|
else return cast(IP)&callable;
|
||||||
|
}
|
||||||
|
|
||||||
package struct TaskScheduler {
|
package struct TaskScheduler {
|
||||||
import eventcore.driver : ExitReason;
|
import eventcore.driver : ExitReason;
|
||||||
import eventcore.core : eventDriver;
|
import eventcore.core : eventDriver;
|
||||||
|
|
Loading…
Reference in a new issue