From 59af94fa61bf90adbe624508e909b5d6ef6e8464 Mon Sep 17 00:00:00 2001 From: Pablo Galindo Date: Wed, 18 Oct 2017 08:13:09 +0100 Subject: bpo-31806: Use _PyTime_ROUND_TIMEOUT for the timeout argument parsing in more functions (#4026) Fix timeout rounding in time.sleep(), threading.Lock.acquire() and socket.socket.settimeout() to round correctly negative timeouts between -1.0 and 0.0. The functions now block waiting for events as expected. Previously, the call was incorrectly non-blocking. --- Misc/NEWS.d/next/Library/2017-10-17-23-27-03.bpo-31806.TzphdL.rst | 4 ++++ Modules/_threadmodule.c | 4 ++-- Modules/socketmodule.c | 6 +++--- Modules/timemodule.c | 2 +- 4 files changed, 10 insertions(+), 6 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2017-10-17-23-27-03.bpo-31806.TzphdL.rst diff --git a/Misc/NEWS.d/next/Library/2017-10-17-23-27-03.bpo-31806.TzphdL.rst b/Misc/NEWS.d/next/Library/2017-10-17-23-27-03.bpo-31806.TzphdL.rst new file mode 100644 index 0000000..941e77d --- /dev/null +++ b/Misc/NEWS.d/next/Library/2017-10-17-23-27-03.bpo-31806.TzphdL.rst @@ -0,0 +1,4 @@ +Fix timeout rounding in time.sleep(), threading.Lock.acquire() and +socket.socket.settimeout() to round correctly negative timeouts between -1.0 and +0.0. The functions now block waiting for events as expected. Previously, the +call was incorrectly non-blocking. Patch by Pablo Galindo. diff --git a/Modules/_threadmodule.c b/Modules/_threadmodule.c index 2657a1f..72df78f 100644 --- a/Modules/_threadmodule.c +++ b/Modules/_threadmodule.c @@ -104,7 +104,7 @@ lock_acquire_parse_args(PyObject *args, PyObject *kwds, if (timeout_obj && _PyTime_FromSecondsObject(timeout, - timeout_obj, _PyTime_ROUND_CEILING) < 0) + timeout_obj, _PyTime_ROUND_TIMEOUT) < 0) return -1; if (!blocking && *timeout != unset_timeout ) { @@ -122,7 +122,7 @@ lock_acquire_parse_args(PyObject *args, PyObject *kwds, else if (*timeout != unset_timeout) { _PyTime_t microseconds; - microseconds = _PyTime_AsMicroseconds(*timeout, _PyTime_ROUND_CEILING); + microseconds = _PyTime_AsMicroseconds(*timeout, _PyTime_ROUND_TIMEOUT); if (microseconds >= PY_TIMEOUT_MAX) { PyErr_SetString(PyExc_OverflowError, "timeout value is too large"); diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c index 5df9d01..0758f9b 100644 --- a/Modules/socketmodule.c +++ b/Modules/socketmodule.c @@ -2539,7 +2539,7 @@ socket_parse_timeout(_PyTime_t *timeout, PyObject *timeout_obj) } if (_PyTime_FromSecondsObject(timeout, - timeout_obj, _PyTime_ROUND_CEILING) < 0) + timeout_obj, _PyTime_ROUND_TIMEOUT) < 0) return -1; if (*timeout < 0) { @@ -2548,10 +2548,10 @@ socket_parse_timeout(_PyTime_t *timeout, PyObject *timeout_obj) } #ifdef MS_WINDOWS - overflow |= (_PyTime_AsTimeval(*timeout, &tv, _PyTime_ROUND_CEILING) < 0); + overflow |= (_PyTime_AsTimeval(*timeout, &tv, _PyTime_ROUND_TIMEOUT) < 0); #endif #ifndef HAVE_POLL - ms = _PyTime_AsMilliseconds(*timeout, _PyTime_ROUND_CEILING); + ms = _PyTime_AsMilliseconds(*timeout, _PyTime_ROUND_TIMEOUT); overflow |= (ms > INT_MAX); #endif if (overflow) { diff --git a/Modules/timemodule.c b/Modules/timemodule.c index 463f5c5..b5e168f 100644 --- a/Modules/timemodule.c +++ b/Modules/timemodule.c @@ -245,7 +245,7 @@ static PyObject * time_sleep(PyObject *self, PyObject *obj) { _PyTime_t secs; - if (_PyTime_FromSecondsObject(&secs, obj, _PyTime_ROUND_CEILING)) + if (_PyTime_FromSecondsObject(&secs, obj, _PyTime_ROUND_TIMEOUT)) return NULL; if (secs < 0) { PyErr_SetString(PyExc_ValueError, -- cgit v0.12