mirror of
https://github.com/python/cpython.git
synced 2025-09-29 11:45:57 +00:00
[3.6] bpo-31334: Fix timeout in select.poll.poll() (GH-3277) (#4033)
Always pass -1, or INFTIM where defined, to the poll() system call when
a negative timeout is passed to the poll.poll([timeout]) method in the
select module. Various OSes throw an error with arbitrary negative
values.
(cherry picked from commit 6cfa927ceb
)
This commit is contained in:
parent
be4e9cc769
commit
97abcabc19
4 changed files with 21 additions and 10 deletions
|
@ -211,7 +211,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()
|
||||
|
|
|
@ -290,6 +290,7 @@ Brad Clements
|
|||
Robbie Clemons
|
||||
Steve Clift
|
||||
Hervé Coatanhay
|
||||
Riccardo Coccioli
|
||||
Nick Coghlan
|
||||
Josh Cogliati
|
||||
Dave Cole
|
||||
|
|
|
@ -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.
|
|
@ -528,20 +528,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)) {
|
||||
|
@ -557,7 +551,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 */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue