From 83f1e8736aea73ab0c57239610de356eb63d6d86 Mon Sep 17 00:00:00 2001 From: Tor Colvin Date: Wed, 10 Jan 2024 14:57:28 -0500 Subject: [PATCH] Use an atomic for one time logging initialization --- rest/config.go | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/rest/config.go b/rest/config.go index b903b16687..b89b626aea 100644 --- a/rest/config.go +++ b/rest/config.go @@ -25,8 +25,8 @@ import ( "strconv" "strings" "sync" + "sync/atomic" "syscall" - "testing" "time" "golang.org/x/crypto/bcrypt" @@ -48,6 +48,9 @@ var ( // The value of defaultLogFilePath is populated by -defaultLogFilePath by command line flag from service scripts. defaultLogFilePath string + + // serverContextLoggingInitialized is set the first time that logging has been initialized + serverContextLoggingInitialized = atomic.Bool{} ) const ( @@ -1345,8 +1348,10 @@ func (sc *StartupConfig) Validate(ctx context.Context, isEnterpriseEdition bool) // SetupServerContext creates a new ServerContext given its configuration and performs the context validation. func SetupServerContext(ctx context.Context, config *StartupConfig, persistentConfig bool) (*ServerContext, error) { - // This logging is global, so do not reinitialize for test logs. - if !testing.Testing() { + // If SetupServerContext is called while any other go routines that might use logging are running, it will + // cause a data race, therefore only initialize logging on the first call. From a main program, there is + // only one ServerContext. + if serverContextLoggingInitialized.CompareAndSwap(false, true) { // Logging config will now have been loaded from command line // or from a sync_gateway config file so we can validate the // configuration and setup logging now