Author: rhuijben
Date: Thu Nov  5 16:15:53 2015
New Revision: 1712806

URL: http://svn.apache.org/viewvc?rev=1712806&view=rev
Log:
Make the aggregate bucket's peek and read a bit more agressive in cleaning
up when it encounters a 100% empty bucket at the front.

The sooner buckets are destroyed, the less chance they have lifetime issues.

* buckets/aggregate_buckets.c
  (serf_aggregate_peek): When the first bucket is 100% empty, destroy it and
    go on to the next one.

Modified:
    serf/trunk/buckets/aggregate_buckets.c

Modified: serf/trunk/buckets/aggregate_buckets.c
URL: 
http://svn.apache.org/viewvc/serf/trunk/buckets/aggregate_buckets.c?rev=1712806&r1=1712805&r2=1712806&view=diff
==============================================================================
--- serf/trunk/buckets/aggregate_buckets.c (original)
+++ serf/trunk/buckets/aggregate_buckets.c Thu Nov  5 16:15:53 2015
@@ -265,10 +265,20 @@ static apr_status_t read_aggregate(serf_
              * we are asked to perform a read operation - thus ensuring the
              * proper read lifetime.
              */
-            next_list = ctx->list->next;
-            ctx->list->next = ctx->done;
-            ctx->done = ctx->list;
-            ctx->list = next_list;
+            if (cur_vecs_used > 0) {
+                next_list = ctx->list->next;
+                ctx->list->next = ctx->done;
+                ctx->done = ctx->list;
+                ctx->list = next_list;
+            }
+            else {
+                /* This bucket didn't add a single byte.
+                   We can destroy it directly */
+                next_list = ctx->list;
+                ctx->list = next_list->next;
+                serf_bucket_destroy(next_list->bucket);
+                serf_bucket_mem_free(bucket->allocator, next_list);
+            }
 
             /* If we have no more in our list, return EOF. */
             if (!ctx->list) {
@@ -439,8 +449,29 @@ static apr_status_t serf_aggregate_peek(
 
     status = serf_bucket_peek(head, data, len);
 
+    /* Is the current head *at* eof? */
+    while (APR_STATUS_IS_EOF(status) && !*len) {
+        bucket_list_t *item = ctx->list;
+
+        if (item->next)
+            ctx->list = item->next;
+        else
+            ctx->list = ctx->last = NULL;
+
+        /* We don't have outstanding data. We are free to release now */
+        serf_bucket_destroy(item->bucket);
+        serf_bucket_mem_free(bucket->allocator, item);
+
+        if (ctx->list) {
+            head = ctx->list->bucket;
+            status = serf_bucket_peek(head, data, len);
+        }
+        else
+            break; /* Check hold open below */
+    }
+
     if (APR_STATUS_IS_EOF(status)) {
-        if (ctx->list->next) {
+        if (ctx->list && ctx->list->next) {
             status = APR_SUCCESS;
         } else {
             if (ctx->hold_open) {


Reply via email to