diff options
| author | Maisem Ali <maisem@tailscale.com> | 2022-08-04 10:51:21 -0700 |
|---|---|---|
| committer | Maisem Ali <maisem@gmail.com> | 2022-08-04 11:52:16 -0700 |
| commit | b75f81ec003c7ab39eb5b7c1aadc29df1d9a0932 (patch) | |
| tree | 02928c9f0e35f8c79dfe7455898bbe54948e9472 /syncs | |
| parent | 5055e00cf1e119e8242d655e48a5a9ba18136910 (diff) | |
| download | tailscale-b75f81ec003c7ab39eb5b7c1aadc29df1d9a0932.tar.xz tailscale-b75f81ec003c7ab39eb5b7c1aadc29df1d9a0932.zip | |
syncs: add generic AtomicValue
Signed-off-by: Maisem Ali <maisem@tailscale.com>
Diffstat (limited to 'syncs')
| -rw-r--r-- | syncs/syncs.go | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/syncs/syncs.go b/syncs/syncs.go index af9943632..1728a5df4 100644 --- a/syncs/syncs.go +++ b/syncs/syncs.go @@ -21,6 +21,49 @@ func initClosedChan() <-chan struct{} { return ch } +// AtomicValue is the generic version of atomic.Value. +type AtomicValue[T any] struct { + v atomic.Value +} + +// Load returns the value set by the most recent Store. +// It returns the zero value for T if the value is empty. +func (v *AtomicValue[T]) Load() T { + x, _ := v.LoadOk() + return x +} + +// LoadOk is like Load but returns a boolean indicating whether the value was +// loaded. +func (v *AtomicValue[T]) LoadOk() (_ T, ok bool) { + x := v.v.Load() + if x != nil { + return x.(T), true + } + var zero T + return zero, false +} + +// Store sets the value of the Value to x. +func (v *AtomicValue[T]) Store(x T) { + v.v.Store(x) +} + +// Swap stores new into Value and returns the previous value. +// It returns the zero value for T if the value is empty. +func (v *AtomicValue[T]) Swap(x T) (old T) { + oldV := v.v.Swap(x) + if oldV != nil { + return oldV.(T) + } + return old +} + +// CompareAndSwap executes the compare-and-swap operation for the Value. +func (v *AtomicValue[T]) CompareAndSwap(oldV, newV T) (swapped bool) { + return v.v.CompareAndSwap(oldV, newV) +} + // WaitGroupChan is like a sync.WaitGroup, but has a chan that closes // on completion that you can wait on. (This, you can only use the // value once) |
