Skip to content

Commit

Permalink
Allow returning void from performInWorker callables.
Browse files Browse the repository at this point in the history
  • Loading branch information
s-ludwig committed Dec 20, 2023
1 parent f4c6b75 commit de2403c
Showing 1 changed file with 32 additions and 4 deletions.
36 changes: 32 additions & 4 deletions source/vibe/core/concurrency.d
Original file line number Diff line number Diff line change
Expand Up @@ -1272,7 +1272,8 @@ ReturnType!CALLABLE performInWorker(CALLABLE, ARGS...)
static struct CTX {
CALLABLE callable;
ARGS args;
ReturnType!CALLABLE result;
static if (!is(ReturnType!CALLABLE == void))
ReturnType!CALLABLE result;
shared(Mutex) mutex;
shared(TaskCondition) condition;
bool done;
Expand All @@ -1287,10 +1288,13 @@ ReturnType!CALLABLE performInWorker(CALLABLE, ARGS...)
// start worker task
pool.runTask((shared(CTX)* ctx_) nothrow {
auto ctx = () @trusted { return cast(CTX*)ctx_; } ();
auto res = ctx.callable(ctx.args);
static if (!is(ReturnType!CALLABLE == void))
auto res = ctx.callable(ctx.args);
else ctx.callable(ctx.args);
{
auto l = scopedMutexLock(ctx.mutex);
ctx.result = res;
static if (!is(ReturnType!CALLABLE == void))
ctx.result = res;
ctx.done = true;
ctx.condition.notifyAll();
}
Expand All @@ -1314,7 +1318,8 @@ ReturnType!CALLABLE performInWorker(CALLABLE, ARGS...)
GC.free(cast(void*)ctx.mutex);
} ();

return ctx.result;
static if (!is(ReturnType!CALLABLE == void))
return ctx.result;
}

///
Expand Down Expand Up @@ -1356,6 +1361,29 @@ ReturnType!CALLABLE performInWorker(CALLABLE, ARGS...)
t.join();
}

@safe unittest {
import vibe.core.core : runTask, sleepUninterruptible;
import vibe.core.log : logInfo;

auto tms = MonoTime.currTime();

// perform some heavy CPU work in a worker thread, while the background task
// continues to run unaffected
performInWorker((long start_value) {
auto tm = MonoTime.currTime;
long res = start_value;
// simulate some CPU workload for 50 ms
while (MonoTime.currTime - tm < 50.msecs) {
res++;
res *= res;
if (!res) res++;
}
}, 1234);

// ensure performInWorker only returns after the workload has been processed
assert(MonoTime.currTime - tms >= 50.msecs);
}


/******************************************************************************/
/* std.concurrency compatible interface for message passing */
Expand Down

0 comments on commit de2403c

Please sign in to comment.