diff --git a/docs/manual/mod/core.xml b/docs/manual/mod/core.xml index 0abab55c69..29ff18f253 100644 --- a/docs/manual/mod/core.xml +++ b/docs/manual/mod/core.xml @@ -2031,21 +2031,24 @@ filenames FlushMaxPipelined -Threshold above which pipelined responses are flushed to the -network +Maximum number of pipelined responses above which they are flushed +to the network FlushMaxPipelined number FlushMaxPipelined 5 server configvirtual host -directory + 2.5 and later -

This directive allows to configure the threshold for pipelined - responses, which remain pending so long as pipelined request are handled. - When this limit is reached, are forcibly flushed to the network in blocking - mode, until passing under the threshold again.

+

This directive allows to configure the maximum number of pipelined + responses, which remain pending so long as pipelined request are received. + When the limit is reached, reponses are forcibly flushed to the network in + blocking mode, until passing under the limit again.

-

This threshold helps maintaning constrained memory usage.

+

FlushMaxPipelined helps constraining memory + usage. When set to 0 pipelining is disabled, when set to + -1 there is no limit (FlushMaxThreshold + still applies).

@@ -2056,15 +2059,19 @@ network FlushMaxThresholdnumber-of-bytes FlushMaxThreshold 65536 server configvirtual host -directory + 2.5 and later -

This directive allows to configure the threshold (in bytes) for pending - output data. When this limit is reached, data are forcibly flushed to the - network in blocking mode, until passing under the threshold again.

+

This directive allows to configure the threshold for pending output + data (in bytes). When the limit is reached, data are forcibly flushed to + the network in blocking mode, until passing under the limit again.

-

This threshold helps maintaning constrained memory usage.

+

FlushMaxThreshold helps constraining memory + usage. When set to 0 or a too small value there are actually + no pending data, but for threaded MPMs there can be more threads busy + waiting for the network thus less ones available to handle the other + simultaneous connections.

@@ -4179,19 +4186,20 @@ Protocols h2 http/1.1 ReadBufferSize -Size of the buffers used to read network data -ReadBufferSize number-of-bytes +Size of the buffers used to read data +ReadBufferSize bytes ReadBufferSize 8192 server configvirtual host directory 2.5 and later -

This directive allows to configure the size in bytes of the memory - buffers used to read data from the network.

+

This directive allows to configure the size (in bytes) of the memory + buffer used to read data from the network or files.

-

Larger buffer can increase peformances for large data but consume more - memory (per connection).

+

A larger buffer can increase peformances with larger data, but consumes + more memory per connection. The minimum configurable size is + 1024.

