From: Yann Ylavic Date: Thu, 19 Aug 2021 16:04:45 +0000 (+0000) Subject: core: core output filter to cleanup empty/meta buckets following data, ASAP. X-Git-Tag: 2.5.0-alpha2-ci-test-only~865 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=2fc2a9ca96904b34adc49028f072a25a909eebe4;p=thirdparty%2Fapache%2Fhttpd.git core: core output filter to cleanup empty/meta buckets following data, ASAP. * server/core_filters.c (delete_meta_bucket): Add delete_meta_bucket() helper to set r->flush on EOR. * server/core_filters.c (send_brigade_nonblocking): Use delete_meta_bucket() to factorize code. * server/core_filters.c (writev_nonblocking): Use delete_meta_bucket() to factorize code. Cleanup trailing empty/meta buckets immediately after data have been sent to get more accurate EOR timestamp (otherwise trailing buckets could be deleted only after the next data or with a final send_brigade_nonblocking() call in the output filter). git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1892452 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/server/core_filters.c b/server/core_filters.c index 0325dea452d..5868539ec87 100644 --- a/server/core_filters.c +++ b/server/core_filters.c @@ -480,6 +480,19 @@ static APR_INLINE int can_sendfile_bucket(apr_bucket *b) } #endif +static void delete_meta_bucket(apr_bucket *bucket) +{ + if (AP_BUCKET_IS_EOR(bucket)) { + /* Mark the request as flushed since all its + * buckets (preceding this EOR) have been sent. + */ + request_rec *r = ap_bucket_eor_request(bucket); + ap_assert(r != NULL); + r->flushed = 1; + } + apr_bucket_delete(bucket); +} + static apr_status_t send_brigade_nonblocking(apr_socket_t *s, apr_bucket_brigade *bb, core_output_ctx_t *ctx, @@ -551,15 +564,7 @@ static apr_status_t send_brigade_nonblocking(apr_socket_t *s, * brigade in order. */ if (!nvec) { - if (AP_BUCKET_IS_EOR(bucket)) { - /* Mark the request as flushed since all its - * buckets (preceding this EOR) have been sent. - */ - request_rec *r = ap_bucket_eor_request(bucket); - ap_assert(r != NULL); - r->flushed = 1; - } - apr_bucket_delete(bucket); + delete_meta_bucket(bucket); } continue; } @@ -643,15 +648,7 @@ static apr_status_t writev_nonblocking(apr_socket_t *s, for (i = offset; i < nvec; ) { apr_bucket *bucket = APR_BRIGADE_FIRST(bb); if (!bucket->length) { - if (AP_BUCKET_IS_EOR(bucket)) { - /* Mark the request as flushed since all its - * buckets (preceding this EOR) have been sent. - */ - request_rec *r = ap_bucket_eor_request(bucket); - ap_assert(r != NULL); - r->flushed = 1; - } - apr_bucket_delete(bucket); + delete_meta_bucket(bucket); } else if (n >= vec[i].iov_len) { apr_bucket_delete(bucket); @@ -668,6 +665,16 @@ static apr_status_t writev_nonblocking(apr_socket_t *s, break; } } + if (i == nvec) { + /* Cleanup empty/meta buckets following sent data */ + while (!APR_BRIGADE_EMPTY(bb)) { + apr_bucket *bucket = APR_BRIGADE_FIRST(bb); + if (bucket->length) { + break; + } + delete_meta_bucket(bucket); + } + } } while (rv == APR_SUCCESS && bytes_written < bytes_to_write); if ((ap__logio_add_bytes_out != NULL) && (bytes_written > 0)) {