From: Nick Mathewson Date: Tue, 10 Feb 2009 19:39:22 +0000 (+0000) Subject: Explode less badly in the case where we're told to prepend/append/remove a buffer... X-Git-Tag: release-2.0.1-alpha~76 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=01456265c3113c401579895f60c410202d633788;p=libevent Explode less badly in the case where we're told to prepend/append/remove a buffer to itself. Note some API/implementation deficiencies. svn:r1110 --- diff --git a/buffer.c b/buffer.c index f0aa109f..bb3cd72b 100644 --- a/buffer.c +++ b/buffer.c @@ -350,7 +350,7 @@ evbuffer_add_buffer(struct evbuffer *outbuf, struct evbuffer *inbuf) size_t out_total_len = outbuf->total_len; size_t in_total_len = inbuf->total_len; - if (in_total_len == 0) + if (in_total_len == 0 || outbuf == inbuf) return (0); if (out_total_len == 0) { @@ -374,7 +374,7 @@ evbuffer_prepend_buffer(struct evbuffer *outbuf, struct evbuffer *inbuf) size_t out_total_len = outbuf->total_len; size_t in_total_len = inbuf->total_len; - if (!in_total_len) + if (!in_total_len || inbuf == outbuf) return; if (out_total_len == 0) { @@ -433,6 +433,7 @@ evbuffer_drain(struct evbuffer *buf, size_t len) int evbuffer_remove(struct evbuffer *buf, void *data_out, size_t datlen) { + /*XXX fails badly on sendfile case. */ struct evbuffer_chain *chain = buf->first, *tmp; char *data = data_out; size_t nread; @@ -481,10 +482,16 @@ int evbuffer_remove_buffer(struct evbuffer *src, struct evbuffer *dst, size_t datlen) { + /*XXX We should have an option to force this to be zero-copy.*/ + + /*XXX can fail badly on sendfile case. */ struct evbuffer_chain *chain = src->first; struct evbuffer_chain *previous = chain, *previous_to_previous = NULL; size_t nread = 0; + if (datlen == 0 || dst == src) + return (0); + /* short-cut if there is no more data buffered */ if (datlen >= src->total_len) { datlen = src->total_len; @@ -492,9 +499,6 @@ evbuffer_remove_buffer(struct evbuffer *src, struct evbuffer *dst, return (datlen); } - if (datlen == 0) - return (0); - /* removes chains if possible */ while (chain->off <= datlen) { nread += chain->off;