Move Py_BEGIN_ALLOW_THREADS/Py_END_ALLOW_THREADS inside internal_select_ex() to prepare a switch to the _PyTime_t type and retry syscall on EINTR.
This commit is contained in:
parent
34dc0f46ae
commit
b7df3144ef
|
@ -601,6 +601,11 @@ internal_select_ex(PySocketSockObject *s, int writing, double interval)
|
||||||
{
|
{
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
|
#ifdef WITH_THREAD
|
||||||
|
/* must be called with the GIL held */
|
||||||
|
assert(PyGILState_Check());
|
||||||
|
#endif
|
||||||
|
|
||||||
/* 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.0)
|
if (s->sock_timeout <= 0.0)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -625,7 +630,10 @@ internal_select_ex(PySocketSockObject *s, int writing, double interval)
|
||||||
|
|
||||||
/* s->sock_timeout is in seconds, timeout in ms */
|
/* s->sock_timeout is in seconds, timeout in ms */
|
||||||
timeout = (int)(interval * 1000 + 0.5);
|
timeout = (int)(interval * 1000 + 0.5);
|
||||||
|
|
||||||
|
Py_BEGIN_ALLOW_THREADS;
|
||||||
n = poll(&pollfd, 1, timeout);
|
n = poll(&pollfd, 1, timeout);
|
||||||
|
Py_END_ALLOW_THREADS;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
{
|
{
|
||||||
|
@ -638,12 +646,14 @@ internal_select_ex(PySocketSockObject *s, int writing, double interval)
|
||||||
FD_SET(s->sock_fd, &fds);
|
FD_SET(s->sock_fd, &fds);
|
||||||
|
|
||||||
/* See if the socket is ready */
|
/* See if the socket is ready */
|
||||||
|
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, NULL, &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, NULL, &tv);
|
||||||
|
Py_END_ALLOW_THREADS;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -667,11 +677,14 @@ internal_select(PySocketSockObject *s, int writing)
|
||||||
Here is an example of use:
|
Here is an example of use:
|
||||||
|
|
||||||
BEGIN_SELECT_LOOP(s)
|
BEGIN_SELECT_LOOP(s)
|
||||||
Py_BEGIN_ALLOW_THREADS
|
|
||||||
timeout = internal_select_ex(s, 0, interval);
|
timeout = internal_select_ex(s, 0, interval);
|
||||||
if (!timeout)
|
|
||||||
|
if (!timeout) {
|
||||||
|
Py_BEGIN_ALLOW_THREADS
|
||||||
outlen = recv(s->sock_fd, cbuf, len, flags);
|
outlen = recv(s->sock_fd, cbuf, len, flags);
|
||||||
Py_END_ALLOW_THREADS
|
Py_END_ALLOW_THREADS
|
||||||
|
}
|
||||||
if (timeout == 1) {
|
if (timeout == 1) {
|
||||||
PyErr_SetString(socket_timeout, "timed out");
|
PyErr_SetString(socket_timeout, "timed out");
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -2066,9 +2079,10 @@ sock_accept(PySocketSockObject *s)
|
||||||
|
|
||||||
BEGIN_SELECT_LOOP(s)
|
BEGIN_SELECT_LOOP(s)
|
||||||
do {
|
do {
|
||||||
Py_BEGIN_ALLOW_THREADS
|
|
||||||
timeout = internal_select_ex(s, 0, interval);
|
timeout = internal_select_ex(s, 0, interval);
|
||||||
|
|
||||||
if (!timeout) {
|
if (!timeout) {
|
||||||
|
Py_BEGIN_ALLOW_THREADS
|
||||||
#if defined(HAVE_ACCEPT4) && defined(SOCK_CLOEXEC)
|
#if defined(HAVE_ACCEPT4) && defined(SOCK_CLOEXEC)
|
||||||
if (accept4_works != 0) {
|
if (accept4_works != 0) {
|
||||||
newfd = accept4(s->sock_fd, SAS2SA(&addrbuf), &addrlen,
|
newfd = accept4(s->sock_fd, SAS2SA(&addrbuf), &addrlen,
|
||||||
|
@ -2083,8 +2097,8 @@ sock_accept(PySocketSockObject *s)
|
||||||
#else
|
#else
|
||||||
newfd = accept(s->sock_fd, SAS2SA(&addrbuf), &addrlen);
|
newfd = accept(s->sock_fd, SAS2SA(&addrbuf), &addrlen);
|
||||||
#endif
|
#endif
|
||||||
|
Py_END_ALLOW_THREADS
|
||||||
}
|
}
|
||||||
Py_END_ALLOW_THREADS
|
|
||||||
} while (newfd < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
|
} while (newfd < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
|
||||||
if (timeout == 1) {
|
if (timeout == 1) {
|
||||||
PyErr_SetString(socket_timeout, "timed out");
|
PyErr_SetString(socket_timeout, "timed out");
|
||||||
|
@ -2395,51 +2409,59 @@ internal_connect(PySocketSockObject *s, struct sockaddr *addr, int addrlen,
|
||||||
{
|
{
|
||||||
int res, timeout;
|
int res, timeout;
|
||||||
|
|
||||||
|
|
||||||
timeout = 0;
|
timeout = 0;
|
||||||
|
|
||||||
|
Py_BEGIN_ALLOW_THREADS
|
||||||
res = connect(s->sock_fd, addr, addrlen);
|
res = connect(s->sock_fd, addr, addrlen);
|
||||||
|
Py_END_ALLOW_THREADS
|
||||||
|
|
||||||
|
|
||||||
#ifdef MS_WINDOWS
|
#ifdef MS_WINDOWS
|
||||||
|
|
||||||
if (s->sock_timeout > 0.0) {
|
if (s->sock_timeout > 0.0
|
||||||
if (res < 0 && WSAGetLastError() == WSAEWOULDBLOCK &&
|
&& res < 0 && WSAGetLastError() == WSAEWOULDBLOCK
|
||||||
IS_SELECTABLE(s)) {
|
&& IS_SELECTABLE(s)) {
|
||||||
/* This is a mess. Best solution: trust select */
|
/* This is a mess. Best solution: trust select */
|
||||||
fd_set fds;
|
fd_set fds;
|
||||||
fd_set fds_exc;
|
fd_set fds_exc;
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
tv.tv_sec = (int)s->sock_timeout;
|
|
||||||
tv.tv_usec = (int)((s->sock_timeout - tv.tv_sec) * 1e6);
|
Py_BEGIN_ALLOW_THREADS
|
||||||
FD_ZERO(&fds);
|
tv.tv_sec = (int)s->sock_timeout;
|
||||||
FD_SET(s->sock_fd, &fds);
|
tv.tv_usec = (int)((s->sock_timeout - tv.tv_sec) * 1e6);
|
||||||
FD_ZERO(&fds_exc);
|
FD_ZERO(&fds);
|
||||||
FD_SET(s->sock_fd, &fds_exc);
|
FD_SET(s->sock_fd, &fds);
|
||||||
res = select(Py_SAFE_DOWNCAST(s->sock_fd+1, SOCKET_T, int),
|
FD_ZERO(&fds_exc);
|
||||||
NULL, &fds, &fds_exc, &tv);
|
FD_SET(s->sock_fd, &fds_exc);
|
||||||
if (res == 0) {
|
res = select(Py_SAFE_DOWNCAST(s->sock_fd+1, SOCKET_T, int),
|
||||||
res = WSAEWOULDBLOCK;
|
NULL, &fds, &fds_exc, &tv);
|
||||||
timeout = 1;
|
Py_END_ALLOW_THREADS
|
||||||
} else if (res > 0) {
|
|
||||||
if (FD_ISSET(s->sock_fd, &fds))
|
if (res == 0) {
|
||||||
/* The socket is in the writable set - this
|
res = WSAEWOULDBLOCK;
|
||||||
means connected */
|
timeout = 1;
|
||||||
res = 0;
|
} else if (res > 0) {
|
||||||
else {
|
if (FD_ISSET(s->sock_fd, &fds))
|
||||||
/* As per MS docs, we need to call getsockopt()
|
/* The socket is in the writable set - this
|
||||||
to get the underlying error */
|
means connected */
|
||||||
int res_size = sizeof res;
|
res = 0;
|
||||||
/* It must be in the exception set */
|
else {
|
||||||
assert(FD_ISSET(s->sock_fd, &fds_exc));
|
/* As per MS docs, we need to call getsockopt()
|
||||||
if (0 == getsockopt(s->sock_fd, SOL_SOCKET, SO_ERROR,
|
to get the underlying error */
|
||||||
(char *)&res, &res_size))
|
int res_size = sizeof res;
|
||||||
/* getsockopt also clears WSAGetLastError,
|
/* It must be in the exception set */
|
||||||
so reset it back. */
|
assert(FD_ISSET(s->sock_fd, &fds_exc));
|
||||||
WSASetLastError(res);
|
if (0 == getsockopt(s->sock_fd, SOL_SOCKET, SO_ERROR,
|
||||||
else
|
(char *)&res, &res_size))
|
||||||
res = WSAGetLastError();
|
/* getsockopt also clears WSAGetLastError,
|
||||||
}
|
so reset it back. */
|
||||||
|
WSASetLastError(res);
|
||||||
|
else
|
||||||
|
res = WSAGetLastError();
|
||||||
}
|
}
|
||||||
/* else if (res < 0) an error occurred */
|
|
||||||
}
|
}
|
||||||
|
/* else if (res < 0) an error occurred */
|
||||||
}
|
}
|
||||||
|
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
|
@ -2447,26 +2469,27 @@ internal_connect(PySocketSockObject *s, struct sockaddr *addr, int addrlen,
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
if (s->sock_timeout > 0.0) {
|
if (s->sock_timeout > 0.0
|
||||||
if (res < 0 && errno == EINPROGRESS && IS_SELECTABLE(s)) {
|
&& res < 0 && errno == EINPROGRESS && IS_SELECTABLE(s)) {
|
||||||
timeout = internal_select(s, 1);
|
|
||||||
if (timeout == 0) {
|
timeout = internal_select(s, 1);
|
||||||
/* Bug #1019808: in case of an EINPROGRESS,
|
|
||||||
use getsockopt(SO_ERROR) to get the real
|
if (timeout == 0) {
|
||||||
error. */
|
/* Bug #1019808: in case of an EINPROGRESS,
|
||||||
socklen_t res_size = sizeof res;
|
use getsockopt(SO_ERROR) to get the real
|
||||||
(void)getsockopt(s->sock_fd, SOL_SOCKET,
|
error. */
|
||||||
SO_ERROR, &res, &res_size);
|
socklen_t res_size = sizeof res;
|
||||||
if (res == EISCONN)
|
(void)getsockopt(s->sock_fd, SOL_SOCKET,
|
||||||
res = 0;
|
SO_ERROR, &res, &res_size);
|
||||||
errno = res;
|
if (res == EISCONN)
|
||||||
}
|
res = 0;
|
||||||
else if (timeout == -1) {
|
errno = res;
|
||||||
res = errno; /* had error */
|
|
||||||
}
|
|
||||||
else
|
|
||||||
res = EWOULDBLOCK; /* timed out */
|
|
||||||
}
|
}
|
||||||
|
else if (timeout == -1) {
|
||||||
|
res = errno; /* had error */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
res = EWOULDBLOCK; /* timed out */
|
||||||
}
|
}
|
||||||
|
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
|
@ -2491,9 +2514,7 @@ sock_connect(PySocketSockObject *s, PyObject *addro)
|
||||||
if (!getsockaddrarg(s, addro, SAS2SA(&addrbuf), &addrlen))
|
if (!getsockaddrarg(s, addro, SAS2SA(&addrbuf), &addrlen))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
Py_BEGIN_ALLOW_THREADS
|
|
||||||
res = internal_connect(s, SAS2SA(&addrbuf), addrlen, &timeout);
|
res = internal_connect(s, SAS2SA(&addrbuf), addrlen, &timeout);
|
||||||
Py_END_ALLOW_THREADS
|
|
||||||
|
|
||||||
if (timeout == 1) {
|
if (timeout == 1) {
|
||||||
PyErr_SetString(socket_timeout, "timed out");
|
PyErr_SetString(socket_timeout, "timed out");
|
||||||
|
@ -2525,9 +2546,7 @@ sock_connect_ex(PySocketSockObject *s, PyObject *addro)
|
||||||
if (!getsockaddrarg(s, addro, SAS2SA(&addrbuf), &addrlen))
|
if (!getsockaddrarg(s, addro, SAS2SA(&addrbuf), &addrlen))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
Py_BEGIN_ALLOW_THREADS
|
|
||||||
res = internal_connect(s, SAS2SA(&addrbuf), addrlen, &timeout);
|
res = internal_connect(s, SAS2SA(&addrbuf), addrlen, &timeout);
|
||||||
Py_END_ALLOW_THREADS
|
|
||||||
|
|
||||||
/* Signals are not errors (though they may raise exceptions). Adapted
|
/* Signals are not errors (though they may raise exceptions). Adapted
|
||||||
from PyErr_SetFromErrnoWithFilenameObject(). */
|
from PyErr_SetFromErrnoWithFilenameObject(). */
|
||||||
|
@ -2679,9 +2698,10 @@ sock_recv_guts(PySocketSockObject *s, char* cbuf, Py_ssize_t len, int flags)
|
||||||
|
|
||||||
BEGIN_SELECT_LOOP(s)
|
BEGIN_SELECT_LOOP(s)
|
||||||
do {
|
do {
|
||||||
Py_BEGIN_ALLOW_THREADS
|
|
||||||
timeout = internal_select_ex(s, 0, interval);
|
timeout = internal_select_ex(s, 0, interval);
|
||||||
|
|
||||||
if (!timeout) {
|
if (!timeout) {
|
||||||
|
Py_BEGIN_ALLOW_THREADS
|
||||||
#ifdef MS_WINDOWS
|
#ifdef MS_WINDOWS
|
||||||
if (len > INT_MAX)
|
if (len > INT_MAX)
|
||||||
len = INT_MAX;
|
len = INT_MAX;
|
||||||
|
@ -2689,8 +2709,8 @@ sock_recv_guts(PySocketSockObject *s, char* cbuf, Py_ssize_t len, int flags)
|
||||||
#else
|
#else
|
||||||
outlen = recv(s->sock_fd, cbuf, len, flags);
|
outlen = recv(s->sock_fd, cbuf, len, flags);
|
||||||
#endif
|
#endif
|
||||||
|
Py_END_ALLOW_THREADS
|
||||||
}
|
}
|
||||||
Py_END_ALLOW_THREADS
|
|
||||||
} while (outlen < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
|
} while (outlen < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
|
||||||
|
|
||||||
if (timeout == 1) {
|
if (timeout == 1) {
|
||||||
|
@ -2853,10 +2873,11 @@ sock_recvfrom_guts(PySocketSockObject *s, char* cbuf, Py_ssize_t len, int flags,
|
||||||
|
|
||||||
BEGIN_SELECT_LOOP(s)
|
BEGIN_SELECT_LOOP(s)
|
||||||
do {
|
do {
|
||||||
Py_BEGIN_ALLOW_THREADS
|
|
||||||
memset(&addrbuf, 0, addrlen);
|
memset(&addrbuf, 0, addrlen);
|
||||||
timeout = internal_select_ex(s, 0, interval);
|
timeout = internal_select_ex(s, 0, interval);
|
||||||
|
|
||||||
if (!timeout) {
|
if (!timeout) {
|
||||||
|
Py_BEGIN_ALLOW_THREADS
|
||||||
#ifdef MS_WINDOWS
|
#ifdef MS_WINDOWS
|
||||||
if (len > INT_MAX)
|
if (len > INT_MAX)
|
||||||
len = INT_MAX;
|
len = INT_MAX;
|
||||||
|
@ -2866,8 +2887,8 @@ sock_recvfrom_guts(PySocketSockObject *s, char* cbuf, Py_ssize_t len, int flags,
|
||||||
n = recvfrom(s->sock_fd, cbuf, len, flags,
|
n = recvfrom(s->sock_fd, cbuf, len, flags,
|
||||||
SAS2SA(&addrbuf), &addrlen);
|
SAS2SA(&addrbuf), &addrlen);
|
||||||
#endif
|
#endif
|
||||||
|
Py_END_ALLOW_THREADS
|
||||||
}
|
}
|
||||||
Py_END_ALLOW_THREADS
|
|
||||||
} while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
|
} while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
|
||||||
|
|
||||||
if (timeout == 1) {
|
if (timeout == 1) {
|
||||||
|
@ -3054,7 +3075,6 @@ sock_recvmsg_guts(PySocketSockObject *s, struct iovec *iov, int iovlen,
|
||||||
|
|
||||||
BEGIN_SELECT_LOOP(s)
|
BEGIN_SELECT_LOOP(s)
|
||||||
do {
|
do {
|
||||||
Py_BEGIN_ALLOW_THREADS;
|
|
||||||
msg.msg_name = SAS2SA(&addrbuf);
|
msg.msg_name = SAS2SA(&addrbuf);
|
||||||
msg.msg_namelen = addrbuflen;
|
msg.msg_namelen = addrbuflen;
|
||||||
msg.msg_iov = iov;
|
msg.msg_iov = iov;
|
||||||
|
@ -3062,13 +3082,17 @@ sock_recvmsg_guts(PySocketSockObject *s, struct iovec *iov, int iovlen,
|
||||||
msg.msg_control = controlbuf;
|
msg.msg_control = controlbuf;
|
||||||
msg.msg_controllen = controllen;
|
msg.msg_controllen = controllen;
|
||||||
timeout = internal_select_ex(s, 0, interval);
|
timeout = internal_select_ex(s, 0, interval);
|
||||||
if (!timeout)
|
|
||||||
bytes_received = recvmsg(s->sock_fd, &msg, flags);
|
|
||||||
Py_END_ALLOW_THREADS;
|
|
||||||
if (timeout == 1) {
|
if (timeout == 1) {
|
||||||
PyErr_SetString(socket_timeout, "timed out");
|
PyErr_SetString(socket_timeout, "timed out");
|
||||||
goto finally;
|
goto finally;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!timeout) {
|
||||||
|
Py_BEGIN_ALLOW_THREADS;
|
||||||
|
bytes_received = recvmsg(s->sock_fd, &msg, flags);
|
||||||
|
Py_END_ALLOW_THREADS;
|
||||||
|
}
|
||||||
} while (bytes_received < 0 && errno == EINTR &&
|
} while (bytes_received < 0 && errno == EINTR &&
|
||||||
!(async_err = PyErr_CheckSignals()));
|
!(async_err = PyErr_CheckSignals()));
|
||||||
END_SELECT_LOOP(s)
|
END_SELECT_LOOP(s)
|
||||||
|
@ -3350,9 +3374,10 @@ sock_send(PySocketSockObject *s, PyObject *args)
|
||||||
|
|
||||||
BEGIN_SELECT_LOOP(s)
|
BEGIN_SELECT_LOOP(s)
|
||||||
do {
|
do {
|
||||||
Py_BEGIN_ALLOW_THREADS
|
|
||||||
timeout = internal_select_ex(s, 1, interval);
|
timeout = internal_select_ex(s, 1, interval);
|
||||||
|
|
||||||
if (!timeout) {
|
if (!timeout) {
|
||||||
|
Py_BEGIN_ALLOW_THREADS
|
||||||
#ifdef MS_WINDOWS
|
#ifdef MS_WINDOWS
|
||||||
if (len > INT_MAX)
|
if (len > INT_MAX)
|
||||||
len = INT_MAX;
|
len = INT_MAX;
|
||||||
|
@ -3360,8 +3385,8 @@ sock_send(PySocketSockObject *s, PyObject *args)
|
||||||
#else
|
#else
|
||||||
n = send(s->sock_fd, buf, len, flags);
|
n = send(s->sock_fd, buf, len, flags);
|
||||||
#endif
|
#endif
|
||||||
|
Py_END_ALLOW_THREADS
|
||||||
}
|
}
|
||||||
Py_END_ALLOW_THREADS
|
|
||||||
} while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
|
} while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
|
||||||
if (timeout == 1) {
|
if (timeout == 1) {
|
||||||
PyBuffer_Release(&pbuf);
|
PyBuffer_Release(&pbuf);
|
||||||
|
@ -3406,10 +3431,11 @@ sock_sendall(PySocketSockObject *s, PyObject *args)
|
||||||
}
|
}
|
||||||
|
|
||||||
do {
|
do {
|
||||||
Py_BEGIN_ALLOW_THREADS
|
|
||||||
timeout = internal_select(s, 1);
|
timeout = internal_select(s, 1);
|
||||||
|
|
||||||
n = -1;
|
n = -1;
|
||||||
if (!timeout) {
|
if (!timeout) {
|
||||||
|
Py_BEGIN_ALLOW_THREADS
|
||||||
#ifdef MS_WINDOWS
|
#ifdef MS_WINDOWS
|
||||||
if (len > INT_MAX)
|
if (len > INT_MAX)
|
||||||
len = INT_MAX;
|
len = INT_MAX;
|
||||||
|
@ -3417,8 +3443,8 @@ sock_sendall(PySocketSockObject *s, PyObject *args)
|
||||||
#else
|
#else
|
||||||
n = send(s->sock_fd, buf, len, flags);
|
n = send(s->sock_fd, buf, len, flags);
|
||||||
#endif
|
#endif
|
||||||
|
Py_END_ALLOW_THREADS
|
||||||
}
|
}
|
||||||
Py_END_ALLOW_THREADS
|
|
||||||
if (timeout == 1) {
|
if (timeout == 1) {
|
||||||
PyBuffer_Release(&pbuf);
|
PyBuffer_Release(&pbuf);
|
||||||
PyErr_SetString(socket_timeout, "timed out");
|
PyErr_SetString(socket_timeout, "timed out");
|
||||||
|
@ -3495,9 +3521,10 @@ sock_sendto(PySocketSockObject *s, PyObject *args)
|
||||||
|
|
||||||
BEGIN_SELECT_LOOP(s)
|
BEGIN_SELECT_LOOP(s)
|
||||||
do {
|
do {
|
||||||
Py_BEGIN_ALLOW_THREADS
|
|
||||||
timeout = internal_select_ex(s, 1, interval);
|
timeout = internal_select_ex(s, 1, interval);
|
||||||
|
|
||||||
if (!timeout) {
|
if (!timeout) {
|
||||||
|
Py_BEGIN_ALLOW_THREADS
|
||||||
#ifdef MS_WINDOWS
|
#ifdef MS_WINDOWS
|
||||||
if (len > INT_MAX)
|
if (len > INT_MAX)
|
||||||
len = INT_MAX;
|
len = INT_MAX;
|
||||||
|
@ -3507,8 +3534,8 @@ sock_sendto(PySocketSockObject *s, PyObject *args)
|
||||||
n = sendto(s->sock_fd, buf, len, flags,
|
n = sendto(s->sock_fd, buf, len, flags,
|
||||||
SAS2SA(&addrbuf), addrlen);
|
SAS2SA(&addrbuf), addrlen);
|
||||||
#endif
|
#endif
|
||||||
|
Py_END_ALLOW_THREADS
|
||||||
}
|
}
|
||||||
Py_END_ALLOW_THREADS
|
|
||||||
} while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
|
} while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
|
||||||
|
|
||||||
if (timeout == 1) {
|
if (timeout == 1) {
|
||||||
|
@ -3710,11 +3737,14 @@ sock_sendmsg(PySocketSockObject *s, PyObject *args)
|
||||||
|
|
||||||
BEGIN_SELECT_LOOP(s)
|
BEGIN_SELECT_LOOP(s)
|
||||||
do {
|
do {
|
||||||
Py_BEGIN_ALLOW_THREADS;
|
|
||||||
timeout = internal_select_ex(s, 1, interval);
|
timeout = internal_select_ex(s, 1, interval);
|
||||||
if (!timeout)
|
|
||||||
|
if (!timeout) {
|
||||||
|
Py_BEGIN_ALLOW_THREADS;
|
||||||
bytes_sent = sendmsg(s->sock_fd, &msg, flags);
|
bytes_sent = sendmsg(s->sock_fd, &msg, flags);
|
||||||
Py_END_ALLOW_THREADS;
|
Py_END_ALLOW_THREADS;
|
||||||
|
}
|
||||||
|
|
||||||
if (timeout == 1) {
|
if (timeout == 1) {
|
||||||
PyErr_SetString(socket_timeout, "timed out");
|
PyErr_SetString(socket_timeout, "timed out");
|
||||||
goto finally;
|
goto finally;
|
||||||
|
|
Loading…
Reference in New Issue