Wait for overlapped WriteFile completion in Rust (#7383)

On Windows, SimpleQueue skips write locking because pipe
writes are assumed atomic. Without GIL, PipeConnection.
_send_bytes races on _send_ov when multiple threads call
send_bytes concurrently (e.g. _terminate_pool vs workers).

Wait for pending overlapped writes inside WriteFile before
returning to Python, so ERROR_IO_PENDING is never exposed
and the _send_ov assignment window is negligible.
This commit is contained in:
Jeong, YunWon authored and GitHub committed 2026-03-08 18:04:19 +09:00
1 parent fbab8fc5be
commit 0046c627f1
1 file changed
+20
+20
View File
@@ -1251,6 +1251,26 @@ mod _winapi {
err
};
// Without GIL, the Python-level PipeConnection._send_bytes has a
// race on _send_ov when the caller (SimpleQueue) skips locking on
// Windows. Wait for completion here so the caller never sees
// ERROR_IO_PENDING and never blocks in WaitForMultipleObjects,
// keeping the _send_ov window negligibly small.
if err == ERROR_IO_PENDING {
let event = ov.inner.lock().overlapped.hEvent;
vm.allow_threads(|| unsafe {
windows_sys::Win32::System::Threading::WaitForSingleObject(
event,
windows_sys::Win32::System::Threading::INFINITE,
);
});
let result = vm
.ctx
.new_tuple(vec![ov.into_pyobject(vm), vm.ctx.new_int(0u32).into()]);
return Ok(result.into());
}
let result = vm
.ctx
.new_tuple(vec![ov.into_pyobject(vm), vm.ctx.new_int(err).into()]);