diff options
| -rw-r--r-- | ipn/ipnlocal/extension_host.go | 14 | ||||
| -rw-r--r-- | ipn/ipnlocal/local.go | 16 |
2 files changed, 14 insertions, 16 deletions
diff --git a/ipn/ipnlocal/extension_host.go b/ipn/ipnlocal/extension_host.go index 1cacb5353..8e0984c87 100644 --- a/ipn/ipnlocal/extension_host.go +++ b/ipn/ipnlocal/extension_host.go @@ -111,6 +111,12 @@ type ExtensionHost struct { // currentPrefs is a read-only view of the current profile's [ipn.Prefs] // with any private keys stripped. It is always Valid. currentPrefs ipn.PrefsView + + // existsPendingAuthReconfig tracks if a goroutine is already enqueued + // to call [LocalBackend.authReconfig]. It is used to prevent goroutines + // from piling up in the queue to do the same + // work of [LocalBackend.authReconfigLocked]. + existsPendingAuthReconfig atomic.Bool } // Backend is a subset of [LocalBackend] methods that are used by [ExtensionHost]. @@ -544,11 +550,19 @@ func (h *ExtensionHost) Shutdown() { } // AuthReconfigAsync implements [ipnext.Host.AuthReconfigAsync]. +// Callers may experience an early return with no work +// done if another goroutine is waiting in the backend operation queue. +// If there is no other goroutine waiting, the calling goroutine will +// proceed to queue. func (h *ExtensionHost) AuthReconfigAsync() { if h == nil { return } + if h.existsPendingAuthReconfig.Swap(true) { + return + } h.enqueueBackendOperation(func(b Backend) { + h.existsPendingAuthReconfig.Store(false) b.authReconfig() }) } diff --git a/ipn/ipnlocal/local.go b/ipn/ipnlocal/local.go index 28fb48fa6..a9146a303 100644 --- a/ipn/ipnlocal/local.go +++ b/ipn/ipnlocal/local.go @@ -410,12 +410,6 @@ type LocalBackend struct { // getCertForTest is used to retrieve TLS certificates in tests. // See [LocalBackend.ConfigureCertsForTest]. getCertForTest func(hostname string) (*TLSCertKeyPair, error) - - // existsPendingAuthReconfig tracks if a goroutine is waiting to - // acquire [LocalBackend]'s mutex inside of [LocalBackend.AuthReconfig]. - // It is used to prevent goroutines from piling up to do the same - // work of [LocalBackend.authReconfigLocked]. - existsPendingAuthReconfig atomic.Bool } // SetHardwareAttested enables hardware attestation key signatures in map @@ -5080,18 +5074,8 @@ func (b *LocalBackend) readvertiseAppConnectorRoutes() { // Reconfiguration may run asynchronously and may not complete // before the call returns. func (b *LocalBackend) authReconfig() { - // If there's already a pending auth reconfig from another - // goroutine, exit early. If not, this goroutine becomes the pending. - if b.existsPendingAuthReconfig.Swap(true) { - return - } - b.mu.Lock() defer b.mu.Unlock() - - // Allow another goroutine to become pending. - b.existsPendingAuthReconfig.Store(false) - b.authReconfigLocked() } |
