diff --git a/common/buf/readv_windows.go b/common/buf/readv_windows.go index a812ee04b..6b304e0fd 100644 --- a/common/buf/readv_windows.go +++ b/common/buf/readv_windows.go @@ -5,7 +5,8 @@ import ( ) type windowsReader struct { - bufs []syscall.WSABuf + bufs []syscall.WSABuf + ready bool } func (r *windowsReader) Init(bs []*Buffer) { @@ -15,6 +16,7 @@ func (r *windowsReader) Init(bs []*Buffer) { for _, b := range bs { r.bufs = append(r.bufs, syscall.WSABuf{Len: uint32(Size), Buf: &b.v[0]}) } + r.ready = false } func (r *windowsReader) Clear() { @@ -25,6 +27,14 @@ func (r *windowsReader) Clear() { } func (r *windowsReader) Read(fd uintptr) int32 { + // On the first invocation, we return -1 to indicate "not ready" + // to make rawConn.Read wait for readability using the runtime's own mechanism + // because syscall.WSARecv() is a blocking call when used with nil OVERLAPPED + if !r.ready { + r.ready = true + return -1 + } + var nBytes uint32 var flags uint32 err := syscall.WSARecv(syscall.Handle(fd), &r.bufs[0], uint32(len(r.bufs)), &nBytes, &flags, nil, nil)