Merge
This commit is contained in:
commit
0320025f17
|
@ -10,6 +10,7 @@
|
|||
import os
|
||||
import sys
|
||||
import signal
|
||||
import errno
|
||||
|
||||
from multiprocessing import util, process
|
||||
|
||||
|
@ -109,12 +110,17 @@ if sys.platform != 'win32':
|
|||
|
||||
def poll(self, flag=os.WNOHANG):
|
||||
if self.returncode is None:
|
||||
while True:
|
||||
try:
|
||||
pid, sts = os.waitpid(self.pid, flag)
|
||||
except OSError:
|
||||
except OSError as e:
|
||||
if e.errno == errno.EINTR:
|
||||
continue
|
||||
# Child process not yet created. See #1731717
|
||||
# e.errno == errno.ECHILD == 10
|
||||
return None
|
||||
else:
|
||||
break
|
||||
if pid == self.pid:
|
||||
if os.WIFSIGNALED(sts):
|
||||
self.returncode = -os.WTERMSIG(sts)
|
||||
|
|
|
@ -2868,6 +2868,38 @@ class _TestLogging(BaseTestCase):
|
|||
# logger.warn('foo')
|
||||
# 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
|
||||
#
|
||||
|
|
Loading…
Reference in New Issue