Issue #23618: internal_connect_select() now waits also for error events

This commit is contained in:
Victor Stinner 2015-03-31 13:56:29 +02:00
parent e6951c6c8a
commit 416f2e66ca
1 changed files with 15 additions and 6 deletions

View File

@ -592,14 +592,15 @@ internal_setblocking(PySocketSockObject *s, int block)
} }
static int static int
internal_select_impl(PySocketSockObject *s, int writing, _PyTime_t interval) internal_select_impl(PySocketSockObject *s, int writing, _PyTime_t interval,
int error)
{ {
int n; int n;
#ifdef HAVE_POLL #ifdef HAVE_POLL
struct pollfd pollfd; struct pollfd pollfd;
_PyTime_t ms; _PyTime_t ms;
#else #else
fd_set fds; fd_set fds, efds;
struct timeval tv; struct timeval tv;
#endif #endif
@ -608,6 +609,9 @@ internal_select_impl(PySocketSockObject *s, int writing, _PyTime_t interval)
assert(PyGILState_Check()); assert(PyGILState_Check());
#endif #endif
/* Error condition is for output only */
assert(!(error && !writing));
/* Nothing to do unless we're in timeout mode (not non-blocking) */ /* Nothing to do unless we're in timeout mode (not non-blocking) */
if (s->sock_timeout <= 0) if (s->sock_timeout <= 0)
return 0; return 0;
@ -625,6 +629,8 @@ internal_select_impl(PySocketSockObject *s, int writing, _PyTime_t interval)
#ifdef HAVE_POLL #ifdef HAVE_POLL
pollfd.fd = s->sock_fd; pollfd.fd = s->sock_fd;
pollfd.events = writing ? POLLOUT : POLLIN; pollfd.events = writing ? POLLOUT : POLLIN;
if (error)
pollfd.events |= POLLERR;
/* s->sock_timeout is in seconds, timeout in ms */ /* s->sock_timeout is in seconds, timeout in ms */
ms = _PyTime_AsMilliseconds(interval, _PyTime_ROUND_CEILING); ms = _PyTime_AsMilliseconds(interval, _PyTime_ROUND_CEILING);
@ -638,15 +644,18 @@ internal_select_impl(PySocketSockObject *s, int writing, _PyTime_t interval)
FD_ZERO(&fds); FD_ZERO(&fds);
FD_SET(s->sock_fd, &fds); FD_SET(s->sock_fd, &fds);
FD_ZERO(&efds);
if (error)
FD_SET(s->sock_fd, &efds);
/* See if the socket is ready */ /* See if the socket is ready */
Py_BEGIN_ALLOW_THREADS; Py_BEGIN_ALLOW_THREADS;
if (writing) if (writing)
n = select(Py_SAFE_DOWNCAST(s->sock_fd+1, SOCKET_T, int), n = select(Py_SAFE_DOWNCAST(s->sock_fd+1, SOCKET_T, int),
NULL, &fds, NULL, &tv); NULL, &fds, &efds, &tv);
else else
n = select(Py_SAFE_DOWNCAST(s->sock_fd+1, SOCKET_T, int), n = select(Py_SAFE_DOWNCAST(s->sock_fd+1, SOCKET_T, int),
&fds, NULL, NULL, &tv); &fds, NULL, &efds, &tv);
Py_END_ALLOW_THREADS; Py_END_ALLOW_THREADS;
#endif #endif
@ -665,13 +674,13 @@ internal_select_impl(PySocketSockObject *s, int writing, _PyTime_t interval)
static int static int
internal_select(PySocketSockObject *s, int writing, _PyTime_t interval) internal_select(PySocketSockObject *s, int writing, _PyTime_t interval)
{ {
return internal_select_impl(s, writing, interval); return internal_select_impl(s, writing, interval, 0);
} }
static int static int
internal_connect_select(PySocketSockObject *s) internal_connect_select(PySocketSockObject *s)
{ {
return internal_select(s, 1, s->sock_timeout); return internal_select(s, 1, s->sock_timeout, 1);
} }
/* /*