summaryrefslogtreecommitdiffstats
path: root/Modules
diff options
context:
space:
mode:
authorVictor Stinner <vstinner@python.org>2021-09-30 00:11:41 (GMT)
committerGitHub <noreply@github.com>2021-09-30 00:11:41 (GMT)
commit09796f2f142fdb1214f34a3ca917959ecb32a88b (patch)
tree28ec5f6d88dbaaff416418964ce430221b7cacd0 /Modules
parent8d3e7eff0936926554db6162c992af5829dc8160 (diff)
downloadcpython-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.c2
-rw-r--r--Modules/_testcapimodule.c45
-rw-r--r--Modules/selectmodule.c2
-rw-r--r--Modules/socketmodule.c2
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