bpo-41710: Add private _PyDeadline_Get() function (GH-28674)

Add a private C API for deadlines: add _PyDeadline_Init() and
_PyDeadline_Get() functions.

* Add _PyTime_Add() and _PyTime_Mul() functions which compute t1+t2
  and t1*t2 and clamp the result on overflow.
* _PyTime_MulDiv() now uses _PyTime_Add() and _PyTime_Mul().
This commit is contained in:
Victor Stinner 2021-10-01 13:29:25 +02:00 committed by GitHub
parent 54957f16a6
commit 833fdf126c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 177 additions and 109 deletions

View file

@ -949,8 +949,9 @@ _ssl__SSLSocket_do_handshake_impl(PySSLSocket *self)
timeout = GET_SOCKET_TIMEOUT(sock);
has_timeout = (timeout > 0);
if (has_timeout)
deadline = _PyTime_GetMonotonicClock() + timeout;
if (has_timeout) {
deadline = _PyDeadline_Init(timeout);
}
/* Actually negotiate SSL connection */
/* XXX If SSL_do_handshake() returns 0, it's also a failure. */
@ -965,7 +966,7 @@ _ssl__SSLSocket_do_handshake_impl(PySSLSocket *self)
goto error;
if (has_timeout)
timeout = deadline - _PyTime_GetMonotonicClock();
timeout = _PyDeadline_Get(deadline);
if (err.ssl == SSL_ERROR_WANT_READ) {
sockstate = PySSL_select(sock, 0, timeout);
@ -2326,8 +2327,9 @@ _ssl__SSLSocket_write_impl(PySSLSocket *self, Py_buffer *b)
timeout = GET_SOCKET_TIMEOUT(sock);
has_timeout = (timeout > 0);
if (has_timeout)
deadline = _PyTime_GetMonotonicClock() + timeout;
if (has_timeout) {
deadline = _PyDeadline_Init(timeout);
}
sockstate = PySSL_select(sock, 1, timeout);
if (sockstate == SOCKET_HAS_TIMED_OUT) {
@ -2354,8 +2356,9 @@ _ssl__SSLSocket_write_impl(PySSLSocket *self, Py_buffer *b)
if (PyErr_CheckSignals())
goto error;
if (has_timeout)
timeout = deadline - _PyTime_GetMonotonicClock();
if (has_timeout) {
timeout = _PyDeadline_Get(deadline);
}
if (err.ssl == SSL_ERROR_WANT_READ) {
sockstate = PySSL_select(sock, 0, timeout);
@ -2494,7 +2497,7 @@ _ssl__SSLSocket_read_impl(PySSLSocket *self, Py_ssize_t len,
timeout = GET_SOCKET_TIMEOUT(sock);
has_timeout = (timeout > 0);
if (has_timeout)
deadline = _PyTime_GetMonotonicClock() + timeout;
deadline = _PyDeadline_Init(timeout);
do {
PySSL_BEGIN_ALLOW_THREADS
@ -2506,8 +2509,9 @@ _ssl__SSLSocket_read_impl(PySSLSocket *self, Py_ssize_t len,
if (PyErr_CheckSignals())
goto error;
if (has_timeout)
timeout = deadline - _PyTime_GetMonotonicClock();
if (has_timeout) {
timeout = _PyDeadline_Get(deadline);
}
if (err.ssl == SSL_ERROR_WANT_READ) {
sockstate = PySSL_select(sock, 0, timeout);
@ -2592,8 +2596,9 @@ _ssl__SSLSocket_shutdown_impl(PySSLSocket *self)
timeout = GET_SOCKET_TIMEOUT(sock);
has_timeout = (timeout > 0);
if (has_timeout)
deadline = _PyTime_GetMonotonicClock() + timeout;
if (has_timeout) {
deadline = _PyDeadline_Init(timeout);
}
while (1) {
PySSL_BEGIN_ALLOW_THREADS
@ -2626,8 +2631,9 @@ _ssl__SSLSocket_shutdown_impl(PySSLSocket *self)
continue;
}
if (has_timeout)
timeout = deadline - _PyTime_GetMonotonicClock();
if (has_timeout) {
timeout = _PyDeadline_Get(deadline);
}
/* Possibly retry shutdown until timeout or failure */
if (err.ssl == SSL_ERROR_WANT_READ)