1
0
mirror of https://github.com/apache/httpd.git synced 2025-08-08 15:02:10 +03:00

core: always allocate filters (ap_filter_t) on f->c->pool.

When filters are allocated on f->r->pool, they may be destroyed any time
underneath themselves which makes it hard for them to be passed the EOR and
forward it (*f can't be dereferenced anymore when the EOR is destroyed, thus
before request filters return).

On the util_filter side, it also makes it impossible to flush pending request
filters when they have set aside the EOR, since f->bb can't be accessed after
it's passed to the f->next.

So we always use f->c->pool to allocate filters and pending brigades, and to
avoid leaks with keepalive requests (long living connections handling multiple
requests), filters and brigades are recycled with a cleanup on f->r->pool.

Recycling is done (generically) with a spare data ring (void pointers), and a
filter(s) context struct is associated with the conn_rec to maintain the rings
by connection, that is:

    struct ap_filter_conn_ctx {
        struct ap_filter_ring *pending_input_filters;
        struct ap_filter_ring *pending_output_filters;

        struct ap_filter_spare_ring *spare_containers,
                                    *spare_brigades,
                                    *spare_filters,
                                    *spare_flushes;
        int flushing;
    };

MMN major bumped (again).


git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1839997 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Yann Ylavic
2018-09-03 23:49:46 +00:00
parent ef4b1394d8
commit 0a61dd979a
8 changed files with 177 additions and 47 deletions

View File

@@ -1813,7 +1813,7 @@ static apr_status_t ssl_io_filter_output(ap_filter_t *f,
/* if the core has set aside data, back off and try later */
if (!flush_upto) {
if (ap_filter_should_yield(f)) {
if (ap_filter_should_yield(f->next)) {
break;
}
}
@@ -1869,10 +1869,9 @@ static apr_status_t ssl_io_filter_output(ap_filter_t *f,
}
if (APR_STATUS_IS_EOF(status) || (status == APR_SUCCESS)) {
return ap_filter_setaside_brigade(f, bb);
if (status == APR_SUCCESS) {
status = ap_filter_setaside_brigade(f, bb);
}
return status;
}