From ccb69ea5e289a918acf0546a9d0ddc3bdbe1fe90 Mon Sep 17 00:00:00 2001 From: Kiang <50792067+kiangz@users.noreply.github.com> Date: Sun, 13 Sep 2026 03:51:59 +0800 Subject: [PATCH] common/buf/readv_windows.go: Fix raw WSARecv blocking thread and preventing connection close (#6743) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit https://github.com/XTLS/Xray-core/pull/6743#issuecomment-5647971870 --------- Co-authored-by: 风扇滑翔翼 --- common/buf/readv_windows.go | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) 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)