3
0
mirror of https://github.com/ergochat/ergo.git synced 2024-11-22 11:59:40 +01:00

use new aligned atomic types everywhere

See 69448b13a1 / #1969; the compiler can now ensure that a uint64
intended for atomic access is always aligned to a 64-bit boundary.
Convert atomic operations on uint32s and pointers as well.
This commit is contained in:
Shivaram Lingamneni 2022-08-10 02:47:39 -04:00
parent 507dc2d838
commit 35128bfc23
6 changed files with 25 additions and 27 deletions

View File

@ -165,7 +165,7 @@ type Session struct {
sasl saslStatus sasl saslStatus
passStatus serverPassStatus passStatus serverPassStatus
batchCounter uint32 batchCounter atomic.Uint32
quitMessage string quitMessage string
@ -262,7 +262,7 @@ func (session *Session) HasHistoryCaps() bool {
// or nesting) on an individual session connection need to be unique. // or nesting) on an individual session connection need to be unique.
// this allows ~4 billion such batches which should be fine. // this allows ~4 billion such batches which should be fine.
func (session *Session) generateBatchID() string { func (session *Session) generateBatchID() string {
id := atomic.AddUint32(&session.batchCounter, 1) id := session.batchCounter.Add(1)
return strconv.FormatInt(int64(id), 32) return strconv.FormatInt(int64(id), 32)
} }

View File

@ -6,7 +6,6 @@ package irc
import ( import (
"fmt" "fmt"
"net" "net"
"sync/atomic"
"time" "time"
"github.com/ergochat/ergo/irc/caps" "github.com/ergochat/ergo/irc/caps"
@ -36,11 +35,11 @@ func (server *Server) Languages() (lm *languages.Manager) {
} }
func (server *Server) Defcon() uint32 { func (server *Server) Defcon() uint32 {
return atomic.LoadUint32(&server.defcon) return server.defcon.Load()
} }
func (server *Server) SetDefcon(defcon uint32) { func (server *Server) SetDefcon(defcon uint32) {
atomic.StoreUint32(&server.defcon, defcon) server.defcon.Store(defcon)
} }
func (client *Client) Sessions() (sessions []*Session) { func (client *Client) Sessions() (sessions []*Session) {

View File

@ -69,7 +69,7 @@ type Manager struct {
loggers []singleLogger loggers []singleLogger
stdoutWriteLock sync.Mutex // use one lock for both stdout and stderr stdoutWriteLock sync.Mutex // use one lock for both stdout and stderr
fileWriteLock sync.Mutex fileWriteLock sync.Mutex
loggingRawIO uint32 loggingRawIO atomic.Uint32
} }
// LoggingConfig represents the configuration of a single logger. // LoggingConfig represents the configuration of a single logger.
@ -107,7 +107,7 @@ func (logger *Manager) ApplyConfig(config []LoggingConfig) error {
} }
logger.loggers = nil logger.loggers = nil
atomic.StoreUint32(&logger.loggingRawIO, 0) logger.loggingRawIO.Store(0)
// for safety, this deep-copies all mutable data in `config` // for safety, this deep-copies all mutable data in `config`
// XXX let's keep it that way // XXX let's keep it that way
@ -138,7 +138,7 @@ func (logger *Manager) ApplyConfig(config []LoggingConfig) error {
ioEnabled := typeMap["userinput"] || typeMap["useroutput"] || (typeMap["*"] && !(excludedTypeMap["userinput"] && excludedTypeMap["useroutput"])) ioEnabled := typeMap["userinput"] || typeMap["useroutput"] || (typeMap["*"] && !(excludedTypeMap["userinput"] && excludedTypeMap["useroutput"]))
// raw I/O is only logged at level debug; // raw I/O is only logged at level debug;
if ioEnabled && logConfig.Level == LogDebug { if ioEnabled && logConfig.Level == LogDebug {
atomic.StoreUint32(&logger.loggingRawIO, 1) logger.loggingRawIO.Store(1)
} }
if sLogger.MethodFile.Enabled { if sLogger.MethodFile.Enabled {
file, err := os.OpenFile(sLogger.MethodFile.Filename, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0666) file, err := os.OpenFile(sLogger.MethodFile.Filename, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0666)
@ -157,7 +157,7 @@ func (logger *Manager) ApplyConfig(config []LoggingConfig) error {
// IsLoggingRawIO returns true if raw user input and output is being logged. // IsLoggingRawIO returns true if raw user input and output is being logged.
func (logger *Manager) IsLoggingRawIO() bool { func (logger *Manager) IsLoggingRawIO() bool {
return atomic.LoadUint32(&logger.loggingRawIO) == 1 return logger.loggingRawIO.Load() == 1
} }
// Log logs the given message with the given details. // Log logs the given message with the given details.

View File

@ -45,10 +45,8 @@ const (
type e struct{} type e struct{}
type MySQL struct { type MySQL struct {
timeout *int64 db *sql.DB
trackAccountMessages uint32 logger *logger.Manager
db *sql.DB
logger *logger.Manager
insertHistory *sql.Stmt insertHistory *sql.Stmt
insertSequence *sql.Stmt insertSequence *sql.Stmt
@ -60,22 +58,24 @@ type MySQL struct {
config Config config Config
wakeForgetter chan e wakeForgetter chan e
timeout atomic.Uint64
trackAccountMessages atomic.Uint32
} }
func (mysql *MySQL) Initialize(logger *logger.Manager, config Config) { func (mysql *MySQL) Initialize(logger *logger.Manager, config Config) {
mysql.timeout = new(int64)
mysql.logger = logger mysql.logger = logger
mysql.wakeForgetter = make(chan e, 1) mysql.wakeForgetter = make(chan e, 1)
mysql.SetConfig(config) mysql.SetConfig(config)
} }
func (mysql *MySQL) SetConfig(config Config) { func (mysql *MySQL) SetConfig(config Config) {
atomic.StoreInt64(mysql.timeout, int64(config.Timeout)) mysql.timeout.Store(uint64(config.Timeout))
var trackAccountMessages uint32 var trackAccountMessages uint32
if config.TrackAccountMessages { if config.TrackAccountMessages {
trackAccountMessages = 1 trackAccountMessages = 1
} }
atomic.StoreUint32(&mysql.trackAccountMessages, trackAccountMessages) mysql.trackAccountMessages.Store(trackAccountMessages)
mysql.stateMutex.Lock() mysql.stateMutex.Lock()
mysql.config = config mysql.config = config
mysql.stateMutex.Unlock() mysql.stateMutex.Unlock()
@ -555,11 +555,11 @@ func (mysql *MySQL) prepareStatements() (err error) {
} }
func (mysql *MySQL) getTimeout() time.Duration { func (mysql *MySQL) getTimeout() time.Duration {
return time.Duration(atomic.LoadInt64(mysql.timeout)) return time.Duration(mysql.timeout.Load())
} }
func (mysql *MySQL) isTrackingAccountMessages() bool { func (mysql *MySQL) isTrackingAccountMessages() bool {
return atomic.LoadUint32(&mysql.trackAccountMessages) != 0 return mysql.trackAccountMessages.Load() != 0
} }
func (mysql *MySQL) logError(context string, err error) (quit bool) { func (mysql *MySQL) logError(context string, err error) (quit bool) {

View File

@ -91,7 +91,7 @@ type Server struct {
stats Stats stats Stats
semaphores ServerSemaphores semaphores ServerSemaphores
flock flock.Flocker flock flock.Flocker
defcon uint32 defcon atomic.Uint32
} }
// NewServer returns a new Oragono server. // NewServer returns a new Oragono server.
@ -103,8 +103,8 @@ func NewServer(config *Config, logger *logger.Manager) (*Server, error) {
logger: logger, logger: logger,
rehashSignal: make(chan os.Signal, 1), rehashSignal: make(chan os.Signal, 1),
exitSignals: make(chan os.Signal, len(utils.ServerExitSignals)), exitSignals: make(chan os.Signal, len(utils.ServerExitSignals)),
defcon: 5,
} }
server.defcon.Store(5)
server.accepts.Initialize() server.accepts.Initialize()
server.clients.Initialize() server.clients.Initialize()

View File

@ -11,7 +11,6 @@ import (
"sync" "sync"
"sync/atomic" "sync/atomic"
"time" "time"
"unsafe"
"github.com/ergochat/ergo/irc/utils" "github.com/ergochat/ergo/irc/utils"
) )
@ -27,8 +26,8 @@ type UserMaskSet struct {
sync.RWMutex sync.RWMutex
serialCacheUpdateMutex sync.Mutex serialCacheUpdateMutex sync.Mutex
masks map[string]MaskInfo masks map[string]MaskInfo
regexp unsafe.Pointer regexp atomic.Pointer[regexp.Regexp]
muteRegexp unsafe.Pointer muteRegexp atomic.Pointer[regexp.Regexp]
} }
func NewUserMaskSet() *UserMaskSet { func NewUserMaskSet() *UserMaskSet {
@ -110,7 +109,7 @@ func (set *UserMaskSet) Masks() (result map[string]MaskInfo) {
// Match matches the given n!u@h against the standard (non-ext) bans. // Match matches the given n!u@h against the standard (non-ext) bans.
func (set *UserMaskSet) Match(userhost string) bool { func (set *UserMaskSet) Match(userhost string) bool {
regexp := (*regexp.Regexp)(atomic.LoadPointer(&set.regexp)) regexp := set.regexp.Load()
if regexp == nil { if regexp == nil {
return false return false
@ -129,7 +128,7 @@ func (set *UserMaskSet) MatchMute(userhost string) bool {
} }
func (set *UserMaskSet) MuteRegexp() *regexp.Regexp { func (set *UserMaskSet) MuteRegexp() *regexp.Regexp {
return (*regexp.Regexp)(atomic.LoadPointer(&set.muteRegexp)) return set.muteRegexp.Load()
} }
func (set *UserMaskSet) Length() int { func (set *UserMaskSet) Length() int {
@ -162,6 +161,6 @@ func (set *UserMaskSet) setRegexp() {
re := compileMasks(maskExprs) re := compileMasks(maskExprs)
muteRe := compileMasks(muteExprs) muteRe := compileMasks(muteExprs)
atomic.StorePointer(&set.regexp, unsafe.Pointer(re)) set.regexp.Store(re)
atomic.StorePointer(&set.muteRegexp, unsafe.Pointer(muteRe)) set.muteRegexp.Store(muteRe)
} }