Skip to content

Commit a22c8bf

Browse files
committed
net: fix deadlock in lookupProtocol on Windows
If the context expires before `acquireThread(ctx)` succeeds, then the goroutine can block like: ``` net.lookupProtocol.func1() C:/hostedtoolcache/windows/go/1.24.1/x64/src/net/lookup_windows.go:58 +0x105 created by net.lookupProtocol in goroutine 2834 C:/hostedtoolcache/windows/go/1.24.1/x64/src/net/lookup_windows.go:56 +0xda ``` We saw this in our UTs with a leak detector, confirmed by inspection of the source code.
1 parent 13b7c7d commit a22c8bf

File tree

1 file changed

+2
-5
lines changed

1 file changed

+2
-5
lines changed

src/net/lookup_windows.go

+2-5
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ func lookupProtocol(ctx context.Context, name string) (int, error) {
5252
proto int
5353
err error
5454
}
55-
ch := make(chan result) // unbuffered
55+
ch := make(chan result, 1) // buffer so that next goroutine never blocks
5656
go func() {
5757
if err := acquireThread(ctx); err != nil {
5858
ch <- result{err: mapErr(err)}
@@ -62,10 +62,7 @@ func lookupProtocol(ctx context.Context, name string) (int, error) {
6262
runtime.LockOSThread()
6363
defer runtime.UnlockOSThread()
6464
proto, err := getprotobyname(name)
65-
select {
66-
case ch <- result{proto: proto, err: err}:
67-
case <-ctx.Done():
68-
}
65+
ch <- result{proto: proto, err: err}
6966
}()
7067
select {
7168
case r := <-ch:

0 commit comments

Comments
 (0)