Added eventsMutex and wrap all events calls with it.
Due to some "golangish" code this library have possibility to run into data race when application is working with callbacks. This commit adds eventsMutex (which is a sync.Mutex), removed all "golangish" ifs-map reads, and wrap events map read with sync.Mutex to avoid data races.
This commit is contained in:
parent
1b0acb5f2f
commit
e39cceace6
@ -13,13 +13,17 @@ import (
|
||||
func (irc *Connection) AddCallback(eventcode string, callback func(*Event)) int {
|
||||
eventcode = strings.ToUpper(eventcode)
|
||||
id := 0
|
||||
if _, ok := irc.events[eventcode]; !ok {
|
||||
|
||||
irc.eventsMutex.Lock()
|
||||
_, ok := irc.events[eventcode]
|
||||
if !ok {
|
||||
irc.events[eventcode] = make(map[int]func(*Event))
|
||||
id = 0
|
||||
} else {
|
||||
id = len(irc.events[eventcode])
|
||||
}
|
||||
irc.events[eventcode][id] = callback
|
||||
irc.eventsMutex.Unlock()
|
||||
return id
|
||||
}
|
||||
|
||||
@ -28,15 +32,20 @@ func (irc *Connection) AddCallback(eventcode string, callback func(*Event)) int
|
||||
func (irc *Connection) RemoveCallback(eventcode string, i int) bool {
|
||||
eventcode = strings.ToUpper(eventcode)
|
||||
|
||||
if event, ok := irc.events[eventcode]; ok {
|
||||
irc.eventsMutex.Lock()
|
||||
event, ok := irc.events[eventcode]
|
||||
if ok {
|
||||
if _, ok := event[i]; ok {
|
||||
delete(irc.events[eventcode], i)
|
||||
irc.eventsMutex.Unlock()
|
||||
return true
|
||||
}
|
||||
irc.Log.Printf("Event found, but no callback found at id %d\n", i)
|
||||
irc.eventsMutex.Unlock()
|
||||
return false
|
||||
}
|
||||
|
||||
irc.eventsMutex.Unlock()
|
||||
irc.Log.Println("Event not found")
|
||||
return false
|
||||
}
|
||||
@ -46,10 +55,14 @@ func (irc *Connection) RemoveCallback(eventcode string, i int) bool {
|
||||
func (irc *Connection) ClearCallback(eventcode string) bool {
|
||||
eventcode = strings.ToUpper(eventcode)
|
||||
|
||||
if _, ok := irc.events[eventcode]; ok {
|
||||
irc.eventsMutex.Lock()
|
||||
_, ok := irc.events[eventcode]
|
||||
if ok {
|
||||
irc.events[eventcode] = make(map[int]func(*Event))
|
||||
irc.eventsMutex.Unlock()
|
||||
return true
|
||||
}
|
||||
irc.eventsMutex.Unlock()
|
||||
|
||||
irc.Log.Println("Event not found")
|
||||
return false
|
||||
@ -59,7 +72,10 @@ func (irc *Connection) ClearCallback(eventcode string) bool {
|
||||
func (irc *Connection) ReplaceCallback(eventcode string, i int, callback func(*Event)) {
|
||||
eventcode = strings.ToUpper(eventcode)
|
||||
|
||||
if event, ok := irc.events[eventcode]; ok {
|
||||
irc.eventsMutex.Lock()
|
||||
event, ok := irc.events[eventcode]
|
||||
irc.eventsMutex.Unlock()
|
||||
if ok {
|
||||
if _, ok := event[i]; ok {
|
||||
event[i] = callback
|
||||
return
|
||||
@ -109,7 +125,10 @@ func (irc *Connection) RunCallbacks(event *Event) {
|
||||
event.Arguments[len(event.Arguments)-1] = msg
|
||||
}
|
||||
|
||||
if callbacks, ok := irc.events[event.Code]; ok {
|
||||
irc.eventsMutex.Lock()
|
||||
callbacks, ok := irc.events[event.Code]
|
||||
irc.eventsMutex.Unlock()
|
||||
if ok {
|
||||
if irc.VerboseCallbackHandler {
|
||||
irc.Log.Printf("%v (%v) >> %#v\n", event.Code, len(callbacks), event)
|
||||
}
|
||||
@ -121,12 +140,15 @@ func (irc *Connection) RunCallbacks(event *Event) {
|
||||
irc.Log.Printf("%v (0) >> %#v\n", event.Code, event)
|
||||
}
|
||||
|
||||
if callbacks, ok := irc.events["*"]; ok {
|
||||
irc.eventsMutex.Lock()
|
||||
allcallbacks, ok := irc.events["*"]
|
||||
irc.eventsMutex.Unlock()
|
||||
if ok {
|
||||
if irc.VerboseCallbackHandler {
|
||||
irc.Log.Printf("%v (0) >> %#v\n", event.Code, event)
|
||||
}
|
||||
|
||||
for _, callback := range callbacks {
|
||||
for _, callback := range allcallbacks {
|
||||
callback(event)
|
||||
}
|
||||
}
|
||||
|
@ -39,6 +39,7 @@ type Connection struct {
|
||||
user string
|
||||
registered bool
|
||||
events map[string]map[int]func(*Event)
|
||||
eventsMutex sync.Mutex
|
||||
|
||||
QuitMessage string
|
||||
lastMessage time.Time
|
||||
|
Loading…
Reference in New Issue
Block a user