On Tue, 25 Mar 2014 17:48:34 GMT, Sönke Ludwig wrote:
What should work is passing the
Task
handle like this:void workerTaskFunc(Task caller) { caller.send(Task.getThis()); } runWorkerTask(&caller, Task.getThis()); auto task = receiveOnly!Task();
I'm not 100% sure if there isn't currently something that fails here, but in theory message passing between different threads/event loops should work fine. Maybe it makes sense to add a second form of
runWorkerTask
that actually waits and returns the handle. Currently this isn't done for performance reasons.
It didn't occur to me to check if Task was indeed an isolated type; it seems to be working (for a fairly simple test).
A general function could be maybe written as
Task getWorkerTask(R, ARGS...)(R function(ARGS) func, ARGS args)
{
foreach (T; ARGS) static assert(isWeaklyIsolated!T, "Argument type "~T.stringof~" is not safe to pass between threads.");
Task caller = Task.getThis();
runWorkerTask_unsafe({
caller.prioritySend(Task.getThis());
func(args);
});
Task callee;
receive((Task val) { callee = val; });
return callee;
}
with a symmetric function for method tasks.
Looks like a DMD bug. Can you file a quick bug report at http://https://d.puremagic.com/issues/enter_bug.cgi? When I get some time, I'd try to make a reduced test case.
I'm not sure it is a DMD bug:
the problem seems to be the in the template isWeaklyIsolated, more specifically in the last branch
static if(isAggregateType!(T[0])) enum bool isWeaklyIsolated = isWeaklyIsolated!(FieldTypeTuple!(T[0]));
ManualEvent falls in this branch, the same does FieldTypeTuple!ManualEvent, like FieldTypeTuple!(FieldTypeTuple!ManualEvent), and so on.
This is indeed something that is missing and planned since the beginning (hence the "Threaded" in the name). I wasn't sure about the best approach, though. Probably using a separate thread pool with 1-3 threads just for
ThreadedFileStream
will be the best compromise, I guess.
I think a separate thread pool is the right solution as well; as for the size of the pool one could try measuring performance and adjusting it; it could perhaps be made tunable.
A first step could be formalizing the concept of thread pool in a class and make a version of runWorkerTask that takes an explicit thread pool. I hope to be able to play a bit with that in the next days.