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) {