switch to "hat" pattern for mutexes

--HG--
branch : adc
This commit is contained in:
mappu 2017-11-22 20:07:26 +13:00
parent dc3051fd38
commit 2fa40642a9
2 changed files with 20 additions and 19 deletions

View File

@ -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})

View File

@ -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})