[svn.haxx.se] · SVN Dev · SVN Users · SVN Org · TSVN Dev · TSVN Users · Subclipse Dev · Subclipse Users · this month's index

Re: cvs commit: apr-util/buckets apr_brigade.c

From: Cliff Woolley <jwoolley_at_virginia.edu>
Date: 2002-05-28 23:09:47 CEST

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

This is an archived mail posted to the Subversion Dev mailing list.