From a9b64a3956b5680f6b9b48ce47a83836a089e599 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6nke=20Ludwig?= Date: Mon, 5 Aug 2024 17:23:52 +0200 Subject: [PATCH 1/2] Add assertion messages. --- source/vibe/core/task.d | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/source/vibe/core/task.d b/source/vibe/core/task.d index 43e99b0..6c9f214 100644 --- a/source/vibe/core/task.d +++ b/source/vibe/core/task.d @@ -707,18 +707,20 @@ final package class TaskFiber : Fiber { @safe nothrow @nogc { // only record the outermost lock if (m_yieldLockCount > 0) return; + assert (m_yieldLockCount == 0, "Yield lock counter negative!?"); m_yieldLockFile = file; m_yieldLockLine = line; } package void acquireYieldLock() @safe nothrow @nogc { + assert (m_yieldLockCount >= 0, "Acquiring yield lock with negative yield lock counter!?"); m_yieldLockCount++; } package void releaseYieldLock() @safe nothrow @nogc { - assert(m_yieldLockCount > 0); + assert (m_yieldLockCount > 0, "Releasing yield lock with non-positive yield lock counter!?"); if (!--m_yieldLockCount) { m_yieldLockFile = null; m_yieldLockLine = -1; @@ -729,7 +731,7 @@ final package class TaskFiber : Fiber { @safe nothrow { if (m_yieldLockCount > 0 && m_yieldLockFile.length) logError("Yield lock violation for lock at %s:%s", m_yieldLockFile, m_yieldLockLine); - assert(m_yieldLockCount == 0, "May not yield while in an active yieldLock()!"); + assert (m_yieldLockCount == 0, "May not yield while in an active yieldLock()!"); } package bool isInYieldLock() From 0c9882365b90aeb4f2d87289bcf47507a9aef5cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6nke=20Ludwig?= Date: Mon, 5 Aug 2024 17:25:20 +0200 Subject: [PATCH 2/2] Only yield lock in tasks for logging. Avoids the creation of dummy TaskFiber objects and occasional yield lock count corruptions (?) happening when logging from non-D threads. The latter should be investigated further, but so far has proven difficult to diagnose. --- source/vibe/core/core.d | 9 +++++++++ source/vibe/core/log.d | 8 ++++---- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/source/vibe/core/core.d b/source/vibe/core/core.d index ea65359..107ebad 100644 --- a/source/vibe/core/core.d +++ b/source/vibe/core/core.d @@ -1660,6 +1660,15 @@ unittest { assert(!tf.isInYieldLock()); } + +/** Less strict version of `yieldLock` that only locks if called within a task. +*/ +auto taskYieldLock(string file = __FILE__, int line = __LINE__) +@safe nothrow { + if (!Fiber.getThis()) return typeof(yieldLock()).init; + return yieldLock(file, line); +} + debug (VibeRunningTasks) { /** Dumps a list of all active tasks of the calling thread. */ diff --git a/source/vibe/core/log.d b/source/vibe/core/log.d index 8d2a42a..e5e85cc 100644 --- a/source/vibe/core/log.d +++ b/source/vibe/core/log.d @@ -1075,7 +1075,7 @@ unittest { // ensure arguments are evaluated lazily } private struct LogOutputRange { - import vibe.core.core : yieldLock; + import vibe.core.core : taskYieldLock; LogLine info; ScopedLock!Logger* logger; @@ -1084,7 +1084,7 @@ private struct LogOutputRange { this(ref ScopedLock!Logger logger, string file, int line, LogLevel level) { - auto l = yieldLock(); + auto l = taskYieldLock(); () @trusted { this.logger = &logger; } (); try { @@ -1111,7 +1111,7 @@ private struct LogOutputRange { void finalize() { - auto l = yieldLock(); + auto l = taskYieldLock(); logger.endLine(); } @@ -1121,7 +1121,7 @@ private struct LogOutputRange { if (text.empty) return; - auto l = yieldLock(); + auto l = taskYieldLock(); if (logger.multilineLogger) { logger.put(text);