vibe.d beta banner
get vibe.d
0.10.0

Asynchronous I/O that doesn’t get in your way, written in D

Function runWorkerTaskH

Runs a new asynchronous task in a worker thread, returning the task handle.

Task runWorkerTaskH(FT, ARGS...) (
  FT func,
  auto ref ARGS args
)
if (isFunctionPointer!FT && isNothrowCallable!(FT, ARGS));

Task runWorkerTaskH(alias method, T, ARGS...) (
  shared(T) object,
  auto ref ARGS args
)
if (isNothrowMethod!(shared(T), method, ARGS));

Task runWorkerTaskH(FT, ARGS...) (
  TaskSettings settings,
  FT func,
  auto ref ARGS args
)
if (isFunctionPointer!FT && isNothrowCallable!(FT, ARGS));

Task runWorkerTaskH(alias method, T, ARGS...) (
  TaskSettings settings,
  shared(T) object,
  auto ref ARGS args
)
if (isNothrowMethod!(shared(T), method, ARGS));

This function will yield and wait for the new task to be created and started in the worker thread, then resume and return it.

Only function pointers with weakly isolated arguments are allowed to be able to guarantee thread-safety.

Example

Running a worker task using a function

static void workerFunc(int param)
{
	logInfo("Param: %s", param);
}

static void test()
{
	runWorkerTask(&workerFunc, 42);
	runWorkerTask(&workerFunc, cast(ubyte)42); // implicit conversion #719
	runWorkerTaskDist(&workerFunc, 42);
	runWorkerTaskDist(&workerFunc, cast(ubyte)42); // implicit conversion #719
}

Example

Running a worker task using a class method

static class Test {
	void workerMethod(int param)
	shared nothrow {
		logInfo("Param: %s", param);
	}
}

static void test()
{
	auto cls = new shared Test;
	runWorkerTask!(Test.workerMethod)(cls, 42);
	runWorkerTask!(Test.workerMethod)(cls, cast(ubyte)42); // #719
	runWorkerTaskDist!(Test.workerMethod)(cls, 42);
	runWorkerTaskDist!(Test.workerMethod)(cls, cast(ubyte)42); // #719
}

Example

Running a worker task using a function and communicating with it

static void workerFunc(Task caller)
nothrow {
	int counter = 10;
	try {
		while (receiveOnly!string() == "ping" && --counter) {
			logInfo("pong");
			caller.send("pong");
		}
		caller.send("goodbye");
	} catch (Exception e) assert(false, e.msg);
}

static void test()
{
	Task callee = runWorkerTaskH(&workerFunc, Task.getThis);
	do {
		logInfo("ping");
		callee.send("ping");
	} while (receiveOnly!string() == "pong");
}

static void work719(int) nothrow {}
static void test719() { runWorkerTaskH(&work719, cast(ubyte)42); }

Example

Running a worker task using a class method and communicating with it

static class Test {
	void workerMethod(Task caller)
	shared nothrow {
		int counter = 10;
		try {
			while (receiveOnly!string() == "ping" && --counter) {
				logInfo("pong");
				caller.send("pong");
			}
			caller.send("goodbye");
		} catch (Exception e) assert(false, e.msg);
	}
}

static void test()
{
	auto cls = new shared Test;
	Task callee = runWorkerTaskH!(Test.workerMethod)(cls, Task.getThis());
	do {
		logInfo("ping");
		callee.send("ping");
	} while (receiveOnly!string() == "pong");
}

static class Class719 {
	void work(int) shared nothrow {}
}
static void test719() {
	auto cls = new shared Class719;
	runWorkerTaskH!(Class719.work)(cls, cast(ubyte)42);
}
Authors

Sönke Ludwig

Copyright

© 2012-2020 Sönke Ludwig

License

Subject to the terms of the MIT license, as written in the included LICENSE.txt file.