From b75f81ec003c7ab39eb5b7c1aadc29df1d9a0932 Mon Sep 17 00:00:00 2001 From: Maisem Ali Date: Thu, 4 Aug 2022 10:51:21 -0700 Subject: [PATCH] syncs: add generic AtomicValue Signed-off-by: Maisem Ali --- syncs/syncs.go | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/syncs/syncs.go b/syncs/syncs.go index af9943632f876..1728a5df4bd0e 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)