From ade765d6bd164449ee460261176d2734d85cd41c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6nke=20Ludwig?= Date: Tue, 15 Dec 2020 19:43:20 +0100 Subject: [PATCH 1/2] Fix a worker task scheduling issue for busy worker tasks. Fixes new tasks being able to be scheduled on a worker thread while a busy task (that periodically calls yield()) is running. --- source/vibe/core/taskpool.d | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/source/vibe/core/taskpool.d b/source/vibe/core/taskpool.d index ebf3816..ff56aba 100644 --- a/source/vibe/core/taskpool.d +++ b/source/vibe/core/taskpool.d @@ -346,7 +346,16 @@ private final class WorkerThread : Thread { try { if (m_pool.m_state.lock.term) return; logDebug("entering worker thread"); - handleWorkerTasks(); + + // There is an issue where a task that periodically calls yield() + // but otherwise only performs a CPU computation will cause a + // call to runEventLoopOnce() or yield() called from the global + // thread context to not return before the task is finished. For + // this reason we start a task here, which in turn is scheduled + // properly together with such a task, and also is schduled + // according to the task priorities. + runTask(&handleWorkerTasks).joinUninterruptible(); + logDebug("Worker thread exit."); } catch (Throwable th) { th.logException!(LogLevel.fatal)("Worker thread terminated due to uncaught error"); From f8a6044dba1ac89082a82c1bdd62346e4602b5c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6nke=20Ludwig?= Date: Fri, 18 Dec 2020 14:11:29 +0100 Subject: [PATCH 2/2] Avoid modern contract syntax. --- source/vibe/core/sync.d | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/vibe/core/sync.d b/source/vibe/core/sync.d index 9f29d4b..a636ace 100644 --- a/source/vibe/core/sync.d +++ b/source/vibe/core/sync.d @@ -132,7 +132,7 @@ struct ScopedMutexLock(M) @property bool locked() const { return m_locked; } void unlock() - in (this.locked) + in { assert(this.locked); } do { enforce(m_locked); m_mutex.unlock(); @@ -140,13 +140,13 @@ struct ScopedMutexLock(M) } bool tryLock() - in (!this.locked) + in { assert(!this.locked); } do { return m_locked = m_mutex.tryLock(); } void lock() - in (!this.locked) + in { assert(!this.locked); } do { m_locked = true; m_mutex.lock();