Skip to content

Commit bd4518c

Browse files
authored
gh-110036: multiprocessing Popen.terminate() catches PermissionError (#110037)
On Windows, multiprocessing Popen.terminate() now catchs PermissionError and get the process exit code. If the process is still running, raise again the PermissionError. Otherwise, the process terminated as expected: store its exit code.
1 parent 4e356ad commit bd4518c

File tree

3 files changed

+17
-4
lines changed

3 files changed

+17
-4
lines changed

Lib/multiprocessing/popen_spawn_win32.py

+9-2
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#
1515
#
1616

17+
# Exit code used by Popen.terminate()
1718
TERMINATE = 0x10000
1819
WINEXE = (sys.platform == 'win32' and getattr(sys, 'frozen', False))
1920
WINSERVICE = sys.executable.lower().endswith("pythonservice.exe")
@@ -122,9 +123,15 @@ def terminate(self):
122123
if self.returncode is None:
123124
try:
124125
_winapi.TerminateProcess(int(self._handle), TERMINATE)
125-
except OSError:
126-
if self.wait(timeout=1.0) is None:
126+
except PermissionError:
127+
# ERROR_ACCESS_DENIED (winerror 5) is received when the
128+
# process already died.
129+
code = _winapi.GetExitCodeProcess(int(self._handle))
130+
if code == _winapi.STILL_ACTIVE:
127131
raise
132+
self.returncode = code
133+
else:
134+
self.returncode = -signal.SIGTERM
128135

129136
kill = terminate
130137

Lib/test/_test_multiprocessing.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -557,13 +557,14 @@ def handler(*args):
557557

558558
def test_terminate(self):
559559
exitcode = self._kill_process(multiprocessing.Process.terminate)
560-
if os.name != 'nt':
561-
self.assertEqual(exitcode, -signal.SIGTERM)
560+
self.assertEqual(exitcode, -signal.SIGTERM)
562561

563562
def test_kill(self):
564563
exitcode = self._kill_process(multiprocessing.Process.kill)
565564
if os.name != 'nt':
566565
self.assertEqual(exitcode, -signal.SIGKILL)
566+
else:
567+
self.assertEqual(exitcode, -signal.SIGTERM)
567568

568569
def test_cpu_count(self):
569570
try:
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
On Windows, multiprocessing ``Popen.terminate()`` now catchs
2+
:exc:`PermissionError` and get the process exit code. If the process is
3+
still running, raise again the :exc:`PermissionError`. Otherwise, the
4+
process terminated as expected: store its exit code. Patch by Victor
5+
Stinner.

0 commit comments

Comments
 (0)