From a99c8a42f9bd66939a547364cdb24743ca7bbfcb Mon Sep 17 00:00:00 2001 From: Shivaram Lingamneni Date: Wed, 3 Aug 2022 00:59:00 -0400 Subject: [PATCH] remove utils.ConfigStore in favor of atomic.Pointer[T] --- irc/getters.go | 2 +- irc/server.go | 5 +++-- irc/utils/config.go | 33 --------------------------------- 3 files changed, 4 insertions(+), 36 deletions(-) delete mode 100644 irc/utils/config.go diff --git a/irc/getters.go b/irc/getters.go index 6031659f..6e5718b6 100644 --- a/irc/getters.go +++ b/irc/getters.go @@ -16,7 +16,7 @@ import ( ) func (server *Server) Config() (config *Config) { - return server.config.Get() + return server.config.Load() } func (server *Server) ChannelRegistrationEnabled() bool { diff --git a/irc/server.go b/irc/server.go index b4bce531..95c20eda 100644 --- a/irc/server.go +++ b/irc/server.go @@ -15,6 +15,7 @@ import ( "strconv" "strings" "sync" + "sync/atomic" "syscall" "time" @@ -66,7 +67,7 @@ type Server struct { channels ChannelManager channelRegistry ChannelRegistry clients ClientManager - config utils.ConfigStore[Config] + config atomic.Pointer[Config] configFilename string connectionLimiter connection_limits.Limiter ctime time.Time @@ -707,7 +708,7 @@ func (server *Server) applyConfig(config *Config) (err error) { config.Server.Cloaks.SetSecret(LoadCloakSecret(server.store)) // activate the new config - server.config.Set(config) + server.config.Store(config) // load [dk]-lines, registered users and channels, etc. if initial { diff --git a/irc/utils/config.go b/irc/utils/config.go deleted file mode 100644 index 73fd7165..00000000 --- a/irc/utils/config.go +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright (c) 2022 Shivaram Lingamneni -// released under the MIT license - -package utils - -import ( - "sync/atomic" - "unsafe" -) - -/* -This can be used to implement the following pattern: - -1. Prepare a config object (this can be arbitrarily expensive) -2. Take a pointer to the config object and use Set() to install it -3. Use Get() to access the config from any goroutine -4. To update the config, call Set() again with a new prepared config object -5. As long as any individual config object is not modified (by any goroutine) - after it is installed with Set(), this is free of data races, and Get() - is extremely cheap (on amd64 it compiles down to plain MOV instructions). -*/ - -type ConfigStore[Config any] struct { - ptr unsafe.Pointer -} - -func (c *ConfigStore[Config]) Get() *Config { - return (*Config)(atomic.LoadPointer(&c.ptr)) -} - -func (c *ConfigStore[Config]) Set(ptr *Config) { - atomic.StorePointer(&c.ptr, unsafe.Pointer(ptr)) -}