switch to "hat" pattern for mutexes
--HG-- branch : adc
This commit is contained in:
parent
dc3051fd38
commit
2fa40642a9
@ -14,10 +14,11 @@ type HubConnection struct {
|
|||||||
Hco *HubConnectionOptions
|
Hco *HubConnectionOptions
|
||||||
|
|
||||||
// Current remote status
|
// Current remote status
|
||||||
HubName string
|
HubName string
|
||||||
State ConnectionState
|
State ConnectionState
|
||||||
|
|
||||||
|
usersMut sync.RWMutex
|
||||||
users map[string]UserInfo
|
users map[string]UserInfo
|
||||||
userLock sync.RWMutex
|
|
||||||
|
|
||||||
proto Protocol
|
proto Protocol
|
||||||
|
|
||||||
@ -33,8 +34,8 @@ type HubConnection struct {
|
|||||||
|
|
||||||
// Thread-safe user accessor.
|
// Thread-safe user accessor.
|
||||||
func (this *HubConnection) Users(cb func(*map[string]UserInfo) error) error {
|
func (this *HubConnection) Users(cb func(*map[string]UserInfo) error) error {
|
||||||
this.userLock.Lock()
|
this.usersMut.Lock()
|
||||||
defer this.userLock.Unlock()
|
defer this.usersMut.Unlock()
|
||||||
|
|
||||||
return cb(&this.users)
|
return cb(&this.users)
|
||||||
}
|
}
|
||||||
@ -48,16 +49,16 @@ func (this *HubConnection) SayPrivate(recipient string, message string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (this *HubConnection) UserExists(nick string) bool {
|
func (this *HubConnection) UserExists(nick string) bool {
|
||||||
this.userLock.RLock()
|
this.usersMut.RLock()
|
||||||
defer this.userLock.RUnlock()
|
defer this.usersMut.RUnlock()
|
||||||
|
|
||||||
_, already_existed := this.users[nick]
|
_, already_existed := this.users[nick]
|
||||||
return already_existed
|
return already_existed
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *HubConnection) UserCount() int {
|
func (this *HubConnection) UserCount() int {
|
||||||
this.userLock.RLock()
|
this.usersMut.RLock()
|
||||||
defer this.userLock.RUnlock()
|
defer this.usersMut.RUnlock()
|
||||||
|
|
||||||
return len(this.users)
|
return len(this.users)
|
||||||
}
|
}
|
||||||
@ -65,9 +66,9 @@ func (this *HubConnection) UserCount() int {
|
|||||||
func (this *HubConnection) userJoined_NameOnly(nick string) {
|
func (this *HubConnection) userJoined_NameOnly(nick string) {
|
||||||
if !this.UserExists(nick) {
|
if !this.UserExists(nick) {
|
||||||
|
|
||||||
this.userLock.Lock()
|
this.usersMut.Lock()
|
||||||
this.users[nick] = *NewUserInfo(nick)
|
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})
|
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) {
|
func (this *HubConnection) userJoined_Full(uinf *UserInfo) {
|
||||||
// n.b. also called when we get a replacement MyINFO for someone
|
// 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
|
_, userExisted := this.users[uinf.Nick] // don't use UserExists as it would deadlock the mutex
|
||||||
this.users[uinf.Nick] = *uinf
|
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 {
|
if !userExisted {
|
||||||
this.processEvent(HubEvent{EventType: EVENT_USER_JOINED, Nick: uinf.Nick})
|
this.processEvent(HubEvent{EventType: EVENT_USER_JOINED, Nick: uinf.Nick})
|
||||||
|
@ -117,9 +117,9 @@ func (this *NmdcProtocol) ProcessCommand(message string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case "$Quit":
|
case "$Quit":
|
||||||
this.hc.userLock.Lock()
|
this.hc.usersMut.Lock()
|
||||||
delete(this.hc.users, commandParts[1])
|
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]})
|
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
|
// Mark all mentioned nicks as being operators, and all unmentioned nicks
|
||||||
// as being /not/ an operator. (second pass minimises RW mutex use)
|
// as being /not/ an operator. (second pass minimises RW mutex use)
|
||||||
func() {
|
func() {
|
||||||
this.hc.userLock.Lock()
|
this.hc.usersMut.Lock()
|
||||||
defer this.hc.userLock.Unlock()
|
defer this.hc.usersMut.Unlock()
|
||||||
|
|
||||||
for nick, userinfo := range this.hc.users {
|
for nick, userinfo := range this.hc.users {
|
||||||
_, isop := opmap[nick]
|
_, isop := opmap[nick]
|
||||||
@ -182,7 +182,7 @@ func (this *NmdcProtocol) ProcessCommand(message string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case "$UserIP":
|
case "$UserIP":
|
||||||
this.hc.userLock.Lock()
|
this.hc.usersMut.Lock()
|
||||||
|
|
||||||
pairs := strings.Split(commandParts[1], "$$")
|
pairs := strings.Split(commandParts[1], "$$")
|
||||||
notifyOfUpdate := make([]string, 0, len(pairs))
|
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 {
|
for _, nick := range notifyOfUpdate {
|
||||||
this.hc.processEvent(HubEvent{EventType: EVENT_USER_UPDATED_INFO, Nick: nick})
|
this.hc.processEvent(HubEvent{EventType: EVENT_USER_UPDATED_INFO, Nick: nick})
|
||||||
|
Loading…
Reference in New Issue
Block a user