summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorJames Tucker <james@tailscale.com>2023-05-04 15:51:44 -0700
committerJames Tucker <james@tailscale.com>2023-05-04 15:51:44 -0700
commitf275107206897b74b30214d4be07e4530cbb4814 (patch)
tree0da1cc8a069eb46edabe2bdbb0000ff177e917bd
parentd1ce7a9b5ebb8c9acac6358ecc9b50f03bf09ca6 (diff)
downloadtailscale-raggi/atomiccloseonce.tar.xz
tailscale-raggi/atomiccloseonce.zip
wgengine: avoid the need to reenter the engine lock on double closeraggi/atomiccloseonce
Updates #8059 Signed-off-by: James Tucker <james@tailscale.com>
-rw-r--r--wgengine/userspace.go11
1 files changed, 4 insertions, 7 deletions
diff --git a/wgengine/userspace.go b/wgengine/userspace.go
index 1356b36df..11b7ef320 100644
--- a/wgengine/userspace.go
+++ b/wgengine/userspace.go
@@ -15,6 +15,7 @@ import (
"runtime"
"strings"
"sync"
+ "sync/atomic"
"time"
"github.com/tailscale/wireguard-go/device"
@@ -125,10 +126,10 @@ type userspaceEngine struct {
destIPActivityFuncs map[netip.Addr]func()
statusBufioReader *bufio.Reader // reusable for UAPI
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
netMap *netmap.NetworkMap // or nil
- closing bool // Close was called (even if we're still closing)
statusCallback StatusCallback
peerSequence []key.NodePublic
endpoints []tailcfg.Endpoint
@@ -1022,8 +1023,8 @@ func (e *userspaceEngine) getStatus() (*Status, error) {
// (See comment in userspaceEngine's declaration.)
derpConns := e.magicConn.DERPs()
+ closing := e.closing.Load()
e.mu.Lock()
- closing := e.closing
peerKeys := make([]key.NodePublic, len(e.peerSequence))
copy(peerKeys, e.peerSequence)
localAddrs := append([]tailcfg.Endpoint(nil), e.endpoints...)
@@ -1083,13 +1084,9 @@ func (e *userspaceEngine) RequestStatus() {
}
func (e *userspaceEngine) Close() {
- e.mu.Lock()
- if e.closing {
- e.mu.Unlock()
+ if e.closing.Swap(true) {
return
}
- e.closing = true
- e.mu.Unlock()
r := bufio.NewReader(strings.NewReader(""))
e.wgdev.IpcSetOperation(r)