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