[Python-checkins] cpython (merge 3.2 -> 3.3): Fix issue 10527: make multiprocessing use poll() instead of select() if

giampaolo.rodola python-checkins at python.org
Mon Dec 31 17:40:04 CET 2012


http://hg.python.org/cpython/rev/d89891f3f769
changeset:   81173:d89891f3f769
branch:      3.3
parent:      81170:459a23083b66
parent:      81172:5530251d9cac
user:        Giampaolo Rodola' <g.rodola at gmail.com>
date:        Mon Dec 31 17:38:17 2012 +0100
summary:
  Fix issue 10527: make multiprocessing use poll() instead of select() if available.

files:
  Lib/multiprocessing/connection.py |  21 +++++++++++++++++++
  Lib/test/test_multiprocessing.py  |   6 +++-
  Misc/NEWS                         |   2 +
  3 files changed, 27 insertions(+), 2 deletions(-)


diff --git a/Lib/multiprocessing/connection.py b/Lib/multiprocessing/connection.py
--- a/Lib/multiprocessing/connection.py
+++ b/Lib/multiprocessing/connection.py
@@ -509,6 +509,27 @@
         return c1, c2
 
 else:
+    if hasattr(select, 'poll'):
+        def _poll(fds, timeout):
+            if timeout is not None:
+                timeout = int(timeout) * 1000  # timeout is in milliseconds
+            fd_map = {}
+            pollster = select.poll()
+            for fd in fds:
+                pollster.register(fd, select.POLLIN)
+                if hasattr(fd, 'fileno'):
+                    fd_map[fd.fileno()] = fd
+                else:
+                    fd_map[fd] = fd
+            ls = []
+            for fd, event in pollster.poll(timeout):
+                if event & select.POLLNVAL:
+                    raise ValueError('invalid file descriptor %i' % fd)
+                ls.append(fd_map[fd])
+            return ls
+    else:
+        def _poll(fds, timeout):
+            return select.select(fds, [], [], timeout)[0]
 
     def Pipe(duplex=True):
         '''
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
@@ -2127,6 +2127,7 @@
         self.assertTimingAlmostEqual(poll.elapsed, TIMEOUT1)
 
         conn.send(None)
+        time.sleep(.1)
 
         self.assertEqual(poll(TIMEOUT1), True)
         self.assertTimingAlmostEqual(poll.elapsed, 0)
@@ -3232,6 +3233,7 @@
         from multiprocessing.connection import wait
 
         expected = 3
+        sorted_ = lambda l: sorted(l, key=lambda x: isinstance(x, int))
         sem = multiprocessing.Semaphore(0)
         a, b = multiprocessing.Pipe()
         p = multiprocessing.Process(target=self.signal_and_sleep,
@@ -3255,7 +3257,7 @@
         res = wait([a, p.sentinel, b], 20)
         delta = time.time() - start
 
-        self.assertEqual(res, [p.sentinel, b])
+        self.assertEqual(sorted_(res), sorted_([p.sentinel, b]))
         self.assertLess(delta, 0.4)
 
         b.send(None)
@@ -3264,7 +3266,7 @@
         res = wait([a, p.sentinel, b], 20)
         delta = time.time() - start
 
-        self.assertEqual(res, [a, p.sentinel, b])
+        self.assertEqual(sorted_(res), sorted_([a, p.sentinel, b]))
         self.assertLess(delta, 0.4)
 
         p.terminate()
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -124,6 +124,8 @@
 Library
 -------
 
+- Issue 10527: make multiprocessing use poll() instead of select() if available.
+
 - Issue #16688: Fix backreferences did make case-insensitive regex fail on
   non-ASCII strings. Patch by Matthew Barnett.
 

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


More information about the Python-checkins mailing list