Skip to content

Commit

Permalink
resolve atomic.Value usages with interface types
Browse files Browse the repository at this point in the history
  • Loading branch information
wwqgtxx committed Mar 29, 2024
1 parent dfadc7d commit f919a8d
Showing 1 changed file with 17 additions and 6 deletions.
23 changes: 17 additions & 6 deletions atomic/value.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,32 +11,43 @@ func DefaultValue[T any]() T {
}

type TypedValue[T any] struct {
value atomic.Value
_ noCopy
value atomic.Value
}

// tValue is a struct with determined type to resolve atomic.Value usages with interface types
// https://github.com/golang/go/issues/22550
//
// The intention to have an atomic value store for errors. However, running this code panics:
// panic: sync/atomic: store of inconsistently typed value into Value
// This is because atomic.Value requires that the underlying concrete type be the same (which is a reasonable expectation for its implementation).
// When going through the atomic.Value.Store method call, the fact that both these are of the error interface is lost.
type tValue[T any] struct {
value T
}

func (t *TypedValue[T]) Load() T {
value := t.value.Load()
if value == nil {
return DefaultValue[T]()
}
return value.(T)
return value.(tValue[T]).value
}

func (t *TypedValue[T]) Store(value T) {
t.value.Store(value)
t.value.Store(tValue[T]{value})
}

func (t *TypedValue[T]) Swap(new T) T {
old := t.value.Swap(new)
old := t.value.Swap(tValue[T]{new})
if old == nil {
return DefaultValue[T]()
}
return old.(T)
return old.(tValue[T]).value
}

func (t *TypedValue[T]) CompareAndSwap(old, new T) bool {
return t.value.CompareAndSwap(old, new)
return t.value.CompareAndSwap(tValue[T]{old}, tValue[T]{new})
}

func (t *TypedValue[T]) MarshalJSON() ([]byte, error) {
Expand Down

0 comments on commit f919a8d

Please sign in to comment.