From e31f99cb9843b204b21c1e06b87b154369702968 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96rjan=20Fors?= Date: Fri, 3 May 2024 09:59:43 +0200 Subject: [PATCH] fix: fix data race in Default and SetDefault Fixes: https://github.com/charmbracelet/log/issues/121 --- pkg.go | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/pkg.go b/pkg.go index 9100b48..9e083a3 100644 --- a/pkg.go +++ b/pkg.go @@ -7,6 +7,7 @@ import ( "log" "os" "sync" + "sync/atomic" "time" "github.com/muesli/termenv" @@ -17,25 +18,27 @@ var ( registry = sync.Map{} // defaultLogger is the default global logger instance. + defaultLogger atomic.Pointer[Logger] defaultLoggerOnce sync.Once - defaultLogger *Logger ) // Default returns the default logger. The default logger comes with timestamp enabled. func Default() *Logger { - defaultLoggerOnce.Do(func() { - if defaultLogger != nil { - // already set via SetDefault. - return - } - defaultLogger = NewWithOptions(os.Stderr, Options{ReportTimestamp: true}) - }) - return defaultLogger + dl := defaultLogger.Load() + if dl == nil { + defaultLoggerOnce.Do(func() { + defaultLogger.CompareAndSwap( + nil, NewWithOptions(os.Stderr, Options{ReportTimestamp: true}), + ) + }) + dl = defaultLogger.Load() + } + return dl } // SetDefault sets the default global logger. func SetDefault(logger *Logger) { - defaultLogger = logger + defaultLogger.Store(logger) } // New returns a new logger with the default options.