From: database64128 Date: Tue, 16 Sep 2025 20:25:53 +0000 (+0800) Subject: net: fix testHookCanceledDial race X-Git-Tag: go1.26rc1~832 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=a58afe44fa3be498e213bafa77455ffdfe5e23e2;p=gostls13.git 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 --- 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