Skip to content

Commit 3d7dfbc

Browse files
committed
bpo-40550: fix time-of-check/time-of-action issue in multiprocessing
Signed-off-by: Filipe Laíns <lains@archlinux.org>
1 parent d10091a commit 3d7dfbc

File tree

3 files changed

+21
-1
lines changed

3 files changed

+21
-1
lines changed

Lib/subprocess.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2061,7 +2061,13 @@ def send_signal(self, sig):
20612061
# The race condition can still happen if the race condition
20622062
# described above happens between the returncode test
20632063
# and the kill() call.
2064-
os.kill(self.pid, sig)
2064+
try:
2065+
os.kill(self.pid, sig)
2066+
except ProcessLookupError as e:
2067+
# supress the process not found error in case the race
2068+
# condition happens, see bpo-40550
2069+
if e.errno != errno.ESRCH:
2070+
raise e
20652071

20662072
def terminate(self):
20672073
"""Terminate the process with SIGTERM

Lib/test/test_subprocess.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3145,6 +3145,19 @@ def test_send_signal_race(self):
31453145
# so Popen failed to read it and uses a default returncode instead.
31463146
self.assertIsNotNone(proc.returncode)
31473147

3148+
def test_send_signal_race2(self):
3149+
# bpo-40550: the process might exist between the returncode check and
3150+
# the kill operation
3151+
p = subprocess.Popen([sys.executable, '-c', 'exit(1)'])
3152+
3153+
# wait for process to exit
3154+
while not p.returncode:
3155+
p.poll()
3156+
3157+
with mock.patch.object(p, 'poll', new=lambda: None):
3158+
p.returncode = None
3159+
p.send_signal(signal.SIGTERM)
3160+
31483161
def test_communicate_repeated_call_after_stdout_close(self):
31493162
proc = subprocess.Popen([sys.executable, '-c',
31503163
'import os, time; os.close(1), time.sleep(2)'],
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix time-of-check/time-of-action issue in subprocess.Popen.send_signal.

0 commit comments

Comments
 (0)