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

View File

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