Issue #23834: Modify socket.sendall() to reuse sock_call() with

sock_send_impl()
This commit is contained in:
Victor Stinner 2015-04-01 22:53:26 +02:00
parent 31bf2d5073
commit 02f32ab47e
1 changed files with 21 additions and 29 deletions

View File

@ -3501,10 +3501,10 @@ static PyObject *
sock_sendall(PySocketSockObject *s, PyObject *args) sock_sendall(PySocketSockObject *s, PyObject *args)
{ {
char *buf; char *buf;
Py_ssize_t len, n = -1; Py_ssize_t len, n;
int async_err = 0; int flags = 0;
int flags = 0, timeout;
Py_buffer pbuf; Py_buffer pbuf;
struct sock_send ctx;
if (!PyArg_ParseTuple(args, "y*|i:sendall", &pbuf, &flags)) if (!PyArg_ParseTuple(args, "y*|i:sendall", &pbuf, &flags))
return NULL; return NULL;
@ -3517,38 +3517,30 @@ sock_sendall(PySocketSockObject *s, PyObject *args)
} }
do { do {
timeout = internal_select(s, 1, s->sock_timeout); ctx.buf = buf;
ctx.len = len;
n = -1; ctx.flags = flags;
if (!timeout) { if (sock_call(s, 1, sock_send_impl, &ctx) < 0) {
Py_BEGIN_ALLOW_THREADS
#ifdef MS_WINDOWS
if (len > INT_MAX)
len = INT_MAX;
n = send(s->sock_fd, buf, (int)len, flags);
#else
n = send(s->sock_fd, buf, len, flags);
#endif
Py_END_ALLOW_THREADS
}
if (timeout == 1) {
PyBuffer_Release(&pbuf); PyBuffer_Release(&pbuf);
PyErr_SetString(socket_timeout, "timed out");
return NULL; return NULL;
} }
if (n >= 0) { n = ctx.result;
buf += n; assert(n >= 0);
len -= n;
buf += n;
len -= n;
/* We must run our signal handlers before looping again.
send() can return a successful partial write when it is
interrupted, so we can't restrict ourselves to EINTR. */
if (PyErr_CheckSignals()) {
PyBuffer_Release(&pbuf);
return NULL;
} }
} while (len > 0 && (n >= 0 || errno == EINTR) && } while (len > 0);
!(async_err = PyErr_CheckSignals()));
PyBuffer_Release(&pbuf); PyBuffer_Release(&pbuf);
if (n < 0 || async_err) Py_RETURN_NONE;
return (!async_err) ? s->errorhandler() : NULL;
Py_INCREF(Py_None);
return Py_None;
} }
PyDoc_STRVAR(sendall_doc, PyDoc_STRVAR(sendall_doc,