Skip to content

gh-158287: Fix blocked asyncio event loop on macOS when child process is stopped - #158962

Open
JohnnyWilson16 wants to merge 5 commits into
python:mainfrom
JohnnyWilson16:fix-gh-158287-asyncio-macos-cld-stopped
Open

JohnnyWilson16 wants to merge 5 commits into
python:mainfrom
JohnnyWilson16:fix-gh-158287-asyncio-macos-cld-stopped

Conversation

@JohnnyWilson16

Copy link
Copy Markdown

Fixes gh-158287.

On macOS (Darwin), os.waitid(os.P_PID, expected_pid, os.WEXITED | os.WNOWAIT) unexpectedly returns when a child process is stopped (SIGSTOP), reporting si_code == CLD_STOPPED despite WSTOPPED not being requested (a known Darwin kernel quirk, also observed in dotnet/runtime#133930).

In _ThreadedChildWatcher._do_waitpid, treating this as process exit schedules _reap_and_notify, where os.waitpid(expected_pid, 0) blocks the main event loop thread indefinitely because the child has not terminated.

This change consumes the stop notification via waitid(os.P_PID, expected_pid, consume_flags) and continues waiting until actual process termination. Also adds a regression test to SubprocessThreadedWatcherTests.

…rocess is stopped

On macOS, waitid(os.P_PID, pid, os.WEXITED | os.WNOWAIT) returns on SIGSTOP
with si_code == CLD_STOPPED even though WSTOPPED was not requested.
In _ThreadedChildWatcher, consume the stop notification and continue waiting
for actual process termination rather than calling _reap_and_notify with
os.waitpid(pid, 0) which blocks the event loop thread.
Comment thread Misc/NEWS.d/next/Library/2026-10-07-17-30-00.gh-issue-158287.xY9zQp.rst Outdated
Comment thread Lib/test/test_asyncio/test_subprocess.py
Comment thread Lib/asyncio/unix_events.py
Comment thread Lib/test/test_asyncio/test_subprocess.py Outdated
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

asyncio.subprocess blocked event loop unexpectedly on MacOS

2 participants