reduced chance of mutex related panic

This commit is contained in:
meera 2026-07-19 04:22:25 +03:00
parent c2551972a5
commit f921f53669
2 changed files with 28 additions and 19 deletions

2
.gitignore vendored
View File

@ -24,7 +24,7 @@ profile.cov
# Go workspace file
go.work
go.work.sum
stresser.go
# env file
.env

45
main.go
View File

@ -777,8 +777,7 @@ func joinChannel(c *Client, name string) {
// reject duplicate join
if _, exists := ch.members[c.nick]; exists {
ch.mu.Unlock()
c.fwrite(":server 443 %s %s %s :is already on channel\r\n",
c.nick, c.nick, name)
c.fwrite(":server 443 %s %s %s :is already on channel\r\n", c.nick, c.nick, name)
return
}
// clean up stale empty nick
@ -788,28 +787,26 @@ func joinChannel(c *Client, name string) {
c.channels[name] = ch
ch.mu.Unlock()
// echo JOIN to client
fmt.Fprintf(c.conn, ":%s JOIN %s\r\n", c.nick, name)
// broadcast JOIN to others
for _, member := range ch.members {
ch.mu.RLock()
members := make([]*Client, 0, len(ch.members))
for _, m := range ch.members {
members = append(members, m)
}
ch.mu.RUnlock()
for _, member := range members {
if member != c {
fmt.Fprintf(member.conn, ":%s JOIN %s\r\n", c.nick, name)
}
}
// topic
if ch.description != "" {
c.fwrite(":server 332 %s %s :%s\r\n", c.nick, name, ch.description)
} else {
c.fwrite(":server 331 %s %s :No topic is set\r\n", c.nick, name)
}
// names list
c.sendNames(ch)
// MODE if op
if ch.ops[c.nick] {
for _, member := range ch.members {
for _, member := range members {
member.fwrite(":server MODE %s +o %s\r\n", name, c.nick)
}
}
@ -831,7 +828,7 @@ func (c *Client) partChannel(name string) {
fmt.Fprintf(member.conn, ":%s PART %s\r\n", c.nick, name)
}
ch.mu.Unlock()
broadcastNames(ch)
//broadcastNames(ch)
}
func addChannel(name string, description string) {
name = normalizeChannelName(name)
@ -899,7 +896,7 @@ func (c *Client) checkRegistration() {
} else {
c.fwrite("%s :MOTD File is missing", c.nick)
}
fmt.Fprintf(c.conn, ":server 376 %s :End of MOTD\r\n", c.nick)
c.fwrite(":server 376 %s :End of MOTD\r\n", c.nick)
}
}
func reloadMOTD() {
@ -943,7 +940,7 @@ func showWho(c *Client, name string) {
for _, member := range ch.members {
c.fwrite(":server 352 %s %s %s server %s H :0 %s\r\n", c.nick, name, member.host, member.nick, member.nick)
}
fmt.Fprintf(c.conn, ":server 315 %s %s :End of WHO list\r\n", c.nick, name)
c.fwrite(":server 315 %s %s :End of WHO list\r\n", c.nick, name)
}
func (c *Client) handleList() {
chMu.Lock()
@ -1017,18 +1014,30 @@ func (c *Client) cleanup() {
ch.mu.Lock()
delete(ch.members, c.nick)
ch.mu.Unlock()
for nick, member := range ch.members {
if nick != c.nick {
ch.mu.RLock()
snapshot := make([]*Client, 0, len(ch.members))
for _, member := range ch.members {
snapshot = append(snapshot, member)
}
ch.mu.RUnlock()
for _, member := range snapshot {
if member.nick != c.nick {
member.fwrite(":%s PART %s\r\n", c.nick, name)
}
}
delete(c.channels, name)
}
cliMu.RLock()
snapshot := make([]*Client, 0, len(clients))
for _, other := range clients {
other.fwrite(":%s QUIT :Client disconnected\r\n", c.nick)
snapshot = append(snapshot, other)
}
cliMu.RUnlock()
for _, other := range snapshot {
other.fwrite(":%s QUIT :Client disconnected\r\n", c.nick)
}
}
func broadcastNames(ch *Channel) {