On Mon, Sep 17, 2018 at 3:27 PM Yann Ylavic <ylavic....@gmail.com> wrote:
>
> Otherwise, you need a patch like the one attached (untested)...

Sorry, it did not compile, so here is v2.
With this patch, you could compile httpd with "-D
MAX_BYTES_TO_WRITEV=52000" for instance.
Index: server/core_filters.c
===================================================================
--- server/core_filters.c	(revision 1840698)
+++ server/core_filters.c	(working copy)
@@ -348,6 +348,7 @@ static apr_status_t send_brigade_blocking(apr_sock
 static apr_status_t writev_nonblocking(apr_socket_t *s,
                                        struct iovec *vec, apr_size_t nvec,
                                        apr_bucket_brigade *bb,
+                                       apr_size_t bytes_to_write,
                                        apr_size_t *cumulative_bytes_written,
                                        conn_rec *c);
 
@@ -645,6 +646,9 @@ static void setaside_remaining_output(ap_filter_t
 #define MAX_IOVEC_TO_WRITE APR_MAX_IOVEC_SIZE
 #endif
 #endif
+#ifndef MAX_BYTES_TO_WRITEV
+#define MAX_BYTES_TO_WRITEV 0
+#endif
 
 static apr_status_t send_brigade_nonblocking(apr_socket_t *s,
                                              apr_bucket_brigade *bb,
@@ -654,7 +658,7 @@ static apr_status_t send_brigade_nonblocking(apr_s
     apr_bucket *bucket, *next;
     apr_status_t rv;
     struct iovec vec[MAX_IOVEC_TO_WRITE];
-    apr_size_t nvec = 0;
+    apr_size_t nvec = 0, nbytes = 0;
 
     remove_empty_buckets(bb);
 
@@ -676,11 +680,12 @@ static apr_status_t send_brigade_nonblocking(apr_s
                 (bucket->length >= AP_MIN_SENDFILE_BYTES)) {
                 if (nvec > 0) {
                     (void)apr_socket_opt_set(s, APR_TCP_NOPUSH, 1);
-                    rv = writev_nonblocking(s, vec, nvec, bb, bytes_written, c);
+                    rv = writev_nonblocking(s, vec, nvec, bb, nbytes, bytes_written, c);
                     if (rv != APR_SUCCESS) {
                         (void)apr_socket_opt_set(s, APR_TCP_NOPUSH, 0);
                         return rv;
                     }
+                    nbytes = 0;
                 }
                 rv = sendfile_nonblocking(s, bucket, bytes_written, c);
                 if (nvec > 0) {
@@ -705,10 +710,11 @@ static apr_status_t send_brigade_nonblocking(apr_s
             if (APR_STATUS_IS_EAGAIN(rv)) {
                 /* Read would block; flush any pending data and retry. */
                 if (nvec) {
-                    rv = writev_nonblocking(s, vec, nvec, bb, bytes_written, c);
+                    rv = writev_nonblocking(s, vec, nvec, bb, nbytes, bytes_written, c);
                     if (rv) {
                         return rv;
                     }
+                    nbytes = 0;
                     nvec = 0;
                 }
                 
@@ -717,25 +723,42 @@ static apr_status_t send_brigade_nonblocking(apr_s
             if (rv != APR_SUCCESS) {
                 return rv;
             }
+            if (!length) {
+                /* read may have split the bucket, so recompute next: */
+                next = APR_BUCKET_NEXT(bucket);
+                continue;
+            }
 
-            /* reading may have split the bucket, so recompute next: */
+            nbytes += length;
+#if MAX_BYTES_TO_WRITEV
+            if (nbytes > MAX_BYTES_TO_WRITEV) {
+                length -= nbytes - MAX_BYTES_TO_WRITEV;
+                rv = apr_bucket_split(bucket, length);
+                if (rv != APR_SUCCESS) {
+                    return rv;
+                }
+                nbytes = MAX_BYTES_TO_WRITEV;
+            }
+#endif
+
+            /* above may have split the bucket, so recompute next: */
             next = APR_BUCKET_NEXT(bucket);
             vec[nvec].iov_base = (char *)data;
             vec[nvec].iov_len = length;
             nvec++;
-            if (nvec == MAX_IOVEC_TO_WRITE) {
-                rv = writev_nonblocking(s, vec, nvec, bb, bytes_written, c);
-                nvec = 0;
+            if (nvec == MAX_IOVEC_TO_WRITE || nbytes == MAX_BYTES_TO_WRITEV) {
+                rv = writev_nonblocking(s, vec, nvec, bb, nbytes, bytes_written, c);
                 if (rv != APR_SUCCESS) {
                     return rv;
                 }
-                break;
+                nbytes = 0;
+                nvec = 0;
             }
         }
     }
 
     if (nvec > 0) {
-        rv = writev_nonblocking(s, vec, nvec, bb, bytes_written, c);
+        rv = writev_nonblocking(s, vec, nvec, bb, nbytes, bytes_written, c);
         if (rv != APR_SUCCESS) {
             return rv;
         }
@@ -795,11 +818,12 @@ static apr_status_t send_brigade_blocking(apr_sock
 static apr_status_t writev_nonblocking(apr_socket_t *s,
                                        struct iovec *vec, apr_size_t nvec,
                                        apr_bucket_brigade *bb,
+                                       apr_size_t bytes_to_write,
                                        apr_size_t *cumulative_bytes_written,
                                        conn_rec *c)
 {
     apr_status_t rv = APR_SUCCESS, arv;
-    apr_size_t bytes_written = 0, bytes_to_write = 0;
+    apr_size_t bytes_written = 0;
     apr_size_t i, offset;
     apr_interval_time_t old_timeout;
 
@@ -812,9 +836,6 @@ static apr_status_t writev_nonblocking(apr_socket_
         return arv;
     }
 
-    for (i = 0; i < nvec; i++) {
-        bytes_to_write += vec[i].iov_len;
-    }
     offset = 0;
     while (bytes_written < bytes_to_write) {
         apr_size_t n = 0;
@@ -823,7 +844,7 @@ static apr_status_t writev_nonblocking(apr_socket_
             bytes_written += n;
             for (i = offset; i < nvec; ) {
                 apr_bucket *bucket = APR_BRIGADE_FIRST(bb);
-                if (APR_BUCKET_IS_METADATA(bucket)) {
+                if (APR_BUCKET_IS_METADATA(bucket) || !bucket->length) {
                     apr_bucket_delete(bucket);
                 }
                 else if (n >= vec[i].iov_len) {
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@httpd.apache.org
For additional commands, e-mail: users-h...@httpd.apache.org

Reply via email to