File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change 3535import os
3636import sys
3737import signal
38+ import errno
3839
3940from multiprocessing import util , process
4041
@@ -128,12 +129,17 @@ def __init__(self, process_obj):
128129
129130 def poll (self , flag = os .WNOHANG ):
130131 if self .returncode is None :
131- try :
132- pid , sts = os .waitpid (self .pid , flag )
133- except os .error :
134- # Child process not yet created. See #1731717
135- # e.errno == errno.ECHILD == 10
136- return None
132+ while True :
133+ try :
134+ pid , sts = os .waitpid (self .pid , flag )
135+ except os .error as e :
136+ if e .errno == errno .EINTR :
137+ continue
138+ # Child process not yet created. See #1731717
139+ # e.errno == errno.ECHILD == 10
140+ return None
141+ else :
142+ break
137143 if pid == self .pid :
138144 if os .WIFSIGNALED (sts ):
139145 self .returncode = - os .WTERMSIG (sts )
Original file line number Diff line number Diff line change @@ -2167,6 +2167,38 @@ def test_level(self):
21672167# logger.warn('foo')
21682168# assert self.__handled
21692169
2170+ #
2171+ # Check that Process.join() retries if os.waitpid() fails with EINTR
2172+ #
2173+
2174+ class _TestPollEintr (BaseTestCase ):
2175+
2176+ ALLOWED_TYPES = ('processes' ,)
2177+
2178+ @classmethod
2179+ def _killer (cls , pid ):
2180+ time .sleep (0.5 )
2181+ os .kill (pid , signal .SIGUSR1 )
2182+
2183+ @unittest .skipUnless (hasattr (signal , 'SIGUSR1' ), 'requires SIGUSR1' )
2184+ def test_poll_eintr (self ):
2185+ got_signal = [False ]
2186+ def record (* args ):
2187+ got_signal [0 ] = True
2188+ pid = os .getpid ()
2189+ oldhandler = signal .signal (signal .SIGUSR1 , record )
2190+ try :
2191+ killer = self .Process (target = self ._killer , args = (pid ,))
2192+ killer .start ()
2193+ p = self .Process (target = time .sleep , args = (1 ,))
2194+ p .start ()
2195+ p .join ()
2196+ self .assertTrue (got_signal [0 ])
2197+ self .assertEqual (p .exitcode , 0 )
2198+ killer .join ()
2199+ finally :
2200+ signal .signal (signal .SIGUSR1 , oldhandler )
2201+
21702202#
21712203# Test to verify handle verification, see issue 3321
21722204#
Original file line number Diff line number Diff line change @@ -230,6 +230,8 @@ Core and Builtins
230230Library
231231-------
232232
233+ - Issue #17018: Make Process.join() retry if os.waitpid() fails with EINTR.
234+
233235- Issue #14720: sqlite3: Convert datetime microseconds correctly.
234236 Patch by Lowe Thiderman.
235237
You can’t perform that action at this time.
0 commit comments