aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/Lib/multiprocessing/popen_spawn_win32.py
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/multiprocessing/popen_spawn_win32.py')
-rw-r--r--Lib/multiprocessing/popen_spawn_win32.py54
1 files changed, 30 insertions, 24 deletions
diff --git a/Lib/multiprocessing/popen_spawn_win32.py b/Lib/multiprocessing/popen_spawn_win32.py
index af044305709..49d4c7eea22 100644
--- a/Lib/multiprocessing/popen_spawn_win32.py
+++ b/Lib/multiprocessing/popen_spawn_win32.py
@@ -101,18 +101,20 @@ class Popen(object):
return reduction.duplicate(handle, self.sentinel)
def wait(self, timeout=None):
- if self.returncode is None:
- if timeout is None:
- msecs = _winapi.INFINITE
- else:
- msecs = max(0, int(timeout * 1000 + 0.5))
-
- res = _winapi.WaitForSingleObject(int(self._handle), msecs)
- if res == _winapi.WAIT_OBJECT_0:
- code = _winapi.GetExitCodeProcess(self._handle)
- if code == TERMINATE:
- code = -signal.SIGTERM
- self.returncode = code
+ if self.returncode is not None:
+ return self.returncode
+
+ if timeout is None:
+ msecs = _winapi.INFINITE
+ else:
+ msecs = max(0, int(timeout * 1000 + 0.5))
+
+ res = _winapi.WaitForSingleObject(int(self._handle), msecs)
+ if res == _winapi.WAIT_OBJECT_0:
+ code = _winapi.GetExitCodeProcess(self._handle)
+ if code == TERMINATE:
+ code = -signal.SIGTERM
+ self.returncode = code
return self.returncode
@@ -120,18 +122,22 @@ class Popen(object):
return self.wait(timeout=0)
def terminate(self):
- if self.returncode is None:
- try:
- _winapi.TerminateProcess(int(self._handle), TERMINATE)
- except PermissionError:
- # ERROR_ACCESS_DENIED (winerror 5) is received when the
- # process already died.
- code = _winapi.GetExitCodeProcess(int(self._handle))
- if code == _winapi.STILL_ACTIVE:
- raise
- self.returncode = code
- else:
- self.returncode = -signal.SIGTERM
+ if self.returncode is not None:
+ return
+
+ try:
+ _winapi.TerminateProcess(int(self._handle), TERMINATE)
+ except PermissionError:
+ # ERROR_ACCESS_DENIED (winerror 5) is received when the
+ # process already died.
+ code = _winapi.GetExitCodeProcess(int(self._handle))
+ if code == _winapi.STILL_ACTIVE:
+ raise
+
+ # gh-113009: Don't set self.returncode. Even if GetExitCodeProcess()
+ # returns an exit code different than STILL_ACTIVE, the process can
+ # still be running. Only set self.returncode once WaitForSingleObject()
+ # returns WAIT_OBJECT_0 in wait().
kill = terminate