From 2fa40642a9ab4bbbafc52f6d43473163d47fbf1a Mon Sep 17 00:00:00 2001 From: mappu Date: Wed, 22 Nov 2017 20:07:26 +1300 Subject: [PATCH] switch to "hat" pattern for mutexes --HG-- branch : adc --- HubConnection.go | 27 ++++++++++++++------------- NmdcProtocol.go | 12 ++++++------ 2 files changed, 20 insertions(+), 19 deletions(-) diff --git a/HubConnection.go b/HubConnection.go index cec8d47..7cb9c4f 100644 --- a/HubConnection.go +++ b/HubConnection.go @@ -14,10 +14,11 @@ type HubConnection struct { Hco *HubConnectionOptions // Current remote status - HubName string - State ConnectionState + HubName string + State ConnectionState + + usersMut sync.RWMutex users map[string]UserInfo - userLock sync.RWMutex proto Protocol @@ -33,8 +34,8 @@ type HubConnection struct { // Thread-safe user accessor. func (this *HubConnection) Users(cb func(*map[string]UserInfo) error) error { - this.userLock.Lock() - defer this.userLock.Unlock() + this.usersMut.Lock() + defer this.usersMut.Unlock() return cb(&this.users) } @@ -48,16 +49,16 @@ func (this *HubConnection) SayPrivate(recipient string, message string) { } func (this *HubConnection) UserExists(nick string) bool { - this.userLock.RLock() - defer this.userLock.RUnlock() + this.usersMut.RLock() + defer this.usersMut.RUnlock() _, already_existed := this.users[nick] return already_existed } func (this *HubConnection) UserCount() int { - this.userLock.RLock() - defer this.userLock.RUnlock() + this.usersMut.RLock() + defer this.usersMut.RUnlock() return len(this.users) } @@ -65,9 +66,9 @@ func (this *HubConnection) UserCount() int { func (this *HubConnection) userJoined_NameOnly(nick string) { if !this.UserExists(nick) { - this.userLock.Lock() + this.usersMut.Lock() this.users[nick] = *NewUserInfo(nick) - this.userLock.Unlock() // Don't lock over a processEvent boundary + this.usersMut.Unlock() // Don't lock over a processEvent boundary this.processEvent(HubEvent{EventType: EVENT_USER_JOINED, Nick: nick}) } @@ -75,10 +76,10 @@ func (this *HubConnection) userJoined_NameOnly(nick string) { func (this *HubConnection) userJoined_Full(uinf *UserInfo) { // n.b. also called when we get a replacement MyINFO for someone - this.userLock.Lock() + this.usersMut.Lock() _, userExisted := this.users[uinf.Nick] // don't use UserExists as it would deadlock the mutex this.users[uinf.Nick] = *uinf - this.userLock.Unlock() // Don't lock over a processEvent boundary + this.usersMut.Unlock() // Don't lock over a processEvent boundary if !userExisted { this.processEvent(HubEvent{EventType: EVENT_USER_JOINED, Nick: uinf.Nick}) diff --git a/NmdcProtocol.go b/NmdcProtocol.go index db209fe..42dce25 100644 --- a/NmdcProtocol.go +++ b/NmdcProtocol.go @@ -117,9 +117,9 @@ func (this *NmdcProtocol) ProcessCommand(message string) { } case "$Quit": - this.hc.userLock.Lock() + this.hc.usersMut.Lock() delete(this.hc.users, commandParts[1]) - this.hc.userLock.Unlock() // Don't lock over a processEvent boundary + this.hc.usersMut.Unlock() // Don't lock over a processEvent boundary this.hc.processEvent(HubEvent{EventType: EVENT_USER_PART, Nick: commandParts[1]}) @@ -156,8 +156,8 @@ func (this *NmdcProtocol) ProcessCommand(message string) { // Mark all mentioned nicks as being operators, and all unmentioned nicks // as being /not/ an operator. (second pass minimises RW mutex use) func() { - this.hc.userLock.Lock() - defer this.hc.userLock.Unlock() + this.hc.usersMut.Lock() + defer this.hc.usersMut.Unlock() for nick, userinfo := range this.hc.users { _, isop := opmap[nick] @@ -182,7 +182,7 @@ func (this *NmdcProtocol) ProcessCommand(message string) { } case "$UserIP": - this.hc.userLock.Lock() + this.hc.usersMut.Lock() pairs := strings.Split(commandParts[1], "$$") notifyOfUpdate := make([]string, 0, len(pairs)) @@ -211,7 +211,7 @@ func (this *NmdcProtocol) ProcessCommand(message string) { } } - this.hc.userLock.Unlock() + this.hc.usersMut.Unlock() for _, nick := range notifyOfUpdate { this.hc.processEvent(HubEvent{EventType: EVENT_USER_UPDATED_INFO, Nick: nick})