]> granicus.if.org Git - apache/commitdiff
Merge r1802040, r1807876, r1808014, r1805490, r1823886 from trunk:
authorYann Ylavic <ylavic@apache.org>
Sat, 3 Mar 2018 12:18:37 +0000 (12:18 +0000)
committerYann Ylavic <ylavic@apache.org>
Sat, 3 Mar 2018 12:18:37 +0000 (12:18 +0000)
mod_proxy_fcgi: Add the support for mod_proxy's
                flushpackets and flushwait params

This change was requested on the development mailing
list in order to fill another gap between mod_fcgi
and mod_proxy_fcgi, namely the -flush funtionality.

The more evolved core trunk code would not need this
feature becuse of the non-blocking writes, but it
is be needed in 2.4.x.

mod_proxy_fcgi: limit the flush buckets inserted when flushpackets=on|auto

This commit is a follow up of r1802040 based on Jacob's
feedback, namely inserting the FLUSH buckets only when
really needed and useful, not always.

mod_proxy_fcgi: follow up to r1807876.
Fix mixed declarations and code [-Wdeclaration-after-statement].

Fix a compilation warning introduced by r1802040.
mod_proxy_fcgi.c:893:19: warning: ‘flushpoll’ may be used uninitialized in this function [-Wmaybe-uninitialized]

This warning is a false positive.

mod_proxy_fcgi: prioritize the check for mayflush when using flushpackets

The mayflush variable should be checked before the rest
to avoid polling when not needed.

Suggested by Yann Ylavic on the dev@ mailing list.

Submitted by: elukey, ylavic, jailletc36, elukey
Reviewed by: elukey, jim, ylavic

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1825765 13f79535-47bb-0310-9956-ffa450edef68

CHANGES
docs/manual/mod/mod_proxy.xml
modules/proxy/mod_proxy_fcgi.c

diff --git a/CHANGES b/CHANGES
index 3ab0b273763053e3f87b81fd2616fd794bd2f323..99887ea3fd204ce52e1fc2bbb9bd7ec3f194d809 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,6 +1,9 @@
                                                          -*- coding: utf-8 -*-
 Changes with Apache 2.4.31
 
+  *) mod_proxy_fcgi: Add the support for mod_proxy's flushpackets and flushwait
+     parameters. [Luca Toscano, Ruediger Pluem, Yann Ylavic]
+
   *) mod_ldap: Avoid possible crashes, hangs, and busy loops due to
      improper merging of the cache lock in vhost config.
      PR 43164 [Eric Covener]
index 4bd5146986bce1912c84bd8e105dd65693c9e5c6..44a5f66bf2ee9de7fa57f40fcad673822643f94d 100644 (file)
@@ -1082,7 +1082,7 @@ ProxyPass "/mirror/foo" "http://backend.example.com"
         only when needed; 'on' means after each chunk is sent; and
         'auto' means poll/wait for a period of time and flush if
         no input has been received for 'flushwait' milliseconds.
-        Currently, this is in effect only for AJP.
+        Currently, this is in effect only for mod_proxy_ajp and mod_proxy_fcgi.
     </td></tr>
     <tr><td>flushwait</td>
         <td>10</td>
index 41292e8726756d94fe4974b1f4abe66e67a59f87..2e97408f3f7bba3a0913747d6918901699524791 100644 (file)
@@ -532,6 +532,8 @@ static apr_status_t dispatch(proxy_conn_rec *conn, proxy_dir_conf *conf,
     ap_fcgi_header header;
     unsigned char farray[AP_FCGI_HEADER_LEN];
     apr_pollfd_t pfd;
+    apr_pollfd_t *flushpoll = NULL;
+    apr_int32_t flushpoll_fd;
     int header_state = HDR_STATE_READING_HEADERS;
     char stack_iobuf[AP_IOBUFSIZE];
     apr_size_t iobuf_size = AP_IOBUFSIZE;
@@ -548,6 +550,13 @@ static apr_status_t dispatch(proxy_conn_rec *conn, proxy_dir_conf *conf,
     pfd.p = r->pool;
     pfd.reqevents = APR_POLLIN | APR_POLLOUT;
 
+    if (conn->worker->s->flush_packets == flush_auto) {
+        flushpoll = apr_pcalloc(r->pool, sizeof(apr_pollfd_t));
+        flushpoll->reqevents = APR_POLLIN;
+        flushpoll->desc_type = APR_POLL_SOCKET;
+        flushpoll->desc.s = conn->sock;
+    }
+
     ib = apr_brigade_create(r->pool, c->bucket_alloc);
     ob = apr_brigade_create(r->pool, c->bucket_alloc);
 
@@ -658,6 +667,7 @@ static apr_status_t dispatch(proxy_conn_rec *conn, proxy_dir_conf *conf,
             apr_bucket *b;
             unsigned char plen;
             unsigned char type, version;
+            int mayflush = 0;
 
             /* First, we grab the header... */
             rv = get_data_full(conn, (char *) farray, AP_FCGI_HEADER_LEN);
@@ -786,6 +796,7 @@ recv_again:
                                     *err = "passing brigade to output filters";
                                     break;
                                 }
+                                mayflush = 1;
                             }
                             apr_brigade_cleanup(ob);
 
@@ -812,6 +823,7 @@ recv_again:
                                 *err = "passing brigade to output filters";
                                 break;
                             }
+                            mayflush = 1;
                         }
                         apr_brigade_cleanup(ob);
                     }
@@ -876,6 +888,20 @@ recv_again:
                     break;
                 }
             }
+
+            if (mayflush && ((conn->worker->s->flush_packets == flush_on) ||
+                             ((conn->worker->s->flush_packets == flush_auto) && 
+                              (apr_poll(flushpoll, 1, &flushpoll_fd,
+                               conn->worker->s->flush_wait) == APR_TIMEUP)))) {
+                apr_bucket* flush_b = apr_bucket_flush_create(r->connection->bucket_alloc);
+                APR_BRIGADE_INSERT_TAIL(ob, flush_b);
+                rv = ap_pass_brigade(r->output_filters, ob);
+                if (rv != APR_SUCCESS) {
+                    *err = "passing headers brigade to output filters";
+                    break;
+                }
+                mayflush = 0;
+            }
         }
     }