Pārlūkot izejas kodu

replace some utils.Semaphore with (*sync.Mutex).TryLock

See #1994
tags/v2.11.0-rc1
Shivaram Lingamneni 1 gadu atpakaļ
vecāks
revīzija
746309e386
3 mainītis faili ar 39 papildinājumiem un 46 dzēšanām
  1. 16
    17
      irc/channel.go
  2. 15
    18
      irc/client.go
  3. 8
    11
      irc/socket.go

+ 16
- 17
irc/channel.go Parādīt failu

47
 	userLimit         int
47
 	userLimit         int
48
 	accountToUMode    map[string]modes.Mode
48
 	accountToUMode    map[string]modes.Mode
49
 	history           history.Buffer
49
 	history           history.Buffer
50
-	stateMutex        sync.RWMutex    // tier 1
51
-	writerSemaphore   utils.Semaphore // tier 1.5
52
-	joinPartMutex     sync.Mutex      // tier 3
53
-	ensureLoaded      utils.Once      // manages loading stored registration info from the database
50
+	stateMutex        sync.RWMutex // tier 1
51
+	writebackLock     sync.Mutex   // tier 1.5
52
+	joinPartMutex     sync.Mutex   // tier 3
53
+	ensureLoaded      utils.Once   // manages loading stored registration info from the database
54
 	dirtyBits         uint
54
 	dirtyBits         uint
55
 	settings          ChannelSettings
55
 	settings          ChannelSettings
56
 }
56
 }
61
 	config := s.Config()
61
 	config := s.Config()
62
 
62
 
63
 	channel := &Channel{
63
 	channel := &Channel{
64
-		createdTime:     time.Now().UTC(), // may be overwritten by applyRegInfo
65
-		members:         make(MemberSet),
66
-		name:            name,
67
-		nameCasefolded:  casefoldedName,
68
-		server:          s,
69
-		writerSemaphore: utils.NewSemaphore(1),
64
+		createdTime:    time.Now().UTC(), // may be overwritten by applyRegInfo
65
+		members:        make(MemberSet),
66
+		name:           name,
67
+		nameCasefolded: casefoldedName,
68
+		server:         s,
70
 	}
69
 	}
71
 
70
 
72
 	channel.initializeLists()
71
 	channel.initializeLists()
209
 // ChannelManager's lock (that way, no one can join and make the channel dirty again
208
 // ChannelManager's lock (that way, no one can join and make the channel dirty again
210
 // between this method exiting and the actual deletion).
209
 // between this method exiting and the actual deletion).
211
 func (channel *Channel) IsClean() bool {
210
 func (channel *Channel) IsClean() bool {
212
-	if !channel.writerSemaphore.TryAcquire() {
211
+	if !channel.writebackLock.TryLock() {
213
 		// a database write (which may fail) is in progress, the channel cannot be cleaned up
212
 		// a database write (which may fail) is in progress, the channel cannot be cleaned up
214
 		return false
213
 		return false
215
 	}
214
 	}
216
-	defer channel.writerSemaphore.Release()
215
+	defer channel.writebackLock.Unlock()
217
 
216
 
218
 	channel.stateMutex.RLock()
217
 	channel.stateMutex.RLock()
219
 	defer channel.stateMutex.RUnlock()
218
 	defer channel.stateMutex.RUnlock()
225
 }
224
 }
226
 
225
 
227
 func (channel *Channel) wakeWriter() {
226
 func (channel *Channel) wakeWriter() {
228
-	if channel.writerSemaphore.TryAcquire() {
227
+	if channel.writebackLock.TryLock() {
229
 		go channel.writeLoop()
228
 		go channel.writeLoop()
230
 	}
229
 	}
231
 }
230
 }
235
 	for {
234
 	for {
236
 		// TODO(#357) check the error value of this and implement timed backoff
235
 		// TODO(#357) check the error value of this and implement timed backoff
237
 		channel.performWrite(0)
236
 		channel.performWrite(0)
238
-		channel.writerSemaphore.Release()
237
+		channel.writebackLock.Unlock()
239
 
238
 
240
 		channel.stateMutex.RLock()
239
 		channel.stateMutex.RLock()
241
 		isDirty := channel.dirtyBits != 0
240
 		isDirty := channel.dirtyBits != 0
249
 			return // nothing to do
248
 			return // nothing to do
250
 		} // else: isDirty, so we need to write again
249
 		} // else: isDirty, so we need to write again