diff --git a/server/core.c b/server/core.c index f4be343f87..2a3142a7f2 100644 --- a/server/core.c +++ b/server/core.c @@ -83,8 +83,8 @@ /* valid in core-conf, but not in runtime r->used_path_info */ #define AP_ACCEPT_PATHINFO_UNSET 3 -#define AP_FLUSH_MAX_THRESHOLD 65536 -#define AP_FLUSH_MAX_PIPELINED 5 +#define AP_FLUSH_MAX_THRESHOLD 65535 +#define AP_FLUSH_MAX_PIPELINED 4 APR_HOOK_STRUCT( APR_HOOK_LINK(get_mgmt_items) @@ -2344,10 +2344,10 @@ static const char *set_read_buf_size(cmd_parms *cmd, void *d_, char *end; if (apr_strtoff(&size, arg, &end, 10) - || size < 0 || size > APR_SIZE_MAX || *end) + || *end || size < 0 || size > APR_UINT32_MAX) return apr_pstrcat(cmd->pool, "parameter must be a number between 0 and " - APR_STRINGIFY(APR_SIZE_MAX) "): ", + APR_STRINGIFY(APR_UINT32_MAX) "): ", arg, NULL); d->read_buf_size = (apr_size_t)size; @@ -2364,10 +2364,10 @@ static const char *set_flush_max_threshold(cmd_parms *cmd, void *d_, char *end; if (apr_strtoff(&size, arg, &end, 10) - || size <= 0 || size > APR_SIZE_MAX || *end) + || *end || size < 0 || size > APR_UINT32_MAX) return apr_pstrcat(cmd->pool, - "parameter must be a number between 1 and " - APR_STRINGIFY(APR_SIZE_MAX) "): ", + "parameter must be a number between 0 and " + APR_STRINGIFY(APR_UINT32_MAX) "): ", arg, NULL); conf->flush_max_threshold = (apr_size_t)size; @@ -2384,9 +2384,9 @@ static const char *set_flush_max_pipelined(cmd_parms *cmd, void *d_, char *end; if (apr_strtoff(&num, arg, &end, 10) - || num < 0 || num > APR_INT32_MAX || *end) + || *end || num < -1 || num > APR_INT32_MAX) return apr_pstrcat(cmd->pool, - "parameter must be a number between 0 and " + "parameter must be a number between -1 and " APR_STRINGIFY(APR_INT32_MAX) ": ", arg, NULL); @@ -2395,7 +2395,6 @@ static const char *set_flush_max_pipelined(cmd_parms *cmd, void *d_, return NULL; } - /* * Report a missing-'>' syntax error. */ @@ -4733,9 +4732,10 @@ AP_INIT_TAKE1("EnableSendfile", set_enable_sendfile, NULL, OR_FILEINFO, AP_INIT_TAKE1("ReadBufferSize", set_read_buf_size, NULL, ACCESS_CONF|RSRC_CONF, "Size (in bytes) of the memory buffers used to read data"), AP_INIT_TAKE1("FlushMaxThreshold", set_flush_max_threshold, NULL, RSRC_CONF, - "Maximum size (in bytes) above which pending data are flushed (blocking) to the network"), + "Maximum threshold above which pending data are flushed to the network"), AP_INIT_TAKE1("FlushMaxPipelined", set_flush_max_pipelined, NULL, RSRC_CONF, - "Number of pipelined/pending responses above which they are flushed to the network"), + "Maximum number of pipelined responses (pending) above which they are " + "flushed to the network"), /* Old server config file commands */ diff --git a/server/core_filters.c b/server/core_filters.c index fd3cb3928d..1b5317888d 100644 --- a/server/core_filters.c +++ b/server/core_filters.c @@ -610,7 +610,7 @@ static apr_status_t send_brigade_nonblocking(apr_socket_t *s, * we are at the end of the brigade, the write will happen outside * the loop anyway). */ - if (nbytes >= conf->flush_max_threshold + if (nbytes > conf->flush_max_threshold && next != APR_BRIGADE_SENTINEL(bb) && !is_in_memory_bucket(next)) { (void)apr_socket_opt_set(s, APR_TCP_NOPUSH, 1); diff --git a/server/util_filter.c b/server/util_filter.c index c537b00f73..e012265305 100644 --- a/server/util_filter.c +++ b/server/util_filter.c @@ -1104,7 +1104,7 @@ AP_DECLARE(apr_status_t) ap_filter_reinstate_brigade(ap_filter_t *f, * sent to the client.) * * c) The brigade contains at least flush_max_pipelined EOR buckets: do - * blocking writes until the last EOR above flush_max_pipelined. + * blocking writes until after the last EOR above flush_max_pipelined. * (The point of this rule is to prevent too many FDs being kept open * by pipelined requests, possibly allowing a DoS). * @@ -1140,14 +1140,15 @@ AP_DECLARE(apr_status_t) ap_filter_reinstate_brigade(ap_filter_t *f, } if (APR_BUCKET_IS_FLUSH(bucket) - || memory_bytes_in_brigade >= conf->flush_max_threshold - || eor_buckets_in_brigade >= conf->flush_max_pipelined) { + || (memory_bytes_in_brigade > conf->flush_max_threshold) + || (conf->flush_max_pipelined >= 0 + && eor_buckets_in_brigade > conf->flush_max_pipelined)) { /* this segment of the brigade MUST be sent before returning. */ if (APLOGctrace6(f->c)) { char *reason = APR_BUCKET_IS_FLUSH(bucket) ? "FLUSH bucket" : - (memory_bytes_in_brigade >= conf->flush_max_threshold) ? + (memory_bytes_in_brigade > conf->flush_max_threshold) ? "max threshold" : "max requests in pipeline"; ap_log_cerror(APLOG_MARK, APLOG_TRACE6, 0, f->c, "will flush because of %s", reason);