From 4d980a77c59f42e39ad3ab8bf0449682cddbb2f2 Mon Sep 17 00:00:00 2001 From: Simon Law Date: Wed, 27 May 2026 21:46:43 -0700 Subject: [PATCH] fixup! net/routecheck: introduce new package for checking peer reachability @illotum points out that there was a race between atomic.Pointer.Load and Store. Of course, we should have used Swap. Signed-off-by: Simon Law --- net/routecheck/routecheck.go | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/net/routecheck/routecheck.go b/net/routecheck/routecheck.go index 76bf1daf4..063f1ea93 100644 --- a/net/routecheck/routecheck.go +++ b/net/routecheck/routecheck.go @@ -114,9 +114,21 @@ func (c *Client) NotifyNetMapAvailable(nm *netmap.NetworkMap) { if nm == nil { return // client disconnected } - ch := c.hasNetMap.Load() - c.hasNetMap.Store(new(make(chan struct{}))) // prepare for next non-nil netmap - close(*ch) // broadcast to waitForNetMap + var nextCh *chan struct{} + for { + ch := c.hasNetMap.Load() + if *ch == nil { + return // Client has been Closed + } + + if nextCh == nil { + nextCh = new(make(chan struct{})) // prepare for next non-nil netmap + } + if c.hasNetMap.CompareAndSwap(ch, nextCh) { + close(*ch) + return + } + } } func (c *Client) waitForNetMap(ctx context.Context) (*netmap.NetworkMap, error) { @@ -144,9 +156,9 @@ func (c *Client) Close() error { return nil } - ch := c.hasNetMap.Load() - c.hasNetMap.Store(new(chan struct{})) // clear and unlock before waking anything up - if ch != nil { + nilCh := new(chan struct{}) + ch := c.hasNetMap.Swap(nilCh) // clear before waking anything up + if *ch != nil { close(*ch) }