251
 
250
 
252
-		if !channel.writerSemaphore.TryAcquire() {
251
+		if !channel.writebackLock.TryLock() {
253
 			return
252
 			return
254
 		}
253
 		}
255
 	}
254
 	}
272
 		}
271
 		}
273
 	}()
272
 	}()
274
 
273
 
275
-	channel.writerSemaphore.Acquire()
276
-	defer channel.writerSemaphore.Release()
274
+	channel.writebackLock.Lock()
275
+	defer channel.writebackLock.Unlock()
277
 	return channel.performWrite(dirtyBits)
276
 	return channel.performWrite(dirtyBits)
278
 }
277
 }
279
 
278
 

+ 15
- 18
irc/client.go Parādīt failu

113
 	vhost              string
113
 	vhost              string
114
 	history            history.Buffer
114
 	history            history.Buffer
115
 	dirtyBits          uint
115
 	dirtyBits          uint
116
-	writerSemaphore    utils.Semaphore // tier 1.5
116
+	writebackLock      sync.Mutex // tier 1.5
117
 }
117
 }
118
 
118
 
119
 type saslStatus struct {
119
 type saslStatus struct {
335
 			Duration: config.Accounts.LoginThrottling.Duration,
335
 			Duration: config.Accounts.LoginThrottling.Duration,
336
 			Limit:    config.Accounts.LoginThrottling.MaxAttempts,
336
 			Limit:    config.Accounts.LoginThrottling.MaxAttempts,
337
 		},
337
 		},
338
-		server:          server,
339
-		accountName:     "*",
340
-		nick:            "*", // * is used until actual nick is given
341
-		nickCasefolded:  "*",
342
-		nickMaskString:  "*", // * is used until actual nick is given
343
-		realIP:          realIP,
344
-		proxiedIP:       proxiedIP,
345
-		requireSASL:     requireSASL,
346
-		nextSessionID:   1,
347
-		writerSemaphore: utils.NewSemaphore(1),
338
+		server:         server,
339
+		accountName:    "*",
340
+		nick:           "*", // * is used until actual nick is given
341
+		nickCasefolded: "*",
342
+		nickMaskString: "*", // * is used until actual nick is given
343
+		realIP:         realIP,
344
+		proxiedIP:      proxiedIP,
345
+		requireSASL:    requireSASL,
346
+		nextSessionID:  1,
348
 	}
347
 	}
349
 	if requireSASL {
348
 	if requireSASL {
350
 		client.requireSASLMessage = banMsg
349
 		client.requireSASLMessage = banMsg
424
 		realname: realname,
423
 		realname: realname,
425
 
424
 
426
 		nextSessionID: 1,
425
 		nextSessionID: 1,
427
-
428
-		writerSemaphore: utils.NewSemaphore(1),
429
 	}
426
 	}
430
 
427
 
431
 	if client.checkAlwaysOnExpirationNoMutex(config, true) {
428
 	if client.checkAlwaysOnExpirationNoMutex(config, true) {
1772
 }
1769
 }
1773
 
1770
 
1774
 func (client *Client) wakeWriter() {
1771
 func (client *Client) wakeWriter() {
1775
-	if client.writerSemaphore.TryAcquire() {
1772
+	if client.writebackLock.TryLock() {
1776
 		go client.writeLoop()
1773
 		go client.writeLoop()
1777
 	}
1774
 	}
1778
 }
1775
 }
1780
 func (client *Client) writeLoop() {
1777
 func (client *Client) writeLoop() {
1781
 	for {
1778
 	for {
1782
 		client.performWrite(0)
1779
 		client.performWrite(0)
1783
-		client.writerSemaphore.Release()
1780
+		client.writebackLock.Unlock()
1784
 
1781
 
1785
 		client.stateMutex.RLock()
1782
 		client.stateMutex.RLock()
1786
 		isDirty := client.dirtyBits != 0
1783
 		isDirty := client.dirtyBits != 0
1787
 		client.stateMutex.RUnlock()
1784
 		client.stateMutex.RUnlock()
1788
 
1785
 
1789
-		if !isDirty || !client.writerSemaphore.TryAcquire() {
1786
+		if !isDirty || !client.writebackLock.TryLock() {
1790
 			return
1787
 			return
1791
 		}
1788
 		}
1792
 	}
1789
 	}
1844
 		}
1841
 		}
