After registration each IRC connection runs a second goroutine that sends queued messages to the client, and it read c.nick without holding c.mu. The goroutine that reads client commands changes c.nick under c.mu when the client sends NICK, so the race detector failed TestIntegrationTwoClients. Every read of c.nick in relay.go now takes c.mu. No other field that goroutine reads changes after it starts. Model: opus-5-5
This commit is contained in:
@@ -128,7 +128,11 @@ func (c *Conn) deliverIRCMessage(
|
|||||||
default:
|
default:
|
||||||
// Unknown command — deliver as server notice.
|
// Unknown command — deliver as server notice.
|
||||||
if text != "" {
|
if text != "" {
|
||||||
c.sendFromServer("NOTICE", c.nick, text)
|
c.mu.Lock()
|
||||||
|
nick := c.nick
|
||||||
|
c.mu.Unlock()
|
||||||
|
|
||||||
|
c.sendFromServer("NOTICE", nick, text)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -158,8 +162,12 @@ func (c *Conn) deliverNumeric(
|
|||||||
_ = json.Unmarshal(msg.Params, ¶ms)
|
_ = json.Unmarshal(msg.Params, ¶ms)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
c.mu.Lock()
|
||||||
|
nick := c.nick
|
||||||
|
c.mu.Unlock()
|
||||||
|
|
||||||
allParams := make([]string, 0, 1+len(params)+1)
|
allParams := make([]string, 0, 1+len(params)+1)
|
||||||
allParams = append(allParams, c.nick)
|
allParams = append(allParams, nick)
|
||||||
allParams = append(allParams, params...)
|
allParams = append(allParams, params...)
|
||||||
|
|
||||||
if text != "" {
|
if text != "" {
|
||||||
@@ -177,8 +185,12 @@ func (c *Conn) deliverTextMessage(
|
|||||||
from := msg.From
|
from := msg.From
|
||||||
target := msg.To
|
target := msg.To
|
||||||
|
|
||||||
|
c.mu.Lock()
|
||||||
|
nick := c.nick
|
||||||
|
c.mu.Unlock()
|
||||||
|
|
||||||
// Don't echo our own messages back.
|
// Don't echo our own messages back.
|
||||||
if strings.EqualFold(from, c.nick) {
|
if strings.EqualFold(from, nick) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -192,9 +204,13 @@ func (c *Conn) deliverTextMessage(
|
|||||||
|
|
||||||
// deliverJoin sends a JOIN notification.
|
// deliverJoin sends a JOIN notification.
|
||||||
func (c *Conn) deliverJoin(msg *db.IRCMessage) {
|
func (c *Conn) deliverJoin(msg *db.IRCMessage) {
|
||||||
|
c.mu.Lock()
|
||||||
|
nick := c.nick
|
||||||
|
c.mu.Unlock()
|
||||||
|
|
||||||
// Don't echo our own JOINs (we already sent them
|
// Don't echo our own JOINs (we already sent them
|
||||||
// during joinChannel).
|
// during joinChannel).
|
||||||
if strings.EqualFold(msg.From, c.nick) {
|
if strings.EqualFold(msg.From, nick) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -206,7 +222,11 @@ func (c *Conn) deliverJoin(msg *db.IRCMessage) {
|
|||||||
|
|
||||||
// deliverPart sends a PART notification.
|
// deliverPart sends a PART notification.
|
||||||
func (c *Conn) deliverPart(msg *db.IRCMessage, text string) {
|
func (c *Conn) deliverPart(msg *db.IRCMessage, text string) {
|
||||||
if strings.EqualFold(msg.From, c.nick) {
|
c.mu.Lock()
|
||||||
|
nick := c.nick
|
||||||
|
c.mu.Unlock()
|
||||||
|
|
||||||
|
if strings.EqualFold(msg.From, nick) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -227,7 +247,11 @@ func (c *Conn) deliverNickChange(
|
|||||||
msg *db.IRCMessage,
|
msg *db.IRCMessage,
|
||||||
newNick string,
|
newNick string,
|
||||||
) {
|
) {
|
||||||
if strings.EqualFold(msg.From, c.nick) {
|
c.mu.Lock()
|
||||||
|
nick := c.nick
|
||||||
|
c.mu.Unlock()
|
||||||
|
|
||||||
|
if strings.EqualFold(msg.From, nick) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -241,7 +265,11 @@ func (c *Conn) deliverQuitMsg(
|
|||||||
msg *db.IRCMessage,
|
msg *db.IRCMessage,
|
||||||
text string,
|
text string,
|
||||||
) {
|
) {
|
||||||
if strings.EqualFold(msg.From, c.nick) {
|
c.mu.Lock()
|
||||||
|
nick := c.nick
|
||||||
|
c.mu.Unlock()
|
||||||
|
|
||||||
|
if strings.EqualFold(msg.From, nick) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -302,7 +330,11 @@ func (c *Conn) deliverInviteMsg(
|
|||||||
_ *db.IRCMessage,
|
_ *db.IRCMessage,
|
||||||
text string,
|
text string,
|
||||||
) {
|
) {
|
||||||
c.sendFromServer("NOTICE", c.nick, text)
|
c.mu.Lock()
|
||||||
|
nick := c.nick
|
||||||
|
c.mu.Unlock()
|
||||||
|
|
||||||
|
c.sendFromServer("NOTICE", nick, text)
|
||||||
}
|
}
|
||||||
|
|
||||||
// deliverMode sends a MODE change notification.
|
// deliverMode sends a MODE change notification.
|
||||||
|
|||||||
Reference in New Issue
Block a user