From 0f6ee63e6e064ed201365f368f57e2e0870f10e1 Mon Sep 17 00:00:00 2001 From: Jeremy Latt Date: Sat, 15 Feb 2014 20:20:37 -0800 Subject: [PATCH] fix a race --- irc/channel.go | 18 +++++++++++++----- irc/server.go | 8 +++++--- 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/irc/channel.go b/irc/channel.go index fb934040..bf183ba2 100644 --- a/irc/channel.go +++ b/irc/channel.go @@ -51,12 +51,14 @@ func NewChannel(s *Server, name string) *Channel { } func (channel *Channel) Destroy() { - if channel.destroyed { + if channel.IsDestroyed() { return } - channel.destroyed = true - channel.members = make(ClientSet) + channel.withMutex(func() { + channel.destroyed = true + channel.members = make(ClientSet) + }) channel.server.channels.Remove(channel) } @@ -70,7 +72,7 @@ func (channel *Channel) Reply(reply Reply) { func (channel *Channel) receiveCommands(commands <-chan ChannelCommand) { for command := range commands { - if channel.destroyed { + if channel.IsDestroyed() { if DEBUG_CHANNEL { log.Printf("%s → %s %s dropped", command.Source(), channel, command) } @@ -92,9 +94,15 @@ func IsPrivMsg(reply Reply) bool { return strReply.code == "PRIVMSG" } +func (channel *Channel) IsDestroyed() bool { + channel.mutex.Lock() + defer channel.mutex.Unlock() + return channel.destroyed +} + func (channel *Channel) receiveReplies(replies <-chan Reply) { for reply := range replies { - if channel.destroyed { + if channel.IsDestroyed() { if DEBUG_CHANNEL { log.Printf("%s ← %s %s dropped", channel, reply.Source(), reply) } diff --git a/irc/server.go b/irc/server.go index 6648e129..30bef77b 100644 --- a/irc/server.go +++ b/irc/server.go @@ -364,12 +364,14 @@ func (m *JoinCommand) HandleServer(s *Server) { } } -func (m *PartCommand) HandleServer(s *Server) { +func (m *PartCommand) HandleServer(server *Server) { for _, chname := range m.channels { - channel := s.channels[chname] + server.mutex.Lock() + channel := server.channels[chname] + server.mutex.Unlock() if channel == nil { - m.Client().Reply(ErrNoSuchChannel(s, channel.name)) + m.Client().Reply(ErrNoSuchChannel(server, channel.name)) continue }