[Python-checkins] cpython (merge 3.2 -> 3.3): Merge

richard.oudkerk python-checkins at python.org
Tue Feb 26 14:13:14 CET 2013


http://hg.python.org/cpython/rev/c29e588fdd57
changeset:   82397:c29e588fdd57
branch:      3.3
parent:      82393:8928205f57f6
parent:      82396:5fae31006724
user:        Richard Oudkerk <shibturn at gmail.com>
date:        Tue Feb 26 13:00:15 2013 +0000
summary:
  Merge

files:
  Lib/multiprocessing/forking.py   |  18 +++++++---
  Lib/test/test_multiprocessing.py |  32 ++++++++++++++++++++
  Misc/NEWS                        |   2 +
  3 files changed, 46 insertions(+), 6 deletions(-)


diff --git a/Lib/multiprocessing/forking.py b/Lib/multiprocessing/forking.py
--- a/Lib/multiprocessing/forking.py
+++ b/Lib/multiprocessing/forking.py
@@ -10,6 +10,7 @@
 import os
 import sys
 import signal
+import errno
 
 from multiprocessing import util, process
 
@@ -109,12 +110,17 @@
 
         def poll(self, flag=os.WNOHANG):
             if self.returncode is None:
-                try:
-                    pid, sts = os.waitpid(self.pid, flag)
-                except os.error:
-                    # Child process not yet created. See #1731717
-                    # e.errno == errno.ECHILD == 10
-                    return None
+                while True:
+                    try:
+                        pid, sts = os.waitpid(self.pid, flag)
+                    except os.error 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)
diff --git a/Lib/test/test_multiprocessing.py b/Lib/test/test_multiprocessing.py
--- a/Lib/test/test_multiprocessing.py
+++ b/Lib/test/test_multiprocessing.py
@@ -2894,6 +2894,38 @@
 #         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
 #
 
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -191,6 +191,8 @@
 Library
 -------
 
+- Issue #17018: Make Process.join() retry if os.waitpid() fails with EINTR.
+
 - Issue #14720: sqlite3: Convert datetime microseconds correctly.
   Patch by Lowe Thiderman.
 

-- 
Repository URL: http://hg.python.org/cpython


More information about the Python-checkins mailing list