diff --git a/irc/channel.go b/irc/channel.go index 54d9d286..7f2c455d 100644 --- a/irc/channel.go +++ b/irc/channel.go @@ -2,6 +2,7 @@ package irc import ( "log" + "sync" ) type Channel struct { @@ -10,6 +11,7 @@ type Channel struct { destroyed bool key string members ClientSet + mutex *sync.Mutex name string noOutside bool password string @@ -38,6 +40,7 @@ func NewChannel(s *Server, name string) *Channel { banList: make([]UserMask, 0), commands: commands, members: make(ClientSet), + mutex: &sync.Mutex{}, name: name, replies: replies, server: s, @@ -92,11 +95,13 @@ func (channel *Channel) receiveReplies(replies <-chan Reply) { if DEBUG_CHANNEL { log.Printf("%s ← %s %s", channel, reply.Source(), reply) } + channel.mutex.Lock() for client := range channel.members { if reply.Source() != Identifier(client) { client.Reply(reply) } } + channel.mutex.Unlock() } } diff --git a/irc/server.go b/irc/server.go index a0a5db68..027f5436 100644 --- a/irc/server.go +++ b/irc/server.go @@ -9,6 +9,7 @@ import ( "log" "net" "os" + "sync" "time" ) @@ -17,6 +18,7 @@ type Server struct { commands chan Command ctime time.Time motdFile string + mutex *sync.Mutex name string operators map[string]string password string @@ -30,6 +32,7 @@ func NewServer(config *Config) *Server { commands: make(chan Command), ctime: time.Now(), motdFile: config.MOTD, + mutex: &sync.Mutex{}, name: config.Name, operators: make(map[string]string), password: config.Password, @@ -296,7 +299,9 @@ func (m *QuitCommand) HandleServer(server *Server) { iclients.Remove(client) for channel := range client.channels { + channel.mutex.Lock() channel.members.Remove(client) + channel.mutex.Unlock() } client.Reply(RplError(server, client))