]> granicus.if.org Git - apache/commitdiff
core: integrate data_in_{in,out}put_filter to ap_filter_{in,out}put_pending().
authorYann Ylavic <ylavic@apache.org>
Wed, 18 Jul 2018 22:36:19 +0000 (22:36 +0000)
committerYann Ylavic <ylavic@apache.org>
Wed, 18 Jul 2018 22:36:19 +0000 (22:36 +0000)
Straightforward for ap_filter_input_pending() since c->data_in_input_filter is
always checked wherever ap_run_input_pending(c) is.

For ap_filter_output_pending(), this allows to set c->data_in_output_filter in
ap_process_request_after_handler() and avoid an useless flush from mpm_event.

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1836239 13f79535-47bb-0310-9956-ffa450edef68

include/httpd.h
modules/http/http_request.c
server/mpm/event/event.c
server/mpm/motorz/motorz.c
server/mpm/simple/simple_io.c
server/util_filter.c

index 22b1a99ebcd6d883ba9d3151cab8b396b5b4b5e9..33c73619916a1da3fba3e2c231087c94a8104078 100644 (file)
@@ -1163,9 +1163,15 @@ struct conn_rec {
     struct apr_bucket_alloc_t *bucket_alloc;
     /** The current state of this connection; may be NULL if not used by MPM */
     conn_state_t *cs;
-    /** Is there data pending in the input filters or connection? */
+    /** Used internally to force ap_filter_input_pending() decision,
+     *  the public interface is ap_filter_should_yield(c->input_filters)
+     *  or ap_filter_input_pending().
+     */
     int data_in_input_filters;
-    /** No longer used, replaced with ap_filter_should_yield() */
+    /** Used internally to force ap_filter_output_pending() decision,
+     *  the public interface is ap_filter_should_yield(c->output_filters)
+     *  or ap_filter_output_pending().
+     */
     int data_in_output_filters;
 
     /** Are there any filters that clogg/buffer the input stream, breaking
index ac8944b86511ff352d6b5906f82d61a2c24eec81..f8022e892afa04ef741e86902e810dd499f69654 100644 (file)
@@ -403,9 +403,20 @@ AP_DECLARE(void) ap_process_request_after_handler(request_rec *r)
     c->data_in_input_filters = (rv == APR_SUCCESS);
     apr_brigade_cleanup(bb);
 
-    if (c->cs)
-        c->cs->state = (c->aborted) ? CONN_STATE_LINGER
-                                    : CONN_STATE_WRITE_COMPLETION;
+    if (c->cs) {
+        if (c->aborted) {
+            c->cs->state = CONN_STATE_LINGER;
+        }
+        else {
+            /* If we have still data in the output filters here it means that
+             * the last (recent) nonblocking write was EAGAIN, so tell the MPM
+             * to not try another useless/stressful one but to go straight to
+             * POLLOUT.
+            */
+            c->data_in_output_filters = ap_filter_should_yield(c->output_filters);
+            c->cs->state = CONN_STATE_WRITE_COMPLETION;
+        }
+    }
     AP_PROCESS_REQUEST_RETURN((uintptr_t)r, r->uri, r->status);
     if (ap_extended_status) {
         ap_time_process_request(c->sbh, STOP_PREQUEST);
@@ -494,7 +505,7 @@ AP_DECLARE(void) ap_process_request(request_rec *r)
 
     ap_process_async_request(r);
 
-    if (!c->data_in_input_filters || ap_run_input_pending(c) != OK) {
+    if (ap_run_input_pending(c) != OK) {
         bb = ap_reuse_brigade_from_pool("ap_pr_bb", c->pool, c->bucket_alloc);
         b = apr_bucket_flush_create(c->bucket_alloc);
         APR_BRIGADE_INSERT_HEAD(bb, b);
index fd60a57d992b3060c18bb1db933e28458c6ecbcb..fcc42a64c95620eb30886a2e908b01ddd7b40df9 100644 (file)
@@ -1187,7 +1187,7 @@ read_request:
                 || listener_may_exit) {
             cs->pub.state = CONN_STATE_LINGER;
         }
-        else if (c->data_in_input_filters || ap_run_input_pending(c) == OK) {
+        else if (ap_run_input_pending(c) == OK) {
             cs->pub.state = CONN_STATE_READ_REQUEST_LINE;
             goto read_request;
         }
index be8f3020e4d3847598fa73d6e8382cb3142c047e..f3a543e79850fb09696ddbe8599267e0bc43b368 100644 (file)
@@ -438,7 +438,7 @@ read_request:
                     || c->aborted) {
                 scon->cs.state = CONN_STATE_LINGER;
             }
-            else if (c->data_in_input_filters || ap_run_input_pending(c) == OK) {
+            else if (ap_run_input_pending(c) == OK) {
                 scon->cs.state = CONN_STATE_READ_REQUEST_LINE;
                 goto read_request;
             }
index 19f5af136b8628713da523e0a46d0e1d4dc64145..ff94aea281d4f8b11dde4ced92574ffa57ebad4e 100644 (file)
@@ -131,7 +131,7 @@ static apr_status_t simple_io_process(simple_conn_t * scon)
                     || c->aborted) {
                 scon->cs.state = CONN_STATE_LINGER;
             }
-            else if (c->data_in_input_filters || ap_run_input_pending(c) == OK) {
+            else if (ap_run_input_pending(c) == OK) {
                 scon->cs.state = CONN_STATE_READ_REQUEST_LINE;
             }
             else {
index 470547c37eb90c4564fa1126ae36be079e886e1e..22af83d8bc04a494b1643db006da355bf8d131ae 100644 (file)
@@ -1008,6 +1008,10 @@ AP_DECLARE_NONSTD(int) ap_filter_output_pending(conn_rec *c)
     apr_bucket_brigade *bb;
     ap_filter_t *f;
 
+    if (c->data_in_output_filters) {
+        return OK;
+    }
+
     if (!c->pending_filters) {
         return DECLINED;
     }
@@ -1044,6 +1048,10 @@ AP_DECLARE_NONSTD(int) ap_filter_input_pending(conn_rec *c)
 {
     ap_filter_t *f;
 
+    if (c->data_in_input_filters) {
+        return OK;
+    }
+
     if (!c->pending_filters) {
         return DECLINED;
     }