-
-
Notifications
You must be signed in to change notification settings - Fork 3.1k
Support parallel type checking on Windows #20777
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -359,11 +359,60 @@ def ready_to_read(conns: list[IPCClient], timeout: float | None = None) -> list[ | |
|
|
||
| Return index of each readable connection in the original list. | ||
| """ | ||
| # TODO: add Windows support for this. | ||
| assert sys.platform != "win32" | ||
| connections = [conn.connection for conn in conns] | ||
| ready, _, _ = select(connections, [], [], timeout) | ||
| return [connections.index(r) for r in ready] | ||
| if sys.platform == "win32": | ||
| # Windows doesn't support select() on named pipes. Instead, start an overlapped | ||
| # ReadFile on each pipe (which internally creates an event via CreateEventW), | ||
| # then WaitForMultipleObjects on those events for efficient OS-level waiting. | ||
| # Any data consumed by the probe reads is stored into each connection's buffer | ||
| # so the subsequent read_bytes() call will find it via frame_from_buffer(). | ||
| WAIT_FAILED = 0xFFFFFFFF | ||
| pending: list[tuple[int, _winapi.Overlapped]] = [] | ||
| events: list[int] = [] | ||
| ready: list[int] = [] | ||
|
|
||
| for i, conn in enumerate(conns): | ||
| try: | ||
| ov, err = _winapi.ReadFile(conn.connection, 1, overlapped=True) | ||
| except OSError: | ||
| # Broken/closed pipe | ||
| continue | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not sure this So I guess we can either raise |
||
| if err == _winapi.ERROR_IO_PENDING: | ||
| events.append(ov.event) | ||
| pending.append((i, ov)) | ||
| else: | ||
| # Data was immediately available (err == 0 or ERROR_MORE_DATA) | ||
| _, err = ov.GetOverlappedResult(True) | ||
| data = ov.getbuffer() | ||
| if data: | ||
| conn.buffer.extend(data) | ||
| ready.append(i) | ||
|
|
||
| # Wait only if nothing is immediately ready and there are pending operations | ||
| if not ready and events: | ||
| timeout_ms = int(timeout * 1000) if timeout is not None else _winapi.INFINITE | ||
| res = _winapi.WaitForMultipleObjects(events, False, timeout_ms) | ||
| if res == WAIT_FAILED: | ||
| for _, ov in pending: | ||
| ov.cancel() | ||
| raise IPCException(f"Failed to wait for connections: {_winapi.GetLastError()}") | ||
|
|
||
| # Check which pending operations completed, cancel the rest | ||
| for i, ov in pending: | ||
| if _winapi.WaitForSingleObject(ov.event, 0) == _winapi.WAIT_OBJECT_0: | ||
| _, err = ov.GetOverlappedResult(True) | ||
| data = ov.getbuffer() | ||
| if data: | ||
| conns[i].buffer.extend(data) | ||
| ready.append(i) | ||
| else: | ||
| ov.cancel() | ||
|
|
||
| return ready | ||
|
|
||
| else: | ||
| connections = [conn.connection for conn in conns] | ||
| ready, _, _ = select(connections, [], [], timeout) | ||
| return [connections.index(r) for r in ready] | ||
|
|
||
|
|
||
| def send(connection: IPCBase, data: IPCMessage) -> None: | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like we are not the first affected by this. Apparently virtual environments and other launchers on Windows create "wrapper" processes, so we will get a different PIDs, even if using
sys.executable. Found this one https://stackoverflow.com/questions/64884701/subprocess-has-wrong-pid-on-windows (and a bunch of similar questions).There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good find! Somehow my searching didn't find that. I'll update the comment to reflect it.