gh-146313: Fix multiprocessing ResourceTracker deadlock after os.fork() (GH-146316)
`ResourceTracker.__del__` (added in gh-88887 circa Python 3.12) calls os.waitpid(pid, 0) which blocks indefinitely if a process created via os.fork() still holds the tracker pipe's write end. The tracker never sees EOF, never exits, and the parent hangs at interpreter shutdown. Fix with two layers: - **At-fork handler.** An os.register_at_fork(after_in_child=...) handler closes the inherited pipe fd in the child unless a preserve flag is set. popen_fork.Popen._launch() sets the flag before its fork so mp.Process(fork) children keep the fd and reuse the parent's tracker (preserving gh-80849). Raw os.fork() children close the fd, letting the parent reap promptly. - **Timeout safety-net.** _stop_locked() gains a wait_timeout parameter. When called from `__del__`, it polls with WNOHANG using exponential backoff for up to 1 second instead of blocking indefinitely. The at-fork handler makes this unreachable in well-behaved paths; it remains for abnormal shutdowns. Co-authored-by: Itamar Oren <itamarost@gmail.com>
G
Gregory P. Smith committed
3a7df632c96eb6c5de12fac08d1da42df9e25334
Parent: cbd81d5
Committed by GitHub <noreply@github.com>
on 4/12/2026, 6:06:19 AM