reduced chance of mutex related panic
This commit is contained in:
parent
c2551972a5
commit
f921f53669
2
.gitignore
vendored
2
.gitignore
vendored
@ -24,7 +24,7 @@ profile.cov
|
|||||||
# Go workspace file
|
# Go workspace file
|
||||||
go.work
|
go.work
|
||||||
go.work.sum
|
go.work.sum
|
||||||
|
stresser.go
|
||||||
# env file
|
# env file
|
||||||
.env
|
.env
|
||||||
|
|
||||||
|
|||||||
45
main.go
45
main.go
@ -777,8 +777,7 @@ func joinChannel(c *Client, name string) {
|
|||||||
// reject duplicate join
|
// reject duplicate join
|
||||||
if _, exists := ch.members[c.nick]; exists {
|
if _, exists := ch.members[c.nick]; exists {
|
||||||
ch.mu.Unlock()
|
ch.mu.Unlock()
|
||||||
c.fwrite(":server 443 %s %s %s :is already on channel\r\n",
|
c.fwrite(":server 443 %s %s %s :is already on channel\r\n", c.nick, c.nick, name)
|
||||||
c.nick, c.nick, name)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// clean up stale empty nick
|
// clean up stale empty nick
|
||||||
@ -788,28 +787,26 @@ func joinChannel(c *Client, name string) {
|
|||||||
c.channels[name] = ch
|
c.channels[name] = ch
|
||||||
ch.mu.Unlock()
|
ch.mu.Unlock()
|
||||||
|
|
||||||
// echo JOIN to client
|
|
||||||
fmt.Fprintf(c.conn, ":%s JOIN %s\r\n", c.nick, name)
|
fmt.Fprintf(c.conn, ":%s JOIN %s\r\n", c.nick, name)
|
||||||
// broadcast JOIN to others
|
ch.mu.RLock()
|
||||||
for _, member := range ch.members {
|
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 {
|
if member != c {
|
||||||
fmt.Fprintf(member.conn, ":%s JOIN %s\r\n", c.nick, name)
|
fmt.Fprintf(member.conn, ":%s JOIN %s\r\n", c.nick, name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// topic
|
|
||||||
if ch.description != "" {
|
if ch.description != "" {
|
||||||
c.fwrite(":server 332 %s %s :%s\r\n", c.nick, name, ch.description)
|
c.fwrite(":server 332 %s %s :%s\r\n", c.nick, name, ch.description)
|
||||||
} else {
|
} else {
|
||||||
c.fwrite(":server 331 %s %s :No topic is set\r\n", c.nick, name)
|
c.fwrite(":server 331 %s %s :No topic is set\r\n", c.nick, name)
|
||||||
}
|
}
|
||||||
|
|
||||||
// names list
|
|
||||||
c.sendNames(ch)
|
c.sendNames(ch)
|
||||||
|
|
||||||
// MODE if op
|
|
||||||
if ch.ops[c.nick] {
|
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)
|
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)
|
fmt.Fprintf(member.conn, ":%s PART %s\r\n", c.nick, name)
|
||||||
}
|
}
|
||||||
ch.mu.Unlock()
|
ch.mu.Unlock()
|
||||||
broadcastNames(ch)
|
//broadcastNames(ch)
|
||||||
}
|
}
|
||||||
func addChannel(name string, description string) {
|
func addChannel(name string, description string) {
|
||||||
name = normalizeChannelName(name)
|
name = normalizeChannelName(name)
|
||||||
@ -899,7 +896,7 @@ func (c *Client) checkRegistration() {
|
|||||||
} else {
|
} else {
|
||||||
c.fwrite("%s :MOTD File is missing", c.nick)
|
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() {
|
func reloadMOTD() {
|
||||||
@ -943,7 +940,7 @@ func showWho(c *Client, name string) {
|
|||||||
for _, member := range ch.members {
|
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)
|
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() {
|
func (c *Client) handleList() {
|
||||||
chMu.Lock()
|
chMu.Lock()
|
||||||
@ -1017,18 +1014,30 @@ func (c *Client) cleanup() {
|
|||||||
ch.mu.Lock()
|
ch.mu.Lock()
|
||||||
delete(ch.members, c.nick)
|
delete(ch.members, c.nick)
|
||||||
ch.mu.Unlock()
|
ch.mu.Unlock()
|
||||||
for nick, member := range ch.members {
|
ch.mu.RLock()
|
||||||
if nick != c.nick {
|
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)
|
member.fwrite(":%s PART %s\r\n", c.nick, name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
delete(c.channels, name)
|
delete(c.channels, name)
|
||||||
}
|
}
|
||||||
cliMu.RLock()
|
cliMu.RLock()
|
||||||
|
snapshot := make([]*Client, 0, len(clients))
|
||||||
for _, other := range clients {
|
for _, other := range clients {
|
||||||
other.fwrite(":%s QUIT :Client disconnected\r\n", c.nick)
|
snapshot = append(snapshot, other)
|
||||||
}
|
}
|
||||||
cliMu.RUnlock()
|
cliMu.RUnlock()
|
||||||
|
|
||||||
|
for _, other := range snapshot {
|
||||||
|
other.fwrite(":%s QUIT :Client disconnected\r\n", c.nick)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func broadcastNames(ch *Channel) {
|
func broadcastNames(ch *Channel) {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user