From dceb8ee535dafbc56740c7ab702e067c9ea8ecce Mon Sep 17 00:00:00 2001 From: wwqgtxx Date: Wed, 13 Mar 2024 14:49:46 +0800 Subject: [PATCH] fix: resolve atomic.Value usages with interface types --- common/atomic/value.go | 19 +++++++++++++++---- go.mod | 2 +- go.sum | 4 ++-- 3 files changed, 18 insertions(+), 7 deletions(-) diff --git a/common/atomic/value.go b/common/atomic/value.go index cbc6c5b8c..36623b3ee 100644 --- a/common/atomic/value.go +++ b/common/atomic/value.go @@ -15,20 +15,31 @@ type TypedValue[T any] struct { 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]() } @@ -36,7 +47,7 @@ func (t *TypedValue[T]) Swap(new T) T { } 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) { diff --git a/go.mod b/go.mod index 2d1ac543e..9becc8c85 100644 --- a/go.mod +++ b/go.mod @@ -111,4 +111,4 @@ require ( golang.org/x/tools v0.18.0 // indirect ) -replace github.com/sagernet/sing => github.com/metacubex/sing v0.0.0-20240313005020-c77f32e55220 +replace github.com/sagernet/sing => github.com/metacubex/sing v0.0.0-20240313064558-c197257f6542 diff --git a/go.sum b/go.sum index 62e8fb69b..7277a32e1 100644 --- a/go.sum +++ b/go.sum @@ -106,8 +106,8 @@ github.com/metacubex/gvisor v0.0.0-20240214095142-666a73bcf165 h1:QIQI4gEm+gTwVN github.com/metacubex/gvisor v0.0.0-20240214095142-666a73bcf165/go.mod h1:SKY70wiF1UTSoyuDZyKPMsUC6MsMxh8Y3ZNkIa6J3fU= github.com/metacubex/quic-go v0.41.1-0.20240307164142-46c6f7cdf2d1 h1:63zKmEWU4MB5MjUSCmeDhm3OzilF7ypXWPq0gAA2GE8= github.com/metacubex/quic-go v0.41.1-0.20240307164142-46c6f7cdf2d1/go.mod h1:F/t8VnA47xoia8ABlNA4InkZjssvFJ5p6E6jKdbkgAs= -github.com/metacubex/sing v0.0.0-20240313005020-c77f32e55220 h1:lZLFR28Jf3gjoHh560uC8AKnWcQ2+VQoQY/rSj6kSrc= -github.com/metacubex/sing v0.0.0-20240313005020-c77f32e55220/go.mod h1:+60H3Cm91RnL9dpVGWDPHt0zTQImO9Vfqt9a4rSambI= +github.com/metacubex/sing v0.0.0-20240313064558-c197257f6542 h1:e9nBnrJBv3HzZVeSzJN0G2SADjebd2ZLF1F5dmsjUTc= +github.com/metacubex/sing v0.0.0-20240313064558-c197257f6542/go.mod h1:+60H3Cm91RnL9dpVGWDPHt0zTQImO9Vfqt9a4rSambI= github.com/metacubex/sing-quic v0.0.0-20240310154810-47bca850fc01 h1:5INHs85Gp1JZsdF7fQp1pXUjfJOX2dhwZjuUQWJVSt8= github.com/metacubex/sing-quic v0.0.0-20240310154810-47bca850fc01/go.mod h1:WyY0zYxv+o+18R/Ece+QFontlgXoobKbNqbtYn2zjz8= github.com/metacubex/sing-shadowsocks v0.2.6 h1:6oEB3QcsFYnNiFeoevcXrCwJ3sAablwVSgtE9R3QeFQ=