more fine-grained locking around user map (fixes deadlock if callee uses Users() in response to processEvent)
This commit is contained in:
parent
7f898dff32
commit
3cc31323ad
@ -67,10 +67,11 @@ 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()
|
|
||||||
defer this.userLock.Unlock()
|
|
||||||
|
|
||||||
|
this.userLock.Lock()
|
||||||
this.users[nick] = *NewUserInfo(nick)
|
this.users[nick] = *NewUserInfo(nick)
|
||||||
|
this.userLock.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})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -78,11 +79,9 @@ 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.userLock.Lock()
|
||||||
defer this.userLock.Unlock()
|
|
||||||
|
|
||||||
_, 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
|
||||||
|
|
||||||
if !userExisted {
|
if !userExisted {
|
||||||
this.processEvent(HubEvent{EventType: EVENT_USER_JOINED, Nick: uinf.Nick})
|
this.processEvent(HubEvent{EventType: EVENT_USER_JOINED, Nick: uinf.Nick})
|
||||||
@ -177,12 +176,10 @@ func (this *HubConnection) processProtocolMessage(message string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case "$Quit":
|
case "$Quit":
|
||||||
func() {
|
this.userLock.Lock()
|
||||||
this.userLock.Lock()
|
delete(this.users, commandParts[1])
|
||||||
defer this.userLock.Unlock()
|
this.userLock.Unlock() // Don't lock over a processEvent boundary
|
||||||
|
|
||||||
delete(this.users, commandParts[1])
|
|
||||||
}()
|
|
||||||
this.processEvent(HubEvent{EventType: EVENT_USER_PART, Nick: commandParts[1]})
|
this.processEvent(HubEvent{EventType: EVENT_USER_PART, Nick: commandParts[1]})
|
||||||
|
|
||||||
case "$MyINFO":
|
case "$MyINFO":
|
||||||
|
Loading…
Reference in New Issue
Block a user