diff options
-rw-r--r-- | Lib/test/test_poll.py | 2 | ||||
-rw-r--r-- | Misc/ACKS | 1 | ||||
-rw-r--r-- | Misc/NEWS.d/next/Library/2017-09-04-00-22-31.bpo-31334.9WYRfi.rst | 3 | ||||
-rw-r--r-- | Modules/selectmodule.c | 25 |
4 files changed, 21 insertions, 10 deletions
diff --git a/Lib/test/test_poll.py b/Lib/test/test_poll.py index 028dd2d..d593495 100644 --- a/Lib/test/test_poll.py +++ b/Lib/test/test_poll.py @@ -207,7 +207,7 @@ class PollTests(unittest.TestCase): @unittest.skipUnless(threading, 'Threading required for this test.') @reap_threads def test_poll_blocks_with_negative_ms(self): - for timeout_ms in [None, -1, -1.0, -0.1, -1e-100]: + for timeout_ms in [None, -1000, -1, -1.0, -0.1, -1e-100]: # Create two file descriptors. This will be used to unlock # the blocking call to poll.poll inside the thread r, w = os.pipe() @@ -292,6 +292,7 @@ Brad Clements Robbie Clemons Steve Clift Hervé Coatanhay +Riccardo Coccioli Nick Coghlan Josh Cogliati Dave Cole diff --git a/Misc/NEWS.d/next/Library/2017-09-04-00-22-31.bpo-31334.9WYRfi.rst b/Misc/NEWS.d/next/Library/2017-09-04-00-22-31.bpo-31334.9WYRfi.rst new file mode 100644 index 0000000..1cbfd25 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2017-09-04-00-22-31.bpo-31334.9WYRfi.rst @@ -0,0 +1,3 @@ +Fix ``poll.poll([timeout])`` in the ``select`` module for arbitrary negative +timeouts on all OSes where it can only be a non-negative integer or -1. +Patch by Riccardo Coccioli. diff --git a/Modules/selectmodule.c b/Modules/selectmodule.c index 5305523..0f353fb 100644 --- a/Modules/selectmodule.c +++ b/Modules/selectmodule.c @@ -525,20 +525,14 @@ poll_poll(pollObject *self, PyObject *args) PyObject *result_list = NULL, *timeout_obj = NULL; int poll_result, i, j; PyObject *value = NULL, *num = NULL; - _PyTime_t timeout, ms, deadline; + _PyTime_t timeout = -1, ms = -1, deadline = 0; int async_err = 0; if (!PyArg_ParseTuple(args, "|O:poll", &timeout_obj)) { return NULL; } - /* Check values for timeout */ - if (timeout_obj == NULL || timeout_obj == Py_None) { - timeout = -1; - ms = -1; - deadline = 0; /* initialize to prevent gcc warning */ - } - else { + if (timeout_obj != NULL && timeout_obj != Py_None) { if (_PyTime_FromMillisecondsObject(&timeout, timeout_obj, _PyTime_ROUND_TIMEOUT) < 0) { if (PyErr_ExceptionMatches(PyExc_TypeError)) { @@ -554,7 +548,20 @@ poll_poll(pollObject *self, PyObject *args) return NULL; } - deadline = _PyTime_GetMonotonicClock() + timeout; + if (timeout >= 0) { + deadline = _PyTime_GetMonotonicClock() + timeout; + } + } + + /* On some OSes, typically BSD-based ones, the timeout parameter of the + poll() syscall, when negative, must be exactly INFTIM, where defined, + or -1. See issue 31334. */ + if (ms < 0) { +#ifdef INFTIM + ms = INFTIM; +#else + ms = -1; +#endif } /* Avoid concurrent poll() invocation, issue 8865 */ |