Commit e6951c6c authored by Victor Stinner's avatar Victor Stinner

Issue #23618: Refactor internal_select() to prepare socket.connect() for EINTR

parent 391fa713
......@@ -591,19 +591,13 @@ internal_setblocking(PySocketSockObject *s, int block)
return 1;
}
/* Do a select()/poll() on the socket, if necessary (sock_timeout > 0).
The argument writing indicates the direction.
This does not raise an exception; we'll let our caller do that
after they've reacquired the interpreter lock.
Returns 1 on timeout, -1 on error, 0 otherwise. */
static int
internal_select(PySocketSockObject *s, int writing, _PyTime_t interval)
internal_select_impl(PySocketSockObject *s, int writing, _PyTime_t interval)
{
int n;
#ifdef HAVE_POLL
struct pollfd pollfd;
_PyTime_t timeout;
int timeout_int;
_PyTime_t ms;
#else
fd_set fds;
struct timeval tv;
......@@ -633,12 +627,11 @@ internal_select(PySocketSockObject *s, int writing, _PyTime_t interval)
pollfd.events = writing ? POLLOUT : POLLIN;
/* s->sock_timeout is in seconds, timeout in ms */
timeout = _PyTime_AsMilliseconds(interval, _PyTime_ROUND_CEILING);
assert(timeout <= INT_MAX);
timeout_int = (int)timeout;
ms = _PyTime_AsMilliseconds(interval, _PyTime_ROUND_CEILING);
assert(ms <= INT_MAX);
Py_BEGIN_ALLOW_THREADS;
n = poll(&pollfd, 1, timeout_int);
n = poll(&pollfd, 1, (int)ms);
Py_END_ALLOW_THREADS;
#else
_PyTime_AsTimeval_noraise(interval, &tv, _PyTime_ROUND_CEILING);
......@@ -664,6 +657,23 @@ internal_select(PySocketSockObject *s, int writing, _PyTime_t interval)
return 0;
}
/* Do a select()/poll() on the socket, if necessary (sock_timeout > 0).
The argument writing indicates the direction.
This does not raise an exception; we'll let our caller do that
after they've reacquired the interpreter lock.
Returns 1 on timeout, -1 on error, 0 otherwise. */
static int
internal_select(PySocketSockObject *s, int writing, _PyTime_t interval)
{
return internal_select_impl(s, writing, interval);
}
static int
internal_connect_select(PySocketSockObject *s)
{
return internal_select(s, 1, s->sock_timeout);
}
/*
Two macros for automatic retry of select() in case of false positives
(for example, select() could indicate a socket is ready for reading
......@@ -2492,7 +2502,7 @@ internal_connect(PySocketSockObject *s, struct sockaddr *addr, int addrlen,
if (s->sock_timeout > 0
&& res < 0 && errno == EINPROGRESS && IS_SELECTABLE(s)) {
timeout = internal_select(s, 1, s->sock_timeout);
timeout = internal_connect_select(s);
if (timeout == 0) {
/* Bug #1019808: in case of an EINPROGRESS,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment