From 6caff0b105186a1252d41474807194d86d38f7a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6nke=20Ludwig?= Date: Sat, 27 Oct 2018 00:42:06 +0200 Subject: [PATCH 1/2] Fix synchronization and shutdown issues in TaskPool. - terminate() would hang if called from a worker thread because it would attempt to self-join - the handleWorkerTasks could miss signal emits, resulting in a hanging task queue or a missed termination signal --- source/vibe/core/taskpool.d | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/source/vibe/core/taskpool.d b/source/vibe/core/taskpool.d index 736f770..87b0c32 100644 --- a/source/vibe/core/taskpool.d +++ b/source/vibe/core/taskpool.d @@ -71,7 +71,6 @@ shared final class TaskPool { m_state.lock.term = true; m_signal.emit(); - auto ec = m_signal.emitCount; while (true) { WorkerThread th; with (m_state.lock) @@ -81,6 +80,9 @@ shared final class TaskPool { } if (!th) break; + if (th is Thread.getThis()) + continue; + () @trusted { try th.join(); catch (Exception e) { @@ -271,9 +273,8 @@ private final class WorkerThread : Thread { logDebug("worker thread enter"); TaskFuncInfo taskfunc; - while(true){ - auto emit_count = m_pool.m_signal.emitCount; - + auto emit_count = m_pool.m_signal.emitCount; + while(true) { with (m_pool.m_state.lock) { logDebug("worker thread check"); @@ -282,7 +283,7 @@ private final class WorkerThread : Thread { if (m_queue.consume(taskfunc)) { logDebug("worker thread got specific task"); } else if (queue.consume(taskfunc)) { - logDebug("worker thread got specific task"); + logDebug("worker thread got unspecific task"); } } From 439437436403fcb5399b2c0bcfcf37cfa8b16af3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6nke=20Ludwig?= Date: Sat, 27 Oct 2018 00:43:26 +0200 Subject: [PATCH 2/2] Fix race-condition in test case. The wait() call without arguments could miss the initial emit(), if called too late, which could easily happen on VMs with less predictable timing. --- tests/issue-58-task-already-scheduled.d | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/issue-58-task-already-scheduled.d b/tests/issue-58-task-already-scheduled.d index 80cc9f6..9325252 100644 --- a/tests/issue-58-task-already-scheduled.d +++ b/tests/issue-58-task-already-scheduled.d @@ -38,7 +38,7 @@ void main() void worker() { - ev.wait(); + ev.wait(0); ev.emit(); setTimer(dur!"seconds"(1), { auto c = atomicOp!"+="(counter, 1);