From 5842c3d8d31ede5db86870c5672ee762ebf42356 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6nke=20Ludwig?= Date: Sat, 27 Jul 2024 17:00:53 +0200 Subject: [PATCH] Add an implementation note about concurrent loggers. Fixes #176. --- source/vibe/core/connectionpool.d | 6 ++++++ source/vibe/core/log.d | 19 ++++++++++++++++++- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/source/vibe/core/connectionpool.d b/source/vibe/core/connectionpool.d index ca8ef901..d4aded23 100644 --- a/source/vibe/core/connectionpool.d +++ b/source/vibe/core/connectionpool.d @@ -266,8 +266,12 @@ struct LockedConnection(Connection) { ~this() { + import core.memory : GC; + debug assert(m_magic == 0xB1345AC2, "LockedConnection value corrupted."); if (!!m_conn) { + if (GC.inFinalizer) onInvalidMemoryOperationError(); + auto plc = m_conn in m_pool.m_lockCount; assert(plc !is null); assert(*plc != 0); @@ -291,6 +295,8 @@ struct LockedConnection(Connection) { alias __conn this; } +private extern(C) void onInvalidMemoryOperationError() @safe nothrow; + /// unittest { int id = 0; diff --git a/source/vibe/core/log.d b/source/vibe/core/log.d index c2872da9..1e376ca8 100644 --- a/source/vibe/core/log.d +++ b/source/vibe/core/log.d @@ -270,7 +270,24 @@ struct LogLine { string text; /// Legacy field used in `Logger.log` } -/// Abstract base class for all loggers +/** Abstract base class for all loggers + + Concurrency_requirements: + + Classes derived from `Logger` must be implemented in a thread-safe way. + Although the methods of `Logger` are not annotated with `shared` due to + historic reasons, they should be treated as if they were. + + Also, none of the methods must, explicitly or implicitly, yield + execution (e.g. by calling `vibe.core.yield` or performing vibe.d based + I/O or wait operations). In cases where a logger needs to perform + blocking I/O that may degrade performance of the calling thread, for + example by sending over the network, a separate writer thread should be + used in conjunction with a queue. The synchronization of this queue must + use classical synchronization primitives, such as `core.sync.Mutex`, + instead of the ones in `vibe.core.sync`. See `SyslogLogger` for an + example of such an implementation. +*/ class Logger { LogLevel minLevel = LogLevel.min;