From a58afe44fa3be498e213bafa77455ffdfe5e23e2 Mon Sep 17 00:00:00 2001 From: database64128 Date: Wed, 17 Sep 2025 04:25:53 +0800 Subject: [PATCH] net: fix testHookCanceledDial race Loading and calling testHookCanceledDial in the function passed to context.AfterFunc is racey, because the function runs in a separate goroutine, and is not synchronized with the test code that restores the original testHookCanceledDial value. We could add a channel and wait for the "AfterFunc" to return in the deferred function, but that's a lot of synchronization overhead just for a bit of test code. Instead we simply load testHookCanceledDial into a local variable synchronously. This fixes the race without introducing any overhead. Fixes #75474 Change-Id: If8fbd0f5f65375577c2ded64a13a15b406c45ecc Reviewed-on: https://go-review.googlesource.com/c/go/+/704455 Reviewed-by: Dmitri Shuralyov LUCI-TryBot-Result: Go LUCI Auto-Submit: Dmitri Shuralyov Reviewed-by: Damien Neil Auto-Submit: Damien Neil Reviewed-by: Dmitri Shuralyov --- src/net/fd_unix.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/net/fd_unix.go b/src/net/fd_unix.go index 40ecbef2e8..0d4303e2cc 100644 --- a/src/net/fd_unix.go +++ b/src/net/fd_unix.go @@ -82,6 +82,9 @@ func (fd *netFD) connect(ctx context.Context, la, ra syscall.Sockaddr) (rsa sysc defer fd.pfd.SetWriteDeadline(noDeadline) } + // Load the hook function synchronously to prevent a race + // with test code that restores the old value. + testHookCanceledDial := testHookCanceledDial stop := context.AfterFunc(ctx, func() { // Force the runtime's poller to immediately give up // waiting for writability, unblocking waitWrite -- 2.52.0