From 324ae13e8ee714c2c7a8377d98ea6f9aa1722428 Mon Sep 17 00:00:00 2001 From: Yann Ylavic Date: Fri, 20 Aug 2021 09:36:19 +0000 Subject: core: follow up to r1891148: WC bucket defaulting to FLUSH bucket. Define WC bucket semantics as: /** * @brief Write Completion (WC) bucket * * A WC bucket is a FLUSH bucket with special ->data == &ap_bucket_wc_data, * still both AP_BUCKET_IS_WC() and APR_BUCKET_IS_FLUSH() hold for them so * they have the same semantics for most filters, namely: * Everything produced before shall be passed to the next filter, including * the WC/FLUSH bucket itself. * The distinction between WC and FLUSH buckets is only for filters that care * about write completion (calling ap_filter_reinstate_brigade() with non-NULL * flush_upto), those can setaside WC buckets and the preceding data provided * they have first determined that the next filter(s) have pending data * already, usually by calling ap_filter_should_yield(f->next). */ The only filters that care about write completion for now are ap_core_output_filter() and ssl_io_filter_output(), which try to fill in the pipe as much as possible, using ap_filter_reinstate_brigade(&flush_upto) to determine whether they should flush (blocking) or setaside their remaining data. So ap_filter_reinstate_brigade() is made to not treat WC as FLUSH buckets and keep the above filters working as before (and correctly w.r.t. above WC bucket semantics). * include/ap_mmn.h, include/util_filter.h: Axe specific ap_bucket_type_wc and define global &ap_bucket_wc_data address to mark WC buckets checked by AP_BUCKET_IS_WC(). * server/util_filter.c (ap_filter_reinstate_brigade): Don't treat WC buckets as FLUSH buckets. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1892468 13f79535-47bb-0310-9956-ffa450edef68 --- include/ap_mmn.h | 2 +- include/util_filter.h | 22 +++++++++++++++++++--- 2 files changed, 20 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/include/ap_mmn.h b/include/ap_mmn.h index 0ddf227b90..4686cd3cb4 100644 --- a/include/ap_mmn.h +++ b/include/ap_mmn.h @@ -673,7 +673,7 @@ * ap_proxy_tunnel_conn_get_transferred() change * ap_proxy_transfer_between_connections() sent to apr_off_t *. * 20210531.0 (2.5.1-dev) add conn_rec->outgoing and ap_ssl_bind_outgoing() - * 20210531.1 (2.5.1-dev) Add ap_bucket_type_wc, ap_bucket_wc_make() and + * 20210531.1 (2.5.1-dev) Add ap_bucket_wc_data, ap_bucket_wc_make() and * ap_bucket_wc_create() to util_filter.h * 20210531.2 (2.5.1-dev) Add ap_proxy_get_worker_ex() and * ap_proxy_define_worker_ex() to mod_proxy.h diff --git a/include/util_filter.h b/include/util_filter.h index a0205a5f5c..a03e81c16c 100644 --- a/include/util_filter.h +++ b/include/util_filter.h @@ -763,15 +763,31 @@ AP_DECLARE(void) ap_filter_protocol(ap_filter_t* f, unsigned int proto_flags); /** Filter is incompatible with "Cache-Control: no-transform" */ #define AP_FILTER_PROTO_TRANSFORM 0x20 -/** Write Completion (WC) bucket */ -AP_DECLARE_DATA extern const apr_bucket_type_t ap_bucket_type_wc; +/** + * @brief Write Completion (WC) bucket + * + * A WC bucket is a FLUSH bucket with special ->data == &ap_bucket_wc_data, + * still both AP_BUCKET_IS_WC() and APR_BUCKET_IS_FLUSH() hold for them so + * they have the same semantics for most filters, namely: + * Everything produced before shall be passed to the next filter, including + * the WC/FLUSH bucket itself. + * The distinction between WC and FLUSH buckets is only for filters that care + * about write completion (calling ap_filter_reinstate_brigade() with non-NULL + * flush_upto), those can setaside WC buckets and the preceding data provided + * they have first determined that the next filter(s) have pending data + * already, usually by calling ap_filter_should_yield(f->next). + */ + +/** Write Completion (WC) bucket data mark */ +AP_DECLARE_DATA extern const char ap_bucket_wc_data; /** * Determine if a bucket is a Write Completion (WC) bucket * @param e The bucket to inspect * @return true or false */ -#define AP_BUCKET_IS_WC(e) ((e)->type == &ap_bucket_type_wc) +#define AP_BUCKET_IS_WC(e) (APR_BUCKET_IS_FLUSH(e) && \ + (e)->data == (void *)&ap_bucket_wc_data) /** * Make the bucket passed in a Write Completion (WC) bucket -- cgit v1.2.1