From: Spike Curtis Date: Thu, 17 Apr 2025 06:55:10 +0000 (+0000) Subject: net: fix deadlock in lookupProtocol on Windows X-Git-Tag: go1.25rc1~299 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=18431a1c8f7d19410fcd3fe6638cfe1cd4bd7179;p=gostls13.git net: fix deadlock in lookupProtocol on Windows If the context expires before acquireThread(ctx) succeeds, then the goroutine can block like: net.lookupProtocol.func1() src/net/lookup_windows.go:58 +0x105 created by net.lookupProtocol in goroutine 2834 src/net/lookup_windows.go:56 +0xda We saw this in our UTs with a leak detector, confirmed by inspection of the source code. Change-Id: I9b927f0345a2fa7336b23d95c506a8a0976e28d0 GitHub-Last-Rev: 27af7477a99bdbee0c32697837f1ff261ee70d83 GitHub-Pull-Request: golang/go#73364 Reviewed-on: https://go-review.googlesource.com/c/go/+/664956 Reviewed-by: Damien Neil Reviewed-by: Zxilly Chou Reviewed-by: David Chase LUCI-TryBot-Result: Go LUCI --- diff --git a/src/net/lookup_windows.go b/src/net/lookup_windows.go index 7a8fda0a30..38034dc601 100644 --- a/src/net/lookup_windows.go +++ b/src/net/lookup_windows.go @@ -52,7 +52,7 @@ func lookupProtocol(ctx context.Context, name string) (int, error) { proto int err error } - ch := make(chan result) // unbuffered + ch := make(chan result, 1) // buffer so that next goroutine never blocks go func() { if err := acquireThread(ctx); err != nil { ch <- result{err: mapErr(err)} @@ -62,10 +62,7 @@ func lookupProtocol(ctx context.Context, name string) (int, error) { runtime.LockOSThread() defer runtime.UnlockOSThread() proto, err := getprotobyname(name) - select { - case ch <- result{proto: proto, err: err}: - case <-ctx.Done(): - } + ch <- result{proto: proto, err: err} }() select { case r := <-ch: