From 4bc9f8ed3773f46fb153095a9cd9a3b3408eb439 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=A3=8E=E6=89=87=E6=BB=91=E7=BF=94=E7=BF=BC?= Date: Fri, 13 Jun 2025 09:19:35 +0000 Subject: [PATCH] Refine --- common/utils/TypedSyncMap.go | 28 +++++++++++++++++++++++----- proxy/freedom/freedom.go | 4 ++-- 2 files changed, 25 insertions(+), 7 deletions(-) diff --git a/common/utils/TypedSyncMap.go b/common/utils/TypedSyncMap.go index 7512c0fb..0cddc8eb 100644 --- a/common/utils/TypedSyncMap.go +++ b/common/utils/TypedSyncMap.go @@ -1,4 +1,4 @@ -package util +package utils import ( "sync" @@ -6,6 +6,7 @@ import ( // TypedSyncMap is a wrapper of sync.Map that provides type-safe for keys and values. // No need to use type assertions every time, so you can have more time to enjoy other things like GochiUsa +// If sync.Map returned nil, it will return the zero value of the type V. type TypedSyncMap[K, V any] struct { syncMap *sync.Map } @@ -34,26 +35,43 @@ func (m *TypedSyncMap[K, V]) Delete(key K) { func (m *TypedSyncMap[K, V]) Load(key K) (value V, ok bool) { anyValue, ok := m.syncMap.Load(key) - return anyValue.(V), ok + // anyValue might be nil + if anyValue != nil { + value = anyValue.(V) + } + return value, ok } func (m *TypedSyncMap[K, V]) LoadAndDelete(key K) (value V, loaded bool) { anyValue, loaded := m.syncMap.LoadAndDelete(key) - return anyValue.(V), loaded + if anyValue != nil { + value = anyValue.(V) + } + return value, loaded } + func (m *TypedSyncMap[K, V]) LoadOrStore(key K, value V) (actual V, loaded bool) { anyActual, loaded := m.syncMap.LoadOrStore(key, value) - return anyActual.(V), loaded + if anyActual != nil { + actual = anyActual.(V) + } + return actual, loaded } + func (m *TypedSyncMap[K, V]) Range(f func(key K, value V) bool) { m.syncMap.Range(func(key, value any) bool { return f(key.(K), value.(V)) }) } + func (m *TypedSyncMap[K, V]) Store(key K, value V) { m.syncMap.Store(key, value) } + func (m *TypedSyncMap[K, V]) Swap(key K, value V) (previous V, loaded bool) { anyPrevious, loaded := m.syncMap.Swap(key, value) - return anyPrevious.(V), loaded + if anyPrevious != nil { + previous = anyPrevious.(V) + } + return previous, loaded } \ No newline at end of file diff --git a/proxy/freedom/freedom.go b/proxy/freedom/freedom.go index e4f49d9d..cb5c7ead 100644 --- a/proxy/freedom/freedom.go +++ b/proxy/freedom/freedom.go @@ -344,7 +344,7 @@ func NewPacketWriter(conn net.Conn, h *Handler, ctx context.Context, UDPOverride Handler: h, Context: ctx, UDPOverride: UDPOverride, - resolvedUDPAddr: util.NewTypedSyncMap[string, net.Address](), + resolvedUDPAddr: utils.NewTypedSyncMap[string, net.Address](), } } @@ -362,7 +362,7 @@ type PacketWriter struct { // But resolver will return a random one if the domain has many IPs // Resulting in these packets being sent to many different IPs randomly // So, cache and keep the resolve result - resolvedUDPAddr *util.TypedSyncMap[string, net.Address] + resolvedUDPAddr *utils.TypedSyncMap[string, net.Address] } func (w *PacketWriter) WriteMultiBuffer(mb buf.MultiBuffer) error {