forked from jshiffer/go-xmpp
We need to lock isResultRoutes
The map is updated from multiple goroutines, so it needs to be locked.
This commit is contained in:
parent
8e1dac6ffa
commit
6a25856e85
18
router.go
18
router.go
@ -4,6 +4,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"encoding/xml"
|
"encoding/xml"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync"
|
||||||
|
|
||||||
"gosrc.io/xmpp/stanza"
|
"gosrc.io/xmpp/stanza"
|
||||||
)
|
)
|
||||||
@ -28,6 +29,7 @@ type Router struct {
|
|||||||
routes []*Route
|
routes []*Route
|
||||||
|
|
||||||
iqResultRoutes map[string]*IqResultRoute
|
iqResultRoutes map[string]*IqResultRoute
|
||||||
|
iqResultRouteLock sync.RWMutex
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewRouter returns a new router instance.
|
// NewRouter returns a new router instance.
|
||||||
@ -42,8 +44,16 @@ func NewRouter() *Router {
|
|||||||
func (r *Router) route(s Sender, p stanza.Packet) {
|
func (r *Router) route(s Sender, p stanza.Packet) {
|
||||||
iq, isIq := p.(stanza.IQ)
|
iq, isIq := p.(stanza.IQ)
|
||||||
if isIq {
|
if isIq {
|
||||||
if route, ok := r.iqResultRoutes[iq.Id]; ok {
|
r.iqResultRouteLock.RLock()
|
||||||
|
route, ok := r.iqResultRoutes[iq.Id]
|
||||||
|
r.iqResultRouteLock.RUnlock()
|
||||||
|
if ok {
|
||||||
|
r.iqResultRouteLock.Lock()
|
||||||
|
delete(r.iqResultRoutes, iq.Id)
|
||||||
|
r.iqResultRouteLock.Unlock()
|
||||||
|
close(route.matched)
|
||||||
route.handler.HandlePacket(s, p)
|
route.handler.HandlePacket(s, p)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -86,16 +96,20 @@ func (r *Router) NewIqResultRoute(ctx context.Context, id string) *IqResultRoute
|
|||||||
context: ctx,
|
context: ctx,
|
||||||
matched: make(chan struct{}),
|
matched: make(chan struct{}),
|
||||||
}
|
}
|
||||||
|
r.iqResultRouteLock.Lock()
|
||||||
r.iqResultRoutes[id] = route
|
r.iqResultRoutes[id] = route
|
||||||
|
r.iqResultRouteLock.Unlock()
|
||||||
go func() {
|
go func() {
|
||||||
select {
|
select {
|
||||||
case <-route.context.Done():
|
case <-route.context.Done():
|
||||||
|
r.iqResultRouteLock.Lock()
|
||||||
|
delete(r.iqResultRoutes, id)
|
||||||
|
r.iqResultRouteLock.Unlock()
|
||||||
if route.timeoutHandler != nil {
|
if route.timeoutHandler != nil {
|
||||||
route.timeoutHandler(route.context.Err())
|
route.timeoutHandler(route.context.Err())
|
||||||
}
|
}
|
||||||
case <-route.matched:
|
case <-route.matched:
|
||||||
}
|
}
|
||||||
delete(r.iqResultRoutes, id)
|
|
||||||
}()
|
}()
|
||||||
return route
|
return route
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user