From ad1d5f908a51e1c6fd487e31d6f6aab98bae5c00 Mon Sep 17 00:00:00 2001 From: Richard Oudkerk Date: Tue, 15 Jan 2013 01:01:01 +0000 Subject: [PATCH] Issue #10527: Use poll() instead of select() for multiprocessing pipes --- Misc/NEWS | 2 ++ Modules/_multiprocessing/socket_connection.c | 33 ++++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/Misc/NEWS b/Misc/NEWS index 4e892b2463d..150f7fc1feb 100644 --- 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. diff --git a/Modules/_multiprocessing/socket_connection.c b/Modules/_multiprocessing/socket_connection.c index 1169c0a9237..66bc3777924 100644 --- a/Modules/_multiprocessing/socket_connection.c +++ b/Modules/_multiprocessing/socket_connection.c @@ -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 } /*