mirror of
https://github.com/cwinfo/yggdrasil-go.git
synced 2024-11-26 20:01:38 +00:00
Merge pull request #534 from Arceliar/bugfix
Fix race between router and dial code
This commit is contained in:
commit
9da0c40239
@ -90,30 +90,37 @@ func (c *Conn) setMTU(from phony.Actor, mtu uint16) {
|
|||||||
|
|
||||||
// This should never be called from the router goroutine, used in the dial functions
|
// This should never be called from the router goroutine, used in the dial functions
|
||||||
func (c *Conn) search() error {
|
func (c *Conn) search() error {
|
||||||
var sinfo *searchInfo
|
|
||||||
var isIn bool
|
|
||||||
phony.Block(&c.core.router, func() {
|
|
||||||
sinfo, isIn = c.core.router.searches.searches[*c.nodeID]
|
|
||||||
})
|
|
||||||
if !isIn {
|
|
||||||
done := make(chan struct{}, 1)
|
|
||||||
var sess *sessionInfo
|
|
||||||
var err error
|
var err error
|
||||||
searchCompleted := func(sinfo *sessionInfo, e error) {
|
done := make(chan struct{})
|
||||||
sess = sinfo
|
|
||||||
err = e
|
|
||||||
// FIXME close can be called multiple times, do a non-blocking send instead
|
|
||||||
select {
|
|
||||||
case done <- struct{}{}:
|
|
||||||
default:
|
|
||||||
}
|
|
||||||
}
|
|
||||||
phony.Block(&c.core.router, func() {
|
phony.Block(&c.core.router, func() {
|
||||||
sinfo = c.core.router.searches.newIterSearch(c.nodeID, c.nodeMask, searchCompleted)
|
_, isIn := c.core.router.searches.searches[*c.nodeID]
|
||||||
|
if !isIn {
|
||||||
|
searchCompleted := func(sinfo *sessionInfo, e error) {
|
||||||
|
select {
|
||||||
|
case <-done:
|
||||||
|
// Somehow this was called multiple times, TODO don't let that happen
|
||||||
|
if sinfo != nil {
|
||||||
|
// Need to clean up to avoid a session leak
|
||||||
|
sinfo.cancel.Cancel(nil)
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
if sinfo != nil {
|
||||||
|
// Finish initializing the session
|
||||||
|
sinfo.conn = c
|
||||||
|
}
|
||||||
|
c.session = sinfo
|
||||||
|
err = e
|
||||||
|
close(done)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sinfo := c.core.router.searches.newIterSearch(c.nodeID, c.nodeMask, searchCompleted)
|
||||||
sinfo.continueSearch()
|
sinfo.continueSearch()
|
||||||
|
} else {
|
||||||
|
err = errors.New("search already exists")
|
||||||
|
close(done)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
<-done
|
<-done
|
||||||
c.session = sess
|
|
||||||
if c.session == nil && err == nil {
|
if c.session == nil && err == nil {
|
||||||
panic("search failed but returned no error")
|
panic("search failed but returned no error")
|
||||||
}
|
}
|
||||||
@ -122,13 +129,8 @@ func (c *Conn) search() error {
|
|||||||
for i := range c.nodeMask {
|
for i := range c.nodeMask {
|
||||||
c.nodeMask[i] = 0xFF
|
c.nodeMask[i] = 0xFF
|
||||||
}
|
}
|
||||||
c.session.conn = c
|
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
} else {
|
|
||||||
return errors.New("search already exists")
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Used in session keep-alive traffic
|
// Used in session keep-alive traffic
|
||||||
|
Loading…
Reference in New Issue
Block a user