diff options
author | Victor Stinner <vstinner@python.org> | 2021-09-30 00:11:41 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-09-30 00:11:41 (GMT) |
commit | 09796f2f142fdb1214f34a3ca917959ecb32a88b (patch) | |
tree | 28ec5f6d88dbaaff416418964ce430221b7cacd0 /Modules | |
parent | 8d3e7eff0936926554db6162c992af5829dc8160 (diff) | |
download | cpython-09796f2f142fdb1214f34a3ca917959ecb32a88b.zip cpython-09796f2f142fdb1214f34a3ca917959ecb32a88b.tar.gz cpython-09796f2f142fdb1214f34a3ca917959ecb32a88b.tar.bz2 |
bpo-41710: Add _PyTime_AsTimespec_clamp() (GH-28629)
Add the _PyTime_AsTimespec_clamp() function: similar to
_PyTime_AsTimespec(), but clamp to _PyTime_t min/max and don't raise
an exception.
PyThread_acquire_lock_timed() now uses _PyTime_AsTimespec_clamp() to
remove the Py_UNREACHABLE() code path.
* Add _PyTime_AsTime_t() function.
* Add PY_TIME_T_MIN and PY_TIME_T_MAX constants.
* Replace _PyTime_AsTimeval_noraise() with _PyTime_AsTimeval_clamp().
* Add pytime_divide_round_up() function.
* Fix integer overflow in pytime_divide().
* Add pytime_divmod() function.
Diffstat (limited to 'Modules')
-rw-r--r-- | Modules/_ssl.c | 2 | ||||
-rw-r--r-- | Modules/_testcapimodule.c | 45 | ||||
-rw-r--r-- | Modules/selectmodule.c | 2 | ||||
-rw-r--r-- | Modules/socketmodule.c | 2 |
4 files changed, 47 insertions, 4 deletions
diff --git a/Modules/_ssl.c b/Modules/_ssl.c index 6c63301..411314f 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -2264,7 +2264,7 @@ PySSL_select(PySocketSockObject *s, int writing, _PyTime_t timeout) if (!_PyIsSelectable_fd(s->sock_fd)) return SOCKET_TOO_LARGE_FOR_SELECT; - _PyTime_AsTimeval_noraise(timeout, &tv, _PyTime_ROUND_CEILING); + _PyTime_AsTimeval_clamp(timeout, &tv, _PyTime_ROUND_CEILING); FD_ZERO(&fds); FD_SET(s->sock_fd, &fds); diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index 51323f0..e3eec0c 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -4687,7 +4687,32 @@ test_PyTime_AsTimeval(PyObject *self, PyObject *args) if (seconds == NULL) { return NULL; } - return Py_BuildValue("Nl", seconds, tv.tv_usec); + return Py_BuildValue("Nl", seconds, (long)tv.tv_usec); +} + +static PyObject * +test_PyTime_AsTimeval_clamp(PyObject *self, PyObject *args) +{ + PyObject *obj; + int round; + if (!PyArg_ParseTuple(args, "Oi", &obj, &round)) { + return NULL; + } + if (check_time_rounding(round) < 0) { + return NULL; + } + _PyTime_t t; + if (_PyTime_FromNanosecondsObject(&t, obj) < 0) { + return NULL; + } + struct timeval tv; + _PyTime_AsTimeval_clamp(t, &tv, round); + + PyObject *seconds = PyLong_FromLongLong(tv.tv_sec); + if (seconds == NULL) { + return NULL; + } + return Py_BuildValue("Nl", seconds, (long)tv.tv_usec); } #ifdef HAVE_CLOCK_GETTIME @@ -4708,6 +4733,22 @@ test_PyTime_AsTimespec(PyObject *self, PyObject *args) } return Py_BuildValue("Nl", _PyLong_FromTime_t(ts.tv_sec), ts.tv_nsec); } + +static PyObject * +test_PyTime_AsTimespec_clamp(PyObject *self, PyObject *args) +{ + PyObject *obj; + if (!PyArg_ParseTuple(args, "O", &obj)) { + return NULL; + } + _PyTime_t t; + if (_PyTime_FromNanosecondsObject(&t, obj) < 0) { + return NULL; + } + struct timespec ts; + _PyTime_AsTimespec_clamp(t, &ts); + return Py_BuildValue("Nl", _PyLong_FromTime_t(ts.tv_sec), ts.tv_nsec); +} #endif static PyObject * @@ -5872,8 +5913,10 @@ static PyMethodDef TestMethods[] = { {"PyTime_FromSecondsObject", test_pytime_fromsecondsobject, METH_VARARGS}, {"PyTime_AsSecondsDouble", test_pytime_assecondsdouble, METH_VARARGS}, {"PyTime_AsTimeval", test_PyTime_AsTimeval, METH_VARARGS}, + {"PyTime_AsTimeval_clamp", test_PyTime_AsTimeval_clamp, METH_VARARGS}, #ifdef HAVE_CLOCK_GETTIME {"PyTime_AsTimespec", test_PyTime_AsTimespec, METH_VARARGS}, + {"PyTime_AsTimespec_clamp", test_PyTime_AsTimespec_clamp, METH_VARARGS}, #endif {"PyTime_AsMilliseconds", test_PyTime_AsMilliseconds, METH_VARARGS}, {"PyTime_AsMicroseconds", test_PyTime_AsMicroseconds, METH_VARARGS}, diff --git a/Modules/selectmodule.c b/Modules/selectmodule.c index 3ecd0c3..b71b2c4 100644 --- a/Modules/selectmodule.c +++ b/Modules/selectmodule.c @@ -344,7 +344,7 @@ select_select_impl(PyObject *module, PyObject *rlist, PyObject *wlist, n = 0; break; } - _PyTime_AsTimeval_noraise(timeout, &tv, _PyTime_ROUND_CEILING); + _PyTime_AsTimeval_clamp(timeout, &tv, _PyTime_ROUND_CEILING); /* retry select() with the recomputed timeout */ } } while (1); diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c index 83f05b7..f474869 100644 --- a/Modules/socketmodule.c +++ b/Modules/socketmodule.c @@ -758,7 +758,7 @@ internal_select(PySocketSockObject *s, int writing, _PyTime_t interval, Py_END_ALLOW_THREADS; #else if (interval >= 0) { - _PyTime_AsTimeval_noraise(interval, &tv, _PyTime_ROUND_CEILING); + _PyTime_AsTimeval_clamp(interval, &tv, _PyTime_ROUND_CEILING); tvp = &tv; } else |