Browse Source

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.
tags/v2.11.0-rc1
Shivaram Lingamneni 1 year ago
parent
commit
35128bfc23
6 changed files with 25 additions and 27 deletions
  1. 2
    2
      irc/client.go
  2. 2
    3
      irc/getters.go
  3. 4
    4
      irc/logger/logger.go
  4. 9
    9
      irc/mysql/history.go
  5. 2
    2
      irc/server.go
  6. 6
    7
      irc/usermaskset.go

+ 2
- 2
irc/client.go View File

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

+ 2
- 3
irc/getters.go View File

@@ -6,7 +6,6 @@ package irc
6 6
 import (
7 7
 	"fmt"
8 8
 	"net"
9
-	"sync/atomic"
10 9
 	"time"
11 10
 
12 11
 	"github.com/ergochat/ergo/irc/caps"
@@ -36,11 +35,11 @@ func (server *Server) Languages() (lm *languages.Manager) {
36 35
 }
37 36
 
38 37
 func (server *Server) Defcon() uint32 {
39
-	return atomic.LoadUint32(&server.defcon)
38
+	return server.defcon.Load()
40 39
 }
41 40
 
42 41
 func (server *Server) SetDefcon(defcon uint32) {
43
-	atomic.StoreUint32(&server.defcon, defcon)
42
+	server.defcon.Store(defcon)
44 43
 }
45 44
 
46 45
 func (client *Client) Sessions() (sessions []*Session) {

+ 4
- 4
irc/logger/logger.go View File

@@ -69,7 +69,7 @@ type Manager struct {
69 69
 	loggers         []singleLogger
70 70
 	stdoutWriteLock sync.Mutex // use one lock for both stdout and stderr
71 71
 	fileWriteLock   sync.Mutex
72
-	loggingRawIO    uint32
72
+	loggingRawIO    atomic.Uint32
73 73
 }
74 74
 
75 75
 // LoggingConfig represents the configuration of a single logger.
@@ -107,7 +107,7 @@ func (logger *Manager) ApplyConfig(config []LoggingConfig) error {
107 107
 	}
108 108
 
109 109
 	logger.loggers = nil
110
-	atomic.StoreUint32(&logger.loggingRawIO, 0)
110
+	logger.loggingRawIO.Store(0)
111 111
 
112 112
 	// for safety, this deep-copies all mutable data in `config`
113 113
 	// XXX let's keep it that way
@@ -138,7 +138,7 @@ func (logger *Manager) ApplyConfig(config []LoggingConfig) error {
138 138
 		ioEnabled := typeMap["userinput"] || typeMap["useroutput"] || (typeMap["*"] && !(excludedTypeMap["userinput"] && excludedTypeMap["useroutput"]))
139 139
 		// raw I/O is only logged at level debug;
140 140
 		if ioEnabled && logConfig.Level == LogDebug {
141
-			atomic.StoreUint32(&logger.loggingRawIO, 1)
141
+			logger.loggingRawIO.Store(1)
142 142
 		}
143 143
 		if sLogger.MethodFile.Enabled {
144 144
 			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 {
157 157
 
158 158
 // IsLoggingRawIO returns true if raw user input and output is being logged.
159 159
 func (logger *Manager) IsLoggingRawIO() bool {
160
-	return atomic.LoadUint32(&logger.loggingRawIO) == 1
160
+	return logger.loggingRawIO.Load() == 1
161 161
 }
162 162
 
163 163
 // Log logs the given message with the given details.

+ 9
- 9
irc/mysql/history.go View File

@@ -45,10 +45,8 @@ const (
45 45
 type e struct{}
46 46
 
47 47
 type MySQL struct {
48
-	timeout              *int64
49
-	trackAccountMessages uint32
50
-	db                   *sql.DB
51
-	logger               *logger.Manager
48
+	db     *sql.DB
49
+	logger *logger.Manager
52 50
 
53 51
 	insertHistory        *sql.Stmt
54 52
 	insertSequence       *sql.Stmt
@@ -60,22 +58,24 @@ type MySQL struct {
60 58
 	config     Config
61 59
 
62 60
 	wakeForgetter chan e
61
+
62
+	timeout              atomic.Uint64
63
+	trackAccountMessages atomic.Uint32
63 64
 }
64 65
 
65 66
 func (mysql *MySQL) Initialize(logger *logger.Manager, config Config) {
66
-	mysql.timeout = new(int64)
67 67
 	mysql.logger = logger
68 68
 	mysql.wakeForgetter = make(chan e, 1)
69 69
 	mysql.SetConfig(config)
70 70
 }
71 71
 
72 72
 func (mysql *MySQL) SetConfig(config Config) {
73
-	atomic.StoreInt64(mysql.timeout, int64(config.Timeout))
73
+	mysql.timeout.Store(uint64(config.Timeout))
74 74
 	var trackAccountMessages uint32
75 75
 	if config.TrackAccountMessages {
76 76
 		trackAccountMessages = 1
77 77
 	}
78
-	atomic.StoreUint32(&mysql.trackAccountMessages, trackAccountMessages)
78
+	mysql.trackAccountMessages.Store(trackAccountMessages)
79 79
 	mysql.stateMutex.Lock()
80 80
 	mysql.config = config
81 81
 	mysql.stateMutex.Unlock()
@@ -555,11 +555,11 @@ func (mysql *MySQL) prepareStatements() (err error) {
555 555
 }
556 556
 
557 557
 func (mysql *MySQL) getTimeout() time.Duration {
558
-	return time.Duration(atomic.LoadInt64(mysql.timeout))
558
+	return time.Duration(mysql.timeout.Load())
559 559
 }
560 560
 
561 561
 func (mysql *MySQL) isTrackingAccountMessages() bool {
562
-	return atomic.LoadUint32(&mysql.trackAccountMessages) != 0
562
+	return mysql.trackAccountMessages.Load() != 0
563 563
 }
564 564
 
565 565
 func (mysql *MySQL) logError(context string, err error) (quit bool) {

+ 2
- 2
irc/server.go View File

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

+ 6
- 7
irc/usermaskset.go View File

@@ -11,7 +11,6 @@ import (
11 11
 	"sync"
12 12
 	"sync/atomic"
13 13
 	"time"
14
-	"unsafe"
15 14
 
16 15
 	"github.com/ergochat/ergo/irc/utils"
17 16
 )
@@ -27,8 +26,8 @@ type UserMaskSet struct {
27 26
 	sync.RWMutex
28 27
 	serialCacheUpdateMutex sync.Mutex
29 28
 	masks                  map[string]MaskInfo
30
-	regexp                 unsafe.Pointer
31
-	muteRegexp             unsafe.Pointer
29
+	regexp                 atomic.Pointer[regexp.Regexp]
30
+	muteRegexp             atomic.Pointer[regexp.Regexp]
32 31
 }
33 32
 
34 33
 func NewUserMaskSet() *UserMaskSet {
@@ -110,7 +109,7 @@ func (set *UserMaskSet) Masks() (result map[string]MaskInfo) {
110 109
 
111 110
 // Match matches the given n!u@h against the standard (non-ext) bans.
112 111
 func (set *UserMaskSet) Match(userhost string) bool {
113
-	regexp := (*regexp.Regexp)(atomic.LoadPointer(&set.regexp))
112
+	regexp := set.regexp.Load()
114 113
 
115 114
 	if regexp == nil {
116 115
 		return false
@@ -129,7 +128,7 @@ func (set *UserMaskSet) MatchMute(userhost string) bool {
129 128
 }
130 129
 
131 130
 func (set *UserMaskSet) MuteRegexp() *regexp.Regexp {
132
-	return (*regexp.Regexp)(atomic.LoadPointer(&set.muteRegexp))
131
+	return set.muteRegexp.Load()
133 132
 }
134 133
 
135 134
 func (set *UserMaskSet) Length() int {
@@ -162,6 +161,6 @@ func (set *UserMaskSet) setRegexp() {
162 161
 	re := compileMasks(maskExprs)
163 162
 	muteRe := compileMasks(muteExprs)
164 163
 
165
-	atomic.StorePointer(&set.regexp, unsafe.Pointer(re))
166
-	atomic.StorePointer(&set.muteRegexp, unsafe.Pointer(muteRe))
164
+	set.regexp.Store(re)
165
+	set.muteRegexp.Store(muteRe)
167 166
 }

Loading…
Cancel
Save