mirror of https://github.com/fluffle/goirc
Avoid holding hSet lock while executing handlers. Fixes #102.
This commit is contained in:
parent
2ece5aab67
commit
c981f8f568
|
@ -1,10 +1,11 @@
|
||||||
package client
|
package client
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/fluffle/goirc/logging"
|
|
||||||
"runtime"
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
|
"github.com/fluffle/goirc/logging"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Handlers are triggered on incoming Lines from the server, with the handler
|
// Handlers are triggered on incoming Lines from the server, with the handler
|
||||||
|
@ -128,16 +129,25 @@ func (hs *hSet) remove(hn *hNode) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (hs *hSet) dispatch(conn *Conn, line *Line) {
|
func (hs *hSet) getHandlers(ev string) []*hNode {
|
||||||
hs.RLock()
|
hs.RLock()
|
||||||
defer hs.RUnlock()
|
defer hs.RUnlock()
|
||||||
ev := strings.ToLower(line.Cmd)
|
|
||||||
list, ok := hs.set[ev]
|
list, ok := hs.set[ev]
|
||||||
if !ok {
|
if !ok {
|
||||||
return
|
return nil
|
||||||
}
|
}
|
||||||
wg := &sync.WaitGroup{}
|
// Copy current list of handlers to a temporary slice under the lock.
|
||||||
|
handlers := make([]*hNode, 0)
|
||||||
for hn := list.start; hn != nil; hn = hn.next {
|
for hn := list.start; hn != nil; hn = hn.next {
|
||||||
|
handlers = append(handlers, hn)
|
||||||
|
}
|
||||||
|
return handlers
|
||||||
|
}
|
||||||
|
|
||||||
|
func (hs *hSet) dispatch(conn *Conn, line *Line) {
|
||||||
|
ev := strings.ToLower(line.Cmd)
|
||||||
|
wg := &sync.WaitGroup{}
|
||||||
|
for _, hn := range hs.getHandlers(ev) {
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
go func(hn *hNode) {
|
go func(hn *hNode) {
|
||||||
hn.Handle(conn, line.Copy())
|
hn.Handle(conn, line.Copy())
|
||||||
|
|
Loading…
Reference in New Issue