bpo-33929: multiprocessing: fix handle leak on race condition (GH-7921)
Fix a race condition in Popen of
multiprocessing.popen_spawn_win32. The child process now duplicates
the read end of pipe instead of "stealing" it.
Previously, the read end of pipe was "stolen" by the child process,
but it leaked a handle if the child process had been terminated
before it could steal the handle from the parent process.
diff --git a/Lib/multiprocessing/spawn.py b/Lib/multiprocessing/spawn.py
index 1f4f3f4..2de4cb7 100644
--- a/Lib/multiprocessing/spawn.py
+++ b/Lib/multiprocessing/spawn.py
@@ -96,7 +96,15 @@
assert is_forking(sys.argv), "Not forking"
if sys.platform == 'win32':
import msvcrt
- new_handle = reduction.steal_handle(parent_pid, pipe_handle)
+ import _winapi
+
+ if parent_pid is not None:
+ source_process = _winapi.OpenProcess(
+ _winapi.PROCESS_DUP_HANDLE, False, parent_pid)
+ else:
+ source_process = None
+ new_handle = reduction.duplicate(pipe_handle,
+ source_process=source_process)
fd = msvcrt.open_osfhandle(new_handle, os.O_RDONLY)
else:
from . import semaphore_tracker