a couple race fixes and use timer.AfterFunc instead of sleeping goroutines or ticker in a few places

This commit is contained in:
Arceliar 2019-08-25 17:00:02 -05:00
parent a3d4d8125b
commit 502f2937a9
11 changed files with 66 additions and 98 deletions

View file

@ -23,7 +23,7 @@ type tunConn struct {
addr address.Address
snet address.Subnet
stop chan struct{}
alive chan struct{}
alive *time.Timer // From calling time.AfterFunc
}
func (s *tunConn) close() {
@ -40,10 +40,6 @@ func (s *tunConn) _close_nomutex() {
defer func() { recover() }()
close(s.stop) // Closes reader/writer goroutines
}()
func() {
defer func() { recover() }()
close(s.alive) // Closes timeout goroutine
}()
}
func (s *tunConn) _read(bs []byte) (err error) {
@ -228,27 +224,8 @@ func (s *tunConn) _write(bs []byte) (err error) {
}
func (s *tunConn) stillAlive() {
defer func() { recover() }()
select {
case s.alive <- struct{}{}:
default:
}
}
func (s *tunConn) checkForTimeouts() error {
timer := time.NewTimer(tunConnTimeout)
defer util.TimerStop(timer)
defer s.close()
for {
select {
case _, ok := <-s.alive:
if !ok {
return errors.New("connection closed")
}
util.TimerStop(timer)
timer.Reset(tunConnTimeout)
case <-timer.C:
return errors.New("timed out")
}
if s.alive != nil {
s.alive.Stop()
}
s.alive = time.AfterFunc(tunConnTimeout, s.close)
}

View file

@ -227,10 +227,9 @@ func (tun *TunAdapter) handler() error {
func (tun *TunAdapter) wrap(conn *yggdrasil.Conn) (c *tunConn, err error) {
// Prepare a session wrapper for the given connection
s := tunConn{
tun: tun,
conn: conn,
stop: make(chan struct{}),
alive: make(chan struct{}, 1),
tun: tun,
conn: conn,
stop: make(chan struct{}),
}
c = &s
// Get the remote address and subnet of the other side
@ -255,13 +254,13 @@ func (tun *TunAdapter) wrap(conn *yggdrasil.Conn) (c *tunConn, err error) {
// we receive a packet through the interface for this address
tun.addrToConn[s.addr] = &s
tun.subnetToConn[s.snet] = &s
// Set the read callback and start the timeout goroutine
// Set the read callback and start the timeout
conn.SetReadCallback(func(bs []byte) {
s.RecvFrom(conn, func() {
s._read(bs)
})
})
go s.checkForTimeouts()
s.RecvFrom(nil, s.stillAlive)
// Return
return c, err
}