From 7cb6a01dff9157f3f3dca36aa0152f144023ff60 Mon Sep 17 00:00:00 2001 From: AngelicosPhosphoros Date: Tue, 2 Jan 2024 01:57:23 +0100 Subject: [PATCH] Use `Acquire` ordering for initialization check Reasoning is provided in the code comment. --- src/lib.rs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index ad61e3ea8..6a3a8ca98 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1455,7 +1455,15 @@ impl error::Error for ParseLevelError {} /// /// If a logger has not been set, a no-op implementation is returned. pub fn logger() -> &'static dyn Log { - if STATE.load(Ordering::SeqCst) != INITIALIZED { + // Acquire memory ordering guarantees that current thread would see any + // memory writes that happened before store of the value + // into `STATE` with memory ordering `Release` or stronger. + // + // Since the value `INITIALIZED` is written only after `LOGGER` was + // initialized, observing it after `Acquire` load here makes both + // write to the `LOGGER` static and initialization of the logger + // internal state synchronized with current thread. + if STATE.load(Ordering::Acquire) != INITIALIZED { static NOP: NopLogger = NopLogger; &NOP } else {