Hey...
Can you guys do me a favor and make sure this fixes the problem you were
seeing with apr_brigade_write() failing to flush and causing massive
memory consuption since Apache 2.0.32?
Thanks,
Cliff
PS: cc: me directly on any responses, please, since I'm not subscribed to
dev@subversion.
---------- Forwarded message ----------
Date: 28 May 2002 21:07:35 -0000
From: jwoolley@apache.org
Reply-To: dev@apr.apache.org
To: apr-util-cvs@apache.org
Subject: cvs commit: apr-util/buckets apr_brigade.c
jwoolley 02/05/28 14:07:35
Modified: buckets apr_brigade.c
Log:
Refactor apr_brigade_write() one more time to regain a bit of behavior
that was lost when check_brigade_flush() was removed, which is that
if we have a heap bucket at the end of the brigade and it just doesn't
have enough space left in it, we should flush rather than creating
a new buffer bucket.
Revision Changes Path
1.41 +31 -29 apr-util/buckets/apr_brigade.c
Index: apr_brigade.c
===================================================================
RCS file: /home/cvs/apr-util/buckets/apr_brigade.c,v
retrieving revision 1.40
retrieving revision 1.41
diff -u -d -u -r1.40 -r1.41
--- apr_brigade.c 23 May 2002 21:34:27 -0000 1.40
+++ apr_brigade.c 28 May 2002 21:07:35 -0000 1.41
@@ -403,45 +403,47 @@
const char *str, apr_size_t nbyte)
{
apr_bucket *e = APR_BRIGADE_LAST(b);
- char *buf;
+ apr_size_t remaining = APR_BUCKET_BUFF_SIZE;
+ char *buf = NULL;
- if (!APR_BRIGADE_EMPTY(b) && APR_BUCKET_IS_HEAP(e) &&
- (e->length + nbyte <= ((apr_bucket_heap *)e->data)->alloc_len))
- {
- /* there is a sufficiently big buffer bucket available */
+ if (!APR_BRIGADE_EMPTY(b) && APR_BUCKET_IS_HEAP(e)) {
apr_bucket_heap *h = e->data;
+
+ remaining = h->alloc_len - e->length;
buf = h->base + e->start + e->length;
}
- else {
- if (nbyte > APR_BUCKET_BUFF_SIZE) {
- /* too big to buffer */
- if (flush) {
- e = apr_bucket_transient_create(str, nbyte, b->bucket_alloc);
- APR_BRIGADE_INSERT_TAIL(b, e);
- return flush(b, ctx);
- }
- else {
- e = apr_bucket_heap_create(str, nbyte, NULL, b->bucket_alloc);
- APR_BRIGADE_INSERT_TAIL(b, e);
- return APR_SUCCESS;
- }
+
+ if (nbyte > remaining) {
+ /* either a buffer bucket exists but is full,
+ * or no buffer bucket exists and the data is too big
+ * to buffer. In either case, we should flush. */
+ if (flush) {
+ e = apr_bucket_transient_create(str, nbyte, b->bucket_alloc);
+ APR_BRIGADE_INSERT_TAIL(b, e);
+ return flush(b, ctx);
}
else {
- /* bigger than the current buffer can handle, but we don't
- * mind making a new buffer */
- buf = apr_bucket_alloc(APR_BUCKET_BUFF_SIZE, b->bucket_alloc);
- e = apr_bucket_heap_create(buf, APR_BUCKET_BUFF_SIZE,
- apr_bucket_free, b->bucket_alloc);
+ e = apr_bucket_heap_create(str, nbyte, NULL, b->bucket_alloc);
APR_BRIGADE_INSERT_TAIL(b, e);
- e->length = 0; /* We are writing into the brigade, and
- * allocating more memory than we need. This
- * ensures that the bucket thinks it is empty just
- * after we create it. We'll fix the length
- * once we put data in it below.
- */
+ return APR_SUCCESS;
}
}
+ else if (!buf) {
+ /* we don't have a buffer, but the data is small enough
+ * that we don't mind making a new buffer */
+ buf = apr_bucket_alloc(APR_BUCKET_BUFF_SIZE, b->bucket_alloc);
+ e = apr_bucket_heap_create(buf, APR_BUCKET_BUFF_SIZE,
+ apr_bucket_free, b->bucket_alloc);
+ APR_BRIGADE_INSERT_TAIL(b, e);
+ e->length = 0; /* We are writing into the brigade, and
+ * allocating more memory than we need. This
+ * ensures that the bucket thinks it is empty just
+ * after we create it. We'll fix the length
+ * once we put data in it below.
+ */
+ }
+ /* there is a sufficiently big buffer bucket available now */
memcpy(buf, str, nbyte);
e->length += nbyte;
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org
Received on Tue May 28 23:16:44 2002