mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 21:51:50 +00:00 
			
		
		
		
	Issue #17018: Make Process.join() retry if os.waitpid() fails with EINTR.
This commit is contained in:
		
							parent
							
								
									8fd366978d
								
							
						
					
					
						commit
						7aaa1ef858
					
				
					 3 changed files with 46 additions and 6 deletions
				
			
		|  | @ -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 | ||||||
| 
 | 
 | ||||||
|  | @ -128,12 +129,17 @@ def __init__(self, process_obj): | ||||||
| 
 | 
 | ||||||
|         def poll(self, flag=os.WNOHANG): |         def poll(self, flag=os.WNOHANG): | ||||||
|             if self.returncode is None: |             if self.returncode is None: | ||||||
|  |                 while True: | ||||||
|                     try: |                     try: | ||||||
|                         pid, sts = os.waitpid(self.pid, flag) |                         pid, sts = os.waitpid(self.pid, flag) | ||||||
|                 except os.error: |                     except os.error as e: | ||||||
|  |                         if e.errno == errno.EINTR: | ||||||
|  |                             continue | ||||||
|                         # Child process not yet created. See #1731717 |                         # Child process not yet created. See #1731717 | ||||||
|                         # e.errno == errno.ECHILD == 10 |                         # e.errno == errno.ECHILD == 10 | ||||||
|                         return None |                         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) | ||||||
|  |  | ||||||
|  | @ -2167,6 +2167,38 @@ def test_level(self): | ||||||
| #         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 | ||||||
| # | # | ||||||
|  |  | ||||||
|  | @ -230,6 +230,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…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Richard Oudkerk
						Richard Oudkerk