]> granicus.if.org Git - python/commitdiff
Issue #10527: Use poll() instead of select() for multiprocessing pipes
authorRichard Oudkerk <shibturn@gmail.com>
Tue, 15 Jan 2013 01:01:01 +0000 (01:01 +0000)
committerRichard Oudkerk <shibturn@gmail.com>
Tue, 15 Jan 2013 01:01:01 +0000 (01:01 +0000)
Misc/NEWS
Modules/_multiprocessing/socket_connection.c

index 4e892b2463da36d74bc569dda81513fc45708dbb..150f7fc1feb442dd4e48c2e10a1683cec35802b1 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -199,6 +199,8 @@ Core and Builtins
 Library
 -------
 
+- Issue #10527: Use poll() instead of select() for multiprocessing pipes.
+
 - Issue #9720: zipfile now writes correct local headers for files larger than
   4 GiB.
 
index 1169c0a9237a14683da621f16a301c76a031cd92..66bc37779245acd7cd2ac68ce4a048d1a9c7ac44 100644 (file)
@@ -8,6 +8,10 @@
 
 #include "multiprocessing.h"
 
+#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
+#  include "poll.h"
+#endif
+
 #ifdef MS_WINDOWS
 #  define WRITE(h, buffer, length) send((SOCKET)h, buffer, length, 0)
 #  define READ(h, buffer, length) recv((SOCKET)h, buffer, length, 0)
@@ -158,6 +162,34 @@ conn_recv_string(ConnectionObject *conn, char *buffer,
 static int
 conn_poll(ConnectionObject *conn, double timeout, PyThreadState *_save)
 {
+#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
+    int res;
+    struct pollfd p;
+
+    p.fd = (int)conn->handle;
+    p.events = POLLIN | POLLPRI;
+    p.revents = 0;
+
+    if (timeout < 0) {
+        res = poll(&p, 1, -1);
+    } else {
+        res = poll(&p, 1, (int)(timeout * 1000 + 0.5));
+    }
+
+    if (res < 0) {
+        return MP_SOCKET_ERROR;
+    } else if (p.revents & (POLLNVAL|POLLERR)) {
+        Py_BLOCK_THREADS
+        PyErr_SetString(PyExc_IOError, "poll() gave POLLNVAL or POLLERR");
+        Py_UNBLOCK_THREADS
+        return MP_EXCEPTION_HAS_BEEN_SET;
+    } else if (p.revents != 0) {
+        return TRUE;
+    } else {
+        assert(res == 0);
+        return FALSE;
+    }
+#else
     int res;
     fd_set rfds;
 
@@ -193,6 +225,7 @@ conn_poll(ConnectionObject *conn, double timeout, PyThreadState *_save)
         assert(res == 0);
         return FALSE;
     }
+#endif
 }
 
 /*