threadsafe access to HubConnection.Users [[BREAKING CHANGE]]

This commit is contained in:
mappu 2016-05-08 12:33:49 +12:00
parent 3c4972d930
commit cc15a571a8
2 changed files with 37 additions and 11 deletions

View File

@ -4,6 +4,7 @@ import (
"crypto/tls"
"net"
"strings"
"sync"
"time"
)
@ -14,7 +15,8 @@ type HubConnection struct {
// Current remote status
HubName string
State ConnectionState
Users map[string]UserInfo
users map[string]UserInfo
userLock sync.RWMutex
// Streamed events
processEvent func(HubEvent)
@ -27,6 +29,13 @@ type HubConnection struct {
autoReconnect bool
}
func (this *HubConnection) Users(cb func(*map[string]UserInfo) error) error {
this.userLock.Lock()
defer this.userLock.Unlock()
return cb(&this.users)
}
func (this *HubConnection) SayPublic(message string) {
this.SayRaw("<" + this.Hco.Self.Nick + "> " + NMDCEscape(message) + "|")
}
@ -39,18 +48,30 @@ func (this *HubConnection) SayInfo() {
this.SayRaw(this.Hco.Self.toMyINFO() + "|")
}
func (this *HubConnection) UserExists(nick string) bool {
this.userLock.RLock()
defer this.userLock.RUnlock()
_, already_existed := this.users[nick]
return already_existed
}
func (this *HubConnection) userJoined_NameOnly(nick string) {
_, already_existed := this.Users[nick]
if !already_existed {
this.Users[nick] = *NewUserInfo(nick)
if !this.UserExists(nick) {
this.userLock.Lock()
defer this.userLock.Unlock()
this.users[nick] = *NewUserInfo(nick)
this.processEvent(HubEvent{EventType: EVENT_USER_JOINED, Nick: nick})
}
}
func (this *HubConnection) userJoined_Full(uinf *UserInfo) {
_, already_existed := this.Users[uinf.Nick]
if !already_existed {
this.Users[uinf.Nick] = *uinf
if !this.UserExists(uinf.Nick) {
this.userLock.Lock()
defer this.userLock.Unlock()
this.users[uinf.Nick] = *uinf
this.processEvent(HubEvent{EventType: EVENT_USER_JOINED, Nick: uinf.Nick})
}
}
@ -134,7 +155,12 @@ func (this *HubConnection) processProtocolMessage(message string) {
this.SayRaw("$MyPass " + NMDCEscape(this.Hco.NickPassword) + "|")
case "$Quit":
delete(this.Users, commandParts[1])
func() {
this.userLock.Lock()
defer this.userLock.Unlock()
delete(this.users, commandParts[1])
}()
this.processEvent(HubEvent{EventType: EVENT_USER_PART, Nick: commandParts[1]})
case "$MyINFO":

View File

@ -23,7 +23,7 @@ func (this *HubConnectionOptions) prepareConnection() *HubConnection {
Hco: this,
HubName: DEFAULT_HUB_NAME,
State: CONNECTIONSTATE_DISCONNECTED,
Users: make(map[string]UserInfo),
users: make(map[string]UserInfo),
autoReconnect: !this.SkipAutoReconnect,
}