wgengine/tstun: make Close safe for concurrent use
@@ -63,6 +63,8 @@ type TUN struct {
// tdev is the underlying TUN device.
tdev tun.Device
+ closeOnce sync.Once
+
_ [4]byte // force 64-bit alignment of following field on 32-bit
lastActivityAtomic int64 // unix seconds of last send or receive
@@ -140,15 +142,14 @@ func (t *TUN) SetDestIPActivityFuncs(m map[packet.IP]func()) {
}
func (t *TUN) Close() error {
- select {
- case <-t.closed:
- // continue
- default:
+ var err error
+ t.closeOnce.Do(func() {
// Other channels need not be closed: poll will exit gracefully after this.
close(t.closed)
- }
- return t.tdev.Close()
+ err = t.tdev.Close()
+ })
+ return err
}
func (t *TUN) Events() chan tun.Event {
