diff options
Diffstat (limited to 'network_io')
-rw-r--r-- | network_io/unix/sendrecv.c | 17 | ||||
-rw-r--r-- | network_io/win32/sendrecv.c | 33 |
2 files changed, 31 insertions, 19 deletions
diff --git a/network_io/unix/sendrecv.c b/network_io/unix/sendrecv.c index b9e580b1b..1b965af50 100644 --- a/network_io/unix/sendrecv.c +++ b/network_io/unix/sendrecv.c @@ -196,13 +196,8 @@ apr_status_t apr_socket_sendv(apr_socket_t * sock, const struct iovec *vec, { #ifdef HAVE_WRITEV apr_ssize_t rv; - apr_size_t requested_len = 0; apr_int32_t i; - for (i = 0; i < nvec; i++) { - requested_len += vec[i].iov_len; - } - if (sock->options & APR_INCOMPLETE_WRITE) { sock->options &= ~APR_INCOMPLETE_WRITE; goto do_select; @@ -231,8 +226,16 @@ do_select: *len = 0; return errno; } - if ((sock->timeout > 0) && (rv < requested_len)) { - sock->options |= APR_INCOMPLETE_WRITE; + if (sock->timeout > 0) { + apr_size_t rv_len = rv; + for (i = 0; i < nvec; ++i) { + apr_size_t iov_len = vec[i].iov_len; + if (rv_len < iov_len) { + sock->options |= APR_INCOMPLETE_WRITE; + break; + } + rv_len -= iov_len; + } } (*len) = rv; return APR_SUCCESS; diff --git a/network_io/win32/sendrecv.c b/network_io/win32/sendrecv.c index 20d802042..eb4dd241a 100644 --- a/network_io/win32/sendrecv.c +++ b/network_io/win32/sendrecv.c @@ -34,7 +34,10 @@ * than 8193 bytes. */ #define MAX_SEGMENT_SIZE 65536 + +/* Maximum number of WSABUF allocated for a single apr_socket_sendv() */ #define WSABUF_ON_STACK 50 +#define WSABUF_ON_HEAP 500 APR_DECLARE(apr_status_t) apr_socket_send(apr_socket_t *sock, const char *buf, apr_size_t *len) @@ -91,18 +94,26 @@ APR_DECLARE(apr_status_t) apr_socket_sendv(apr_socket_t *sock, apr_status_t rc = APR_SUCCESS; apr_ssize_t rv; apr_size_t cur_len; - apr_int32_t nvec = 0; - int i, j = 0; + apr_size_t nvec = 0; + apr_size_t n; + int i; DWORD dwBytes = 0; WSABUF *pWsaBuf; for (i = 0; i < in_vec; i++) { cur_len = vec[i].iov_len; - nvec++; + while (cur_len > APR_DWORD_MAX) { + if (nvec >= WSABUF_ON_HEAP) { + break; + } nvec++; cur_len -= APR_DWORD_MAX; } + if (nvec >= WSABUF_ON_HEAP) { + break; + } + nvec++; } pWsaBuf = (nvec <= WSABUF_ON_STACK) ? _alloca(sizeof(WSABUF) * (nvec)) @@ -110,25 +121,23 @@ APR_DECLARE(apr_status_t) apr_socket_sendv(apr_socket_t *sock, if (!pWsaBuf) return APR_ENOMEM; - for (i = 0; i < in_vec; i++) { + for (n = i = 0; n < nvec; i++) { char * base = vec[i].iov_base; cur_len = vec[i].iov_len; - + do { if (cur_len > APR_DWORD_MAX) { - pWsaBuf[j].buf = base; - pWsaBuf[j].len = APR_DWORD_MAX; + pWsaBuf[n].buf = base; + pWsaBuf[n].len = APR_DWORD_MAX; cur_len -= APR_DWORD_MAX; base += APR_DWORD_MAX; } else { - pWsaBuf[j].buf = base; - pWsaBuf[j].len = (DWORD)cur_len; + pWsaBuf[n].buf = base; + pWsaBuf[n].len = (DWORD)cur_len; cur_len = 0; } - j++; - - } while (cur_len > 0); + } while (++n < nvec && cur_len > 0); } rv = WSASend(sock->socketdes, pWsaBuf, nvec, &dwBytes, 0, NULL, NULL); if (rv == SOCKET_ERROR) { |