Update
This commit is contained in:
4
vendor/tailscale.com/syncs/locked.go
generated
vendored
4
vendor/tailscale.com/syncs/locked.go
generated
vendored
@@ -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
23
vendor/tailscale.com/syncs/mutex.go
generated
vendored
Normal 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
22
vendor/tailscale.com/syncs/mutex_debug.go
generated
vendored
Normal 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
33
vendor/tailscale.com/syncs/syncs.go
generated
vendored
@@ -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()
|
||||
}()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user