diff --git a/irc/channel.go b/irc/channel.go index 8114803c..d41cc5a8 100644 --- a/irc/channel.go +++ b/irc/channel.go @@ -185,10 +185,10 @@ func (channel *Channel) Nick() string { } // -func (channel *Channel) ModeString(client *Client) (str string) { - channel.membersMutex.RLock() +func (channel *Channel) modeStringNoLock(client *Client) (str string) { + // RLock() isMember := client.flags[Operator] || channel.members.Has(client) - channel.membersMutex.RUnlock() + // RUnlock() showKey := isMember && (channel.key != "") showUserLimit := channel.userLimit > 0 @@ -436,10 +436,9 @@ func (channel *Channel) applyModeFlag(client *Client, mode ChannelMode, return false } -func (channel *Channel) applyModeMember(client *Client, mode ChannelMode, +func (channel *Channel) applyModeMemberNoMutex(client *Client, mode ChannelMode, op ModeOp, nick string) *ChannelModeChange { - channel.membersMutex.Lock() - defer channel.membersMutex.Unlock() + // requires Lock() if nick == "" { //TODO(dan): shouldn't this be handled before it reaches this function? diff --git a/irc/modes.go b/irc/modes.go index ce8a1ed0..4983d8db 100644 --- a/irc/modes.go +++ b/irc/modes.go @@ -414,7 +414,7 @@ func cmodeHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool { // so we only output one warning for each list type when full listFullWarned := make(map[ChannelMode]bool) - clientIsOp := channel.ClientIsAtLeast(client, ChannelOperator) + clientIsOp := channel.clientIsAtLeastNoMutex(client, ChannelOperator) var alreadySentPrivError bool for _, change := range changes { @@ -545,7 +545,7 @@ func cmodeHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool { } } - change := channel.applyModeMember(client, change.mode, change.op, change.arg) + change := channel.applyModeMemberNoMutex(client, change.mode, change.op, change.arg) if change != nil { applied = append(applied, change) } @@ -561,7 +561,7 @@ func cmodeHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool { } } else { //TODO(dan): we should just make ModeString return a slice here - args := append([]string{client.nick, channel.name}, strings.Split(channel.ModeString(client), " ")...) + args := append([]string{client.nick, channel.name}, strings.Split(channel.modeStringNoLock(client), " ")...) client.Send(nil, client.nickMaskString, RPL_CHANNELMODEIS, args...) client.Send(nil, client.nickMaskString, RPL_CHANNELCREATED, client.nick, channel.name, strconv.FormatInt(channel.createdTime.Unix(), 10)) }