1845
 	}()
1842
 	}()
1846
 
1843
 
1847
-	client.writerSemaphore.Acquire()
1848
-	defer client.writerSemaphore.Release()
1844
+	client.writebackLock.Lock()
1845
+	defer client.writebackLock.Unlock()
1849
 	client.performWrite(dirtyBits)
1846
 	client.performWrite(dirtyBits)
1850
 	return nil
1847
 	return nil
1851
 }
1848
 }

+ 8
- 11
irc/socket.go Parādīt failu

8
 	"errors"
8
 	"errors"
9
 	"io"
9
 	"io"
10
 	"sync"
10
 	"sync"
11
-
12
-	"github.com/ergochat/ergo/irc/utils"
13
 )
11
 )
14
 
12
 
15
 var (
13
 var (
27
 	maxSendQBytes int
25
 	maxSendQBytes int
28
 
26
 
29
 	// this is a trylock enforcing that only one goroutine can write to `conn` at a time
27
 	// this is a trylock enforcing that only one goroutine can write to `conn` at a time
30
-	writerSemaphore utils.Semaphore
28
+	writeLock sync.Mutex
31
 
29
 
32
 	buffers       [][]byte
30
 	buffers       [][]byte
33
 	totalLength   int
31
 	totalLength   int
40
 // NewSocket returns a new Socket.
38
 // NewSocket returns a new Socket.
41
 func NewSocket(conn IRCConn, maxSendQBytes int) *Socket {
39
 func NewSocket(conn IRCConn, maxSendQBytes int) *Socket {
42
 	result := Socket{
40
 	result := Socket{
43
-		conn:            conn,
44
-		maxSendQBytes:   maxSendQBytes,
45
-		writerSemaphore: utils.NewSemaphore(1),
41
+		conn:          conn,
42
+		maxSendQBytes: maxSendQBytes,
46
 	}
43
 	}
47
 	return &result
44
 	return &result
48
 }
45
 }
128
 	}()
125
 	}()
129
 
126
 
130
 	// blocking acquire of the trylock
127
 	// blocking acquire of the trylock
131
-	socket.writerSemaphore.Acquire()
132
-	defer socket.writerSemaphore.Release()
128
+	socket.writeLock.Lock()
129
+	defer socket.writeLock.Unlock()
133
 
130
 
134
 	// first, flush any buffered data, to preserve the ordering guarantees
131
 	// first, flush any buffered data, to preserve the ordering guarantees
135
 	closed := socket.performWrite()
132
 	closed := socket.performWrite()
146
 
143
 
147
 // wakeWriter starts the goroutine that actually performs the write, without blocking
144
 // wakeWriter starts the goroutine that actually performs the write, without blocking
148
 func (socket *Socket) wakeWriter() {
145
 func (socket *Socket) wakeWriter() {
149
-	if socket.writerSemaphore.TryAcquire() {
146
+	if socket.writeLock.TryLock() {
150
 		// acquired the trylock; send() will release it
147
 		// acquired the trylock; send() will release it
151
 		go socket.send()
148
 		go socket.send()
152
 	}
149
 	}
182
 		socket.performWrite()
179
 		socket.performWrite()
183
 		// surrender the trylock, avoiding a race where a write comes in after we've
180
 		// surrender the trylock, avoiding a race where a write comes in after we've
184
 		// checked readyToWrite() and it returned false, but while we still hold the trylock:
181
 		// checked readyToWrite() and it returned false, but while we still hold the trylock:
185
-		socket.writerSemaphore.Release()
182
+		socket.writeLock.Unlock()
186
 		// check if more data came in while we held the trylock:
183
 		// check if more data came in while we held the trylock:
187
 		if !socket.readyToWrite() {
184
 		if !socket.readyToWrite() {
188
 			return
185
 			return
189
 		}
186
 		}
190
-		if !socket.writerSemaphore.TryAcquire() {
187
+		if !socket.writeLock.TryLock() {
191
 			// failed to acquire; exit and wait for the holder to observe readyToWrite()
188
 			// failed to acquire; exit and wait for the holder to observe readyToWrite()
192
 			// after releasing it
189
 			// after releasing it
193
 			return
190
 			return

Notiek ielāde…
Atcelt
Saglabāt