This commit is contained in:
2026-02-19 10:07:43 +00:00
parent 007438e372
commit 6e637ecf77
1763 changed files with 60820 additions and 279516 deletions

View File

@@ -8,7 +8,7 @@ import (
)
// AssertLocked panics if m is not locked.
func AssertLocked(m *sync.Mutex) {
func AssertLocked(m *Mutex) {
if m.TryLock() {
m.Unlock()
panic("mutex is not locked")
@@ -16,7 +16,7 @@ func AssertLocked(m *sync.Mutex) {
}
// AssertRLocked panics if rw is not locked for reading or writing.
func AssertRLocked(rw *sync.RWMutex) {
func AssertRLocked(rw *RWMutex) {
if rw.TryLock() {
rw.Unlock()
panic("mutex is not locked")

23
vendor/tailscale.com/syncs/mutex.go generated vendored Normal file
View File

@@ -0,0 +1,23 @@
// Copyright (c) Tailscale Inc & AUTHORS
// SPDX-License-Identifier: BSD-3-Clause
//go:build !ts_mutex_debug
package syncs
import "sync"
// Mutex is an alias for sync.Mutex.
//
// It's only not a sync.Mutex when built with the ts_mutex_debug build tag.
type Mutex = sync.Mutex
// RWMutex is an alias for sync.RWMutex.
//
// It's only not a sync.RWMutex when built with the ts_mutex_debug build tag.
type RWMutex = sync.RWMutex
// RequiresMutex declares the caller assumes it has the given
// mutex held. In non-debug builds, it's a no-op and compiles to
// nothing.
func RequiresMutex(mu *sync.Mutex) {}

22
vendor/tailscale.com/syncs/mutex_debug.go generated vendored Normal file
View File

@@ -0,0 +1,22 @@
// Copyright (c) Tailscale Inc & AUTHORS
// SPDX-License-Identifier: BSD-3-Clause
//go:build ts_mutex_debug
package syncs
import "sync"
type Mutex struct {
sync.Mutex
}
type RWMutex struct {
sync.RWMutex
}
func RequiresMutex(mu *sync.Mutex) {
// TODO: check
}
// TODO(bradfitz): actually track stuff when in debug mode.

33
vendor/tailscale.com/syncs/syncs.go generated vendored
View File

@@ -67,12 +67,18 @@ func (v *AtomicValue[T]) Swap(x T) (old T) {
if oldV != nil {
return oldV.(wrappedValue[T]).v
}
return old
return old // zero value of T
}
// CompareAndSwap executes the compare-and-swap operation for the Value.
// It panics if T is not comparable.
func (v *AtomicValue[T]) CompareAndSwap(oldV, newV T) (swapped bool) {
return v.v.CompareAndSwap(wrappedValue[T]{oldV}, wrappedValue[T]{newV})
var zero T
return v.v.CompareAndSwap(wrappedValue[T]{oldV}, wrappedValue[T]{newV}) ||
// In the edge-case where [atomic.Value.Store] is uninitialized
// and trying to compare with the zero value of T,
// then compare-and-swap with the nil any value.
(any(oldV) == any(zero) && v.v.CompareAndSwap(any(nil), wrappedValue[T]{newV}))
}
// MutexValue is a value protected by a mutex.
@@ -195,6 +201,13 @@ func NewSemaphore(n int) Semaphore {
return Semaphore{c: make(chan struct{}, n)}
}
// Len reports the number of in-flight acquisitions.
// It is incremented whenever the semaphore is acquired.
// It is decremented whenever the semaphore is released.
func (s Semaphore) Len() int {
return len(s.c)
}
// Acquire blocks until a resource is acquired.
func (s Semaphore) Acquire() {
s.c <- struct{}{}
@@ -396,19 +409,3 @@ func (m *Map[K, V]) Swap(key K, value V) (oldValue V) {
mak.Set(&m.m, key, value)
return oldValue
}
// WaitGroup is identical to [sync.WaitGroup],
// but provides a Go method to start a goroutine.
type WaitGroup struct{ sync.WaitGroup }
// Go calls the given function in a new goroutine.
// It automatically increments the counter before execution and
// automatically decrements the counter after execution.
// It must not be called concurrently with Wait.
func (wg *WaitGroup) Go(f func()) {
wg.Add(1)
go func() {
defer wg.Done()
f()
}()
}