Compare commits

...

1 Commits

Author SHA1 Message Date
James Tucker f275107206
wgengine: avoid the need to reenter the engine lock on double close
Updates #8059

Signed-off-by: James Tucker <james@tailscale.com>
2023-05-04 15:51:44 -07:00
1 changed files with 4 additions and 7 deletions

View File

@ -15,6 +15,7 @@ import (
"runtime" "runtime"
"strings" "strings"
"sync" "sync"
"sync/atomic"
"time" "time"
"github.com/tailscale/wireguard-go/device" "github.com/tailscale/wireguard-go/device"
@ -125,10 +126,10 @@ type userspaceEngine struct {
destIPActivityFuncs map[netip.Addr]func() destIPActivityFuncs map[netip.Addr]func()
statusBufioReader *bufio.Reader // reusable for UAPI statusBufioReader *bufio.Reader // reusable for UAPI
lastStatusPollTime mono.Time // last time we polled the engine status lastStatusPollTime mono.Time // last time we polled the engine status
closing atomic.Bool // Close was called (even if we're still closing)
mu sync.Mutex // guards following; see lock order comment below mu sync.Mutex // guards following; see lock order comment below
netMap *netmap.NetworkMap // or nil netMap *netmap.NetworkMap // or nil
closing bool // Close was called (even if we're still closing)
statusCallback StatusCallback statusCallback StatusCallback
peerSequence []key.NodePublic peerSequence []key.NodePublic
endpoints []tailcfg.Endpoint endpoints []tailcfg.Endpoint
@ -1022,8 +1023,8 @@ func (e *userspaceEngine) getStatus() (*Status, error) {
// (See comment in userspaceEngine's declaration.) // (See comment in userspaceEngine's declaration.)
derpConns := e.magicConn.DERPs() derpConns := e.magicConn.DERPs()
closing := e.closing.Load()
e.mu.Lock() e.mu.Lock()
closing := e.closing
peerKeys := make([]key.NodePublic, len(e.peerSequence)) peerKeys := make([]key.NodePublic, len(e.peerSequence))
copy(peerKeys, e.peerSequence) copy(peerKeys, e.peerSequence)
localAddrs := append([]tailcfg.Endpoint(nil), e.endpoints...) localAddrs := append([]tailcfg.Endpoint(nil), e.endpoints...)
@ -1083,13 +1084,9 @@ func (e *userspaceEngine) RequestStatus() {
} }
func (e *userspaceEngine) Close() { func (e *userspaceEngine) Close() {
e.mu.Lock() if e.closing.Swap(true) {
if e.closing {
e.mu.Unlock()
return return
} }
e.closing = true
e.mu.Unlock()
r := bufio.NewReader(strings.NewReader("")) r := bufio.NewReader(strings.NewReader(""))
e.wgdev.IpcSetOperation(r) e.wgdev.IpcSetOperation(r)