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 {
|
func (irc *Connection) AddCallback(eventcode string, callback func(*Event)) int {
|
||||||
eventcode = strings.ToUpper(eventcode)
|
eventcode = strings.ToUpper(eventcode)
|
||||||
id := 0
|
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))
|
irc.events[eventcode] = make(map[int]func(*Event))
|
||||||
id = 0
|
id = 0
|
||||||
} else {
|
} else {
|
||||||
id = len(irc.events[eventcode])
|
id = len(irc.events[eventcode])
|
||||||
}
|
}
|
||||||
irc.events[eventcode][id] = callback
|
irc.events[eventcode][id] = callback
|
||||||
|
irc.eventsMutex.Unlock()
|
||||||
return id
|
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 {
|
func (irc *Connection) RemoveCallback(eventcode string, i int) bool {
|
||||||
eventcode = strings.ToUpper(eventcode)
|
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 {
|
if _, ok := event[i]; ok {
|
||||||
delete(irc.events[eventcode], i)
|
delete(irc.events[eventcode], i)
|
||||||
|
irc.eventsMutex.Unlock()
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
irc.Log.Printf("Event found, but no callback found at id %d\n", i)
|
irc.Log.Printf("Event found, but no callback found at id %d\n", i)
|
||||||
|
irc.eventsMutex.Unlock()
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
irc.eventsMutex.Unlock()
|
||||||
irc.Log.Println("Event not found")
|
irc.Log.Println("Event not found")
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@ -46,10 +55,14 @@ func (irc *Connection) RemoveCallback(eventcode string, i int) bool {
|
|||||||
func (irc *Connection) ClearCallback(eventcode string) bool {
|
func (irc *Connection) ClearCallback(eventcode string) bool {
|
||||||
eventcode = strings.ToUpper(eventcode)
|
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.events[eventcode] = make(map[int]func(*Event))
|
||||||
|
irc.eventsMutex.Unlock()
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
irc.eventsMutex.Unlock()
|
||||||
|
|
||||||
irc.Log.Println("Event not found")
|
irc.Log.Println("Event not found")
|
||||||
return false
|
return false
|
||||||
@ -59,7 +72,10 @@ func (irc *Connection) ClearCallback(eventcode string) bool {
|
|||||||
func (irc *Connection) ReplaceCallback(eventcode string, i int, callback func(*Event)) {
|
func (irc *Connection) ReplaceCallback(eventcode string, i int, callback func(*Event)) {
|
||||||
eventcode = strings.ToUpper(eventcode)
|
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 {
|
if _, ok := event[i]; ok {
|
||||||
event[i] = callback
|
event[i] = callback
|
||||||
return
|
return
|
||||||
@ -109,7 +125,10 @@ func (irc *Connection) RunCallbacks(event *Event) {
|
|||||||
event.Arguments[len(event.Arguments)-1] = msg
|
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 {
|
if irc.VerboseCallbackHandler {
|
||||||
irc.Log.Printf("%v (%v) >> %#v\n", event.Code, len(callbacks), event)
|
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)
|
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 {
|
if irc.VerboseCallbackHandler {
|
||||||
irc.Log.Printf("%v (0) >> %#v\n", event.Code, event)
|
irc.Log.Printf("%v (0) >> %#v\n", event.Code, event)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, callback := range callbacks {
|
for _, callback := range allcallbacks {
|
||||||
callback(event)
|
callback(event)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -39,6 +39,7 @@ type Connection struct {
|
|||||||
user string
|
user string
|
||||||
registered bool
|
registered bool
|
||||||
events map[string]map[int]func(*Event)
|
events map[string]map[int]func(*Event)
|
||||||
|
eventsMutex sync.Mutex
|
||||||
|
|
||||||
QuitMessage string
|
QuitMessage string
|
||||||
lastMessage time.Time
|
lastMessage time.Time
|
||||||
|
Loading…
Reference in New Issue
Block a user