mirror of
https://github.com/python/cpython.git
synced 2025-08-04 08:59:19 +00:00
Fix non-blocking connect() for Windows. Refactored the code
that retries the connect() call in timeout mode so it can be shared between connect() and connect_ex(), and needs only a single #ifdef. The test for this was doing funky stuff I don't approve of, so I removed it in favor of a simpler test. This allowed me to implement a simpler, "purer" form of the timeout retry code. Hopefully that's enough (if you want to be fancy, use non-blocking mode and decode the errors yourself, like before).
This commit is contained in:
parent
129b17d538
commit
7b8bac106a
2 changed files with 42 additions and 39 deletions
|
@ -1270,6 +1270,43 @@ static char close_doc[] =
|
|||
\n\
|
||||
Close the socket. It cannot be used after this call.";
|
||||
|
||||
static int
|
||||
internal_connect(PySocketSockObject *s, struct sockaddr *addr, int addrlen)
|
||||
{
|
||||
int res;
|
||||
|
||||
res = connect(s->sock_fd, addr, addrlen);
|
||||
|
||||
#ifdef MS_WINDOWS
|
||||
|
||||
if (s->sock_timeout > 0.0) {
|
||||
if (res < 0 && WSAGetLastError() == WSAEWOULDBLOCK) {
|
||||
internal_select(s, 1);
|
||||
res = connect(s->sock_fd, addr, addrlen);
|
||||
if (res < 0 && WSAGetLastError() == WSAEISCONN)
|
||||
res = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (res < 0)
|
||||
res = WSAGetLastError();
|
||||
|
||||
#else
|
||||
|
||||
if (s->sock_timeout > 0.0) {
|
||||
if (res < 0 && errno == EINPROGRESS) {
|
||||
internal_select(s, 1);
|
||||
res = connect(s->sock_fd, addr, addrlen);
|
||||
}
|
||||
}
|
||||
|
||||
if (res < 0)
|
||||
res = errno;
|
||||
|
||||
#endif
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/* s.connect(sockaddr) method */
|
||||
|
||||
|
@ -1284,18 +1321,10 @@ sock_connect(PySocketSockObject *s, PyObject *addro)
|
|||
return NULL;
|
||||
|
||||
Py_BEGIN_ALLOW_THREADS
|
||||
if (s->sock_timeout > 0.0) {
|
||||
res = connect(s->sock_fd, addr, addrlen);
|
||||
if (res == EINPROGRESS) {
|
||||
internal_select(s, 1);
|
||||
res = connect(s->sock_fd, addr, addrlen);
|
||||
}
|
||||
}
|
||||
else
|
||||
res = connect(s->sock_fd, addr, addrlen);
|
||||
res = internal_connect(s, addr, addrlen);
|
||||
Py_END_ALLOW_THREADS
|
||||
|
||||
if (res < 0)
|
||||
if (res != 0)
|
||||
return s->errorhandler();
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
|
@ -1321,25 +1350,9 @@ sock_connect_ex(PySocketSockObject *s, PyObject *addro)
|
|||
return NULL;
|
||||
|
||||
Py_BEGIN_ALLOW_THREADS
|
||||
if (s->sock_timeout > 0.0) {
|
||||
res = connect(s->sock_fd, addr, addrlen);
|
||||
if (res == EINPROGRESS) {
|
||||
internal_select(s, 1);
|
||||
res = connect(s->sock_fd, addr, addrlen);
|
||||
}
|
||||
}
|
||||
else
|
||||
res = connect(s->sock_fd, addr, addrlen);
|
||||
res = internal_connect(s, addr, addrlen);
|
||||
Py_END_ALLOW_THREADS
|
||||
|
||||
if (res != 0) {
|
||||
#ifdef MS_WINDOWS
|
||||
res = WSAGetLastError();
|
||||
#else
|
||||
res = errno;
|
||||
#endif
|
||||
}
|
||||
|
||||
return PyInt_FromLong((long) res);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue