Merge pull request #97 from pztrn/pztrn_master

Fix dataraces and possible application stuck
This commit is contained in:
Thomas Jager 2017-10-03 08:19:41 +02:00 committed by GitHub
commit 12e0f85112
3 changed files with 35 additions and 9 deletions

6
irc.go
View File

@ -74,9 +74,9 @@ func (irc *Connection) readLoop() {
irc.Log.Printf("<-- %s\n", strings.TrimSpace(msg)) irc.Log.Printf("<-- %s\n", strings.TrimSpace(msg))
} }
irc.Lock() irc.lastMessageMutex.Lock()
irc.lastMessage = time.Now() irc.lastMessage = time.Now()
irc.Unlock() irc.lastMessageMutex.Unlock()
event, err := parseToEvent(msg) event, err := parseToEvent(msg)
event.Connection = irc event.Connection = irc
if err == nil { if err == nil {
@ -166,9 +166,11 @@ func (irc *Connection) pingLoop() {
select { select {
case <-ticker.C: case <-ticker.C:
//Ping if we haven't received anything from the server within the keep alive period //Ping if we haven't received anything from the server within the keep alive period
irc.lastMessageMutex.Lock()
if time.Since(irc.lastMessage) >= irc.KeepAlive { if time.Since(irc.lastMessage) >= irc.KeepAlive {
irc.SendRawf("PING %d", time.Now().UnixNano()) irc.SendRawf("PING %d", time.Now().UnixNano())
} }
irc.lastMessageMutex.Unlock()
case <-ticker2.C: case <-ticker2.C:
//Ping at the ping frequency //Ping at the ping frequency
irc.SendRawf("PING %d", time.Now().UnixNano()) irc.SendRawf("PING %d", time.Now().UnixNano())

View File

@ -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)
} }
} }

View File

@ -39,9 +39,11 @@ 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
lastMessageMutex sync.Mutex
VerboseCallbackHandler bool VerboseCallbackHandler bool
Log *log.Logger Log *log.Logger