mirror of https://github.com/python/cpython
Issue #17018: Make Process.join() retry if os.waitpid() fails with EINTR.
This commit is contained in:
parent
b1bbc0b3dc
commit
ba48264bce
|
@ -35,6 +35,7 @@
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import signal
|
import signal
|
||||||
|
import errno
|
||||||
|
|
||||||
from multiprocessing import util, process
|
from multiprocessing import util, process
|
||||||
|
|
||||||
|
@ -129,12 +130,17 @@ if sys.platform != 'win32':
|
||||||
|
|
||||||
def poll(self, flag=os.WNOHANG):
|
def poll(self, flag=os.WNOHANG):
|
||||||
if self.returncode is None:
|
if self.returncode is None:
|
||||||
try:
|
while True:
|
||||||
pid, sts = os.waitpid(self.pid, flag)
|
try:
|
||||||
except os.error:
|
pid, sts = os.waitpid(self.pid, flag)
|
||||||
# Child process not yet created. See #1731717
|
except os.error as e:
|
||||||
# e.errno == errno.ECHILD == 10
|
if e.errno == errno.EINTR:
|
||||||
return None
|
continue
|
||||||
|
# Child process not yet created. See #1731717
|
||||||
|
# e.errno == errno.ECHILD == 10
|
||||||
|
return None
|
||||||
|
else:
|
||||||
|
break
|
||||||
if pid == self.pid:
|
if pid == self.pid:
|
||||||
if os.WIFSIGNALED(sts):
|
if os.WIFSIGNALED(sts):
|
||||||
self.returncode = -os.WTERMSIG(sts)
|
self.returncode = -os.WTERMSIG(sts)
|
||||||
|
|
|
@ -2104,6 +2104,38 @@ class _TestLogging(BaseTestCase):
|
||||||
# logger.warn('foo')
|
# logger.warn('foo')
|
||||||
# assert self.__handled
|
# assert self.__handled
|
||||||
|
|
||||||
|
#
|
||||||
|
# Check that Process.join() retries if os.waitpid() fails with EINTR
|
||||||
|
#
|
||||||
|
|
||||||
|
class _TestPollEintr(BaseTestCase):
|
||||||
|
|
||||||
|
ALLOWED_TYPES = ('processes',)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def _killer(cls, pid):
|
||||||
|
time.sleep(0.5)
|
||||||
|
os.kill(pid, signal.SIGUSR1)
|
||||||
|
|
||||||
|
@unittest.skipUnless(hasattr(signal, 'SIGUSR1'), 'requires SIGUSR1')
|
||||||
|
def test_poll_eintr(self):
|
||||||
|
got_signal = [False]
|
||||||
|
def record(*args):
|
||||||
|
got_signal[0] = True
|
||||||
|
pid = os.getpid()
|
||||||
|
oldhandler = signal.signal(signal.SIGUSR1, record)
|
||||||
|
try:
|
||||||
|
killer = self.Process(target=self._killer, args=(pid,))
|
||||||
|
killer.start()
|
||||||
|
p = self.Process(target=time.sleep, args=(1,))
|
||||||
|
p.start()
|
||||||
|
p.join()
|
||||||
|
self.assertTrue(got_signal[0])
|
||||||
|
self.assertEqual(p.exitcode, 0)
|
||||||
|
killer.join()
|
||||||
|
finally:
|
||||||
|
signal.signal(signal.SIGUSR1, oldhandler)
|
||||||
|
|
||||||
#
|
#
|
||||||
# Test to verify handle verification, see issue 3321
|
# Test to verify handle verification, see issue 3321
|
||||||
#
|
#
|
||||||
|
|
|
@ -211,6 +211,8 @@ Core and Builtins
|
||||||
Library
|
Library
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
- Issue #17018: Make Process.join() retry if os.waitpid() fails with EINTR.
|
||||||
|
|
||||||
- Issue #14720: sqlite3: Convert datetime microseconds correctly.
|
- Issue #14720: sqlite3: Convert datetime microseconds correctly.
|
||||||
Patch by Lowe Thiderman.
|
Patch by Lowe Thiderman.
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue