microsoft / go-winio

Win32 IO-related utilities for Go
MIT License
939 stars 181 forks source link

The win32PipeListener.Close() hangs if nobody calls Accept() #281

Open thallgren opened 1 year ago

thallgren commented 1 year ago

The win32PipeListener.Close() function attempts to write to an unbuffered channel that has no reader unless someone calls the Accept() function. As a result, the call to Close() hangs indefinitely. The stack trace from the goroutine that is hanging can look like this:

goroutine 84 [chan receive, 5 minutes]:
github.com/Microsoft/go-winio.(*win32PipeListener).Close(0xc0002cdb30)
    github.com/Microsoft/go-winio@v0.6.0/pipe.go:513 +0x85
net/http.(*onceCloseListener).close(...)
    net/http/server.go:3501
sync.(*Once).doSlow(0xc0009a7a50?, 0x1e0d56?)
    sync/once.go:74 +0xc2
sync.(*Once).Do(...)
    sync/once.go:65
net/http.(*onceCloseListener).Close(0xc0005e4bd0?)
    net/http/server.go:3497 +0x4a
net/http.(*Server).closeListenersLocked(0x0?)
    net/http/server.go:2850 +0xad
net/http.(*Server).Shutdown(0xc0002020f0, {0x2690400, 0xc000376500})
    net/http/server.go:2776 +0xa5