From: Greg Stein Date: Tue, 1 May 2001 18:43:09 +0000 (+0000) Subject: Add a comment about an assumption we make in our keepalive buffering. X-Git-Tag: 2.0.18~133 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=10ead4521affb11ca4dcc5811684d6cfd521f8ae;p=apache Add a comment about an assumption we make in our keepalive buffering. Delay the check for "too many items in an iovec" until we actually try to put something in there. This allows that N+1 bucket to be an EOS, FLUSH, FILE, or zero-length bucket without triggering a split. Only if that next bucket has iovec data will a split be made. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@88969 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/server/core.c b/server/core.c index b371b2db24..6e2706d990 100644 --- a/server/core.c +++ b/server/core.c @@ -3092,29 +3092,31 @@ static apr_status_t core_output_filter(ap_filter_t *f, apr_bucket_brigade *b) rv = apr_bucket_read(e, &str, &n, APR_BLOCK_READ); if (n) { - nbytes += n; if (!fd) { + if (nvec == MAX_IOVEC_TO_WRITE) { + /* woah! too many. stop now. */ + more = apr_brigade_split(b, e); + break; + } vec[nvec].iov_base = (char*) str; vec[nvec].iov_len = n; nvec++; } else { /* The bucket is a trailer to a file bucket */ + + if (nvec_trailers == MAX_IOVEC_TO_WRITE) { + /* woah! too many. stop now. */ + more = apr_brigade_split(b, e); + break; + } vec_trailers[nvec_trailers].iov_base = (char*) str; vec_trailers[nvec_trailers].iov_len = n; nvec_trailers++; } + nbytes += n; } } - - if ((nvec == MAX_IOVEC_TO_WRITE) || - (nvec_trailers == MAX_IOVEC_TO_WRITE)) { - /* Split the brigade and break */ - if (APR_BUCKET_NEXT(e) != APR_BRIGADE_SENTINEL(b)) { - more = apr_brigade_split(b, APR_BUCKET_NEXT(e)); - } - break; - } } /* Completed iterating over the brigades, now determine if we want @@ -3153,6 +3155,17 @@ static apr_status_t core_output_filter(ap_filter_t *f, apr_bucket_brigade *b) apr_size_t n; rv = apr_bucket_read(bucket, &str, &n, APR_BLOCK_READ); + + /* This apr_brigade_write does not use a flush function + because we assume that we will not write enough data + into it to cause a flush. However, if we *do* write + "too much", then we could end up with transient + buckets which would suck. This works for now, but is + a bit shaky if changes are made to some of the + buffering sizes. Let's do an assert to prevent + potential future problems... */ + AP_DEBUG_ASSERT(AP_MIN_BYTES_TO_WRITE < + APR_BUCKET_BUFF_SIZE); apr_brigade_write(ctx->b, NULL, NULL, str, n); } apr_brigade_destroy(b);