summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--buffer.c178
-rw-r--r--buffer_iocp.c6
-rw-r--r--evbuffer-internal.h20
-rw-r--r--test/regress_buffer.c38
4 files changed, 147 insertions, 95 deletions
diff --git a/buffer.c b/buffer.c
index 3bec0c63..82acaee0 100644
--- a/buffer.c
+++ b/buffer.c
@@ -210,29 +210,33 @@ evbuffer_chain_free(struct evbuffer_chain *chain)
}
#endif
}
+
mm_free(chain);
}
+
static inline void
evbuffer_chain_insert(struct evbuffer *buf, struct evbuffer_chain *chain)
{
ASSERT_EVBUFFER_LOCKED(buf);
if (buf->first == NULL) {
buf->first = buf->last = chain;
- buf->last_with_data = chain;
+ buf->last_with_datap = &buf->first;
} else {
/* the last chain is empty so we can just drop it */
if (buf->last->off == 0 && !CHAIN_PINNED(buf->last)) {
- if (buf->last_with_data == buf->last)
- buf->last_with_data = chain;
+ /* NOT CLOSE TO RIGHT XXXX */
+ if (*buf->last_with_datap == buf->last) {
+ *buf->last_with_datap = chain;
+ }
evbuffer_chain_free(buf->last);
buf->last = chain;
} else {
buf->last->next = chain;
+ if (chain->off)
+ buf->last_with_datap = &buf->last->next;
buf->last = chain;
}
- if (chain->off)
- buf->last_with_data = chain;
}
buf->total_len += chain->off;
@@ -265,6 +269,7 @@ evbuffer_new(void)
TAILQ_INIT(&buffer->callbacks);
buffer->refcnt = 1;
+ buffer->last_with_datap = &buffer->first;
return (buffer);
}
@@ -507,7 +512,7 @@ int
evbuffer_reserve_space(struct evbuffer *buf, ev_ssize_t size,
struct evbuffer_iovec *vec, int n_vecs)
{
- struct evbuffer_chain *chain;
+ struct evbuffer_chain *chain, **chainp;
int n = -1;
EVBUFFER_LOCK(buf);
@@ -526,7 +531,7 @@ evbuffer_reserve_space(struct evbuffer *buf, ev_ssize_t size,
} else {
if (_evbuffer_expand_fast(buf, size, n_vecs)<0)
goto done;
- n = _evbuffer_read_setup_vecs(buf, size, vec, n_vecs, &chain, 0);
+ n = _evbuffer_read_setup_vecs(buf, size, vec, n_vecs, &chainp, 0);
}
done:
@@ -541,11 +546,11 @@ advance_last_with_data(struct evbuffer *buf)
int n = 0;
ASSERT_EVBUFFER_LOCKED(buf);
- if (!buf->last_with_data)
+ if (!*buf->last_with_datap)
return 0;
- while (buf->last_with_data->next && buf->last_with_data->next->off) {
- buf->last_with_data = buf->last_with_data->next;
+ while ((*buf->last_with_datap)->next && (*buf->last_with_datap)->next->off) {
+ buf->last_with_datap = &(*buf->last_with_datap)->next;
++n;
}
return n;
@@ -555,7 +560,7 @@ int
evbuffer_commit_space(struct evbuffer *buf,
struct evbuffer_iovec *vec, int n_vecs)
{
- struct evbuffer_chain *firstchain, *chain;
+ struct evbuffer_chain *chain, **firstchainp, **chainp;
int result = -1;
size_t added = 0;
int i;
@@ -576,19 +581,19 @@ evbuffer_commit_space(struct evbuffer *buf,
buf->last->off += vec[0].iov_len;
added = vec[0].iov_len;
if (added)
- buf->last_with_data = buf->last;
+ advance_last_with_data(buf);
goto okay;
}
/* Advance 'firstchain' to the first chain with space in it. */
- firstchain = buf->last_with_data;
- if (!firstchain)
+ firstchainp = buf->last_with_datap;
+ if (!*firstchainp)
goto done;
- if (CHAIN_SPACE_LEN(firstchain) == 0) {
- firstchain = firstchain->next;
+ if (CHAIN_SPACE_LEN(*firstchainp) == 0) {
+ firstchainp = &(*firstchainp)->next;
}
- chain = firstchain;
+ chain = *firstchainp;
/* pass 1: make sure that the pointers and lengths of vecs[] are in
* bounds before we try to commit anything. */
for (i=0; i<n_vecs; ++i) {
@@ -600,13 +605,14 @@ evbuffer_commit_space(struct evbuffer *buf,
chain = chain->next;
}
/* pass 2: actually adjust all the chains. */
- chain = firstchain;
+ chainp = firstchainp;
for (i=0; i<n_vecs; ++i) {
- chain->off += vec[i].iov_len;
+ (*chainp)->off += vec[i].iov_len;
added += vec[i].iov_len;
- if (vec[i].iov_len)
- buf->last_with_data = chain;
- chain = chain->next;
+ if (vec[i].iov_len) {
+ buf->last_with_datap = chainp;
+ }
+ chainp = &(*chainp)->next;
}
okay:
@@ -624,7 +630,7 @@ done:
ASSERT_EVBUFFER_LOCKED(dst); \
(dst)->first = NULL; \
(dst)->last = NULL; \
- (dst)->last_with_data = NULL; \
+ (dst)->last_with_datap = &(dst)->first; \
(dst)->total_len = 0; \
} while (0)
@@ -632,7 +638,10 @@ done:
ASSERT_EVBUFFER_LOCKED(dst); \
ASSERT_EVBUFFER_LOCKED(src); \
(dst)->first = (src)->first; \
- (dst)->last_with_data = (src)->last_with_data; \
+ if ((src)->last_with_datap == &(src)->first) \
+ (dst)->last_with_datap = &(dst)->first; \
+ else \
+ (dst)->last_with_datap = (src)->last_with_datap; \
(dst)->last = (src)->last; \
(dst)->total_len = (src)->total_len; \
} while (0)
@@ -641,20 +650,28 @@ done:
ASSERT_EVBUFFER_LOCKED(dst); \
ASSERT_EVBUFFER_LOCKED(src); \
(dst)->last->next = (src)->first; \
- if ((src)->last_with_data) \
- (dst)->last_with_data = (src)->last_with_data; \
+ if ((src)->last_with_datap == &(src)->first) \
+ (dst)->last_with_datap = &(dst)->last->next; \
+ else \
+ (dst)->last_with_datap = (src)->last_with_datap; \
(dst)->last = (src)->last; \
(dst)->total_len += (src)->total_len; \
} while (0)
-#define PREPEND_CHAIN(dst, src) do { \
- ASSERT_EVBUFFER_LOCKED(dst); \
- ASSERT_EVBUFFER_LOCKED(src); \
- (src)->last->next = (dst)->first; \
- (dst)->first = (src)->first; \
- (dst)->total_len += (src)->total_len; \
- if ((dst)->last_with_data == NULL) \
- (dst)->last_with_data = (src)->last_with_data; \
+#define PREPEND_CHAIN(dst, src) do { \
+ ASSERT_EVBUFFER_LOCKED(dst); \
+ ASSERT_EVBUFFER_LOCKED(src); \
+ (src)->last->next = (dst)->first; \
+ (dst)->first = (src)->first; \
+ (dst)->total_len += (src)->total_len; \
+ if (*(dst)->last_with_datap == NULL) { \
+ if ((src)->last_with_datap == &(src)->first) \
+ (dst)->last_with_datap = &(dst)->first; \
+ else \
+ (dst)->last_with_datap = (src)->last_with_datap; \
+ } else if ((dst)->last_with_datap == &(dst)->first) { \
+ (dst)->last_with_datap = &(src)->last->next; \
+ } \
} while (0)
int
@@ -676,6 +693,7 @@ evbuffer_add_buffer(struct evbuffer *outbuf, struct evbuffer *inbuf)
}
if (out_total_len == 0) {
+ /* XXX need to free old outbuf chains */
COPY_CHAIN(outbuf, inbuf);
} else {
APPEND_CHAIN(outbuf, inbuf);
@@ -714,6 +732,7 @@ evbuffer_prepend_buffer(struct evbuffer *outbuf, struct evbuffer *inbuf)
}
if (out_total_len == 0) {
+ /* XXX need to free old outbuf chains */
COPY_CHAIN(outbuf, inbuf);
} else {
PREPEND_CHAIN(outbuf, inbuf);
@@ -768,8 +787,12 @@ evbuffer_drain(struct evbuffer *buf, size_t len)
for (chain = buf->first; len >= chain->off; chain = next) {
next = chain->next;
len -= chain->off;
- if (chain == buf->last_with_data)
- buf->last_with_data = next;
+
+ if (chain == *buf->last_with_datap) {
+ buf->last_with_datap = &buf->first;
+ }
+ if (&chain->next == buf->last_with_datap)
+ buf->last_with_datap = &buf->first;
if (len == 0 && CHAIN_PINNED_R(chain))
break;
@@ -823,8 +846,9 @@ evbuffer_remove(struct evbuffer *buf, void *data_out, size_t datlen)
data += chain->off;
datlen -= chain->off;
- if (chain == buf->last_with_data)
- buf->last_with_data = chain->next;
+ if (chain == *buf->last_with_datap) {
+ buf->last_with_datap = &buf->first;
+ }
tmp = chain;
chain = chain->next;
@@ -893,10 +917,12 @@ evbuffer_remove_buffer(struct evbuffer *src, struct evbuffer *dst,
/* We can't remove the last with data from src unless we
* remove all chains, in which case we would have done the if
* block above */
- EVUTIL_ASSERT(chain != src->last_with_data);
+ EVUTIL_ASSERT(chain != *src->last_with_datap);
nread += chain->off;
datlen -= chain->off;
previous = chain;
+ if (src->last_with_datap == &chain->next)
+ src->last_with_datap = &src->first;
chain = chain->next;
}
@@ -908,9 +934,9 @@ evbuffer_remove_buffer(struct evbuffer *src, struct evbuffer *dst,
dst->last->next = src->first;
}
dst->last = previous;
- dst->last_with_data = dst->last;
previous->next = NULL;
src->first = chain;
+ advance_last_with_data(dst);
dst->total_len += nread;
dst->n_add_for_cb += nread;
@@ -944,6 +970,7 @@ evbuffer_pullup(struct evbuffer *buf, ev_ssize_t size)
unsigned char *buffer, *result = NULL;
ev_ssize_t remaining;
int removed_last_with_data = 0;
+ int removed_last_with_datap = 0;
EVBUFFER_LOCK(buf);
@@ -1013,8 +1040,10 @@ evbuffer_pullup(struct evbuffer *buf, ev_ssize_t size)
memcpy(buffer, chain->buffer + chain->misalign, chain->off);
size -= chain->off;
buffer += chain->off;
- if (chain == buf->last_with_data)
+ if (chain == *buf->last_with_datap)
removed_last_with_data = 1;
+ if (&chain->next == buf->last_with_datap)
+ removed_last_with_datap = 1;
evbuffer_chain_free(chain);
}
@@ -1030,10 +1059,12 @@ evbuffer_pullup(struct evbuffer *buf, ev_ssize_t size)
tmp->next = chain;
if (removed_last_with_data) {
- int n;
- buf->last_with_data = buf->first;
- n = advance_last_with_data(buf);
- EVUTIL_ASSERT(n == 0);
+ buf->last_with_datap = &buf->first;
+ } else if (removed_last_with_datap) {
+ if (buf->first->next && buf->first->next->off)
+ buf->last_with_datap = &buf->first->next;
+ else
+ buf->last_with_datap = &buf->first;
}
result = (tmp->buffer + tmp->misalign);
@@ -1429,10 +1460,8 @@ evbuffer_prepend(struct evbuffer *buf, const void *data, size_t datlen)
if ((tmp = evbuffer_chain_new(datlen)) == NULL)
goto done;
buf->first = tmp;
- if (buf->last_with_data == NULL)
- buf->last_with_data = tmp;
- else if (chain && buf->last_with_data == chain && 0==chain->off)
- buf->last_with_data = tmp;
+ if (buf->last_with_datap == &buf->first)
+ buf->last_with_datap = &tmp->next;
tmp->next = chain;
@@ -1515,8 +1544,6 @@ evbuffer_expand(struct evbuffer *buf, size_t datlen)
if (buf->first == chain)
buf->first = tmp;
buf->last = tmp;
- if (buf->last->off || buf->last_with_data == chain)
- buf->last_with_data = tmp;
evbuffer_chain_free(chain);
@@ -1555,10 +1582,10 @@ _evbuffer_expand_fast(struct evbuffer *buf, size_t datlen, int n)
/* How many bytes can we stick at the end of buffer as it is? Iterate
* over the chains at the end of the buffer, tring to see how much
* space we have in the first n. */
- for (chain = buf->last_with_data; chain; chain = chain->next) {
+ for (chain = *buf->last_with_datap; chain; chain = chain->next) {
if (chain->off) {
size_t space = CHAIN_SPACE_LEN(chain);
- EVUTIL_ASSERT(chain == buf->last_with_data);
+ EVUTIL_ASSERT(chain == *buf->last_with_datap);
if (space) {
avail += space;
++used;
@@ -1598,7 +1625,7 @@ _evbuffer_expand_fast(struct evbuffer *buf, size_t datlen, int n)
} else {
/* Nuke _all_ the empty chains. */
int rmv_all = 0; /* True iff we removed last_with_data. */
- chain = buf->last_with_data;
+ chain = *buf->last_with_datap;
if (!chain->off) {
EVUTIL_ASSERT(chain == buf->first);
rmv_all = 1;
@@ -1619,16 +1646,17 @@ _evbuffer_expand_fast(struct evbuffer *buf, size_t datlen, int n)
if (rmv_all) {
ZERO_CHAIN(buf);
} else {
- buf->last = buf->last_with_data;
- buf->last_with_data->next = NULL;
+ buf->last = *buf->last_with_datap;
+ (*buf->last_with_datap)->next = NULL;
}
return (-1);
}
if (rmv_all) {
- buf->first = buf->last = buf->last_with_data = tmp;
+ buf->first = buf->last = tmp;
+ buf->last_with_datap = &buf->first;
} else {
- buf->last_with_data->next = tmp;
+ (*buf->last_with_datap)->next = tmp;
buf->last = tmp;
}
return (0);
@@ -1679,9 +1707,10 @@ _evbuffer_expand_fast(struct evbuffer *buf, size_t datlen, int n)
int
_evbuffer_read_setup_vecs(struct evbuffer *buf, ev_ssize_t howmuch,
struct evbuffer_iovec *vecs, int n_vecs_avail,
- struct evbuffer_chain **chainp, int exact)
+ struct evbuffer_chain ***chainp, int exact)
{
- struct evbuffer_chain *chain, *firstchain;
+ struct evbuffer_chain *chain;
+ struct evbuffer_chain **firstchainp;
size_t so_far;
int i;
ASSERT_EVBUFFER_LOCKED(buf);
@@ -1691,11 +1720,12 @@ _evbuffer_read_setup_vecs(struct evbuffer *buf, ev_ssize_t howmuch,
so_far = 0;
/* Let firstchain be the first chain with any space on it */
- firstchain = buf->last_with_data;
- if (CHAIN_SPACE_LEN(firstchain) == 0)
- firstchain = firstchain->next;
+ firstchainp = buf->last_with_datap;
+ if (CHAIN_SPACE_LEN(*firstchainp) == 0) {
+ firstchainp = &(*firstchainp)->next;
+ }
- chain = firstchain;
+ chain = *firstchainp;
for (i = 0; i < n_vecs_avail && so_far < howmuch; ++i) {
size_t avail = CHAIN_SPACE_LEN(chain);
if (avail > howmuch && exact)
@@ -1706,7 +1736,7 @@ _evbuffer_read_setup_vecs(struct evbuffer *buf, ev_ssize_t howmuch,
chain = chain->next;
}
- *chainp = firstchain;
+ *chainp = firstchainp;
return i;
}
@@ -1715,7 +1745,7 @@ _evbuffer_read_setup_vecs(struct evbuffer *buf, ev_ssize_t howmuch,
int
evbuffer_read(struct evbuffer *buf, evutil_socket_t fd, int howmuch)
{
- struct evbuffer_chain *chain;
+ struct evbuffer_chain *chain, **chainp;
int n = EVBUFFER_MAX_READ;
int result;
@@ -1771,13 +1801,13 @@ evbuffer_read(struct evbuffer *buf, evutil_socket_t fd, int howmuch)
IOV_TYPE vecs[NUM_READ_IOVEC];
#ifdef _EVBUFFER_IOVEC_IS_NATIVE
nvecs = _evbuffer_read_setup_vecs(buf, howmuch, vecs,
- NUM_READ_IOVEC, &chain, 1);
+ NUM_READ_IOVEC, &chainp, 1);
#else
/* We aren't using the native struct iovec. Therefore,
we are on win32. */
struct evbuffer_iovec ev_vecs[NUM_READ_IOVEC];
nvecs = _evbuffer_read_setup_vecs(buf, howmuch, ev_vecs, 2,
- &chain, 1);
+ &chainp, 1);
for (i=0; i < nvecs; ++i)
WSABUF_FROM_EVBUFFER_IOV(&vecs[i], &ev_vecs[i]);
@@ -1835,20 +1865,20 @@ evbuffer_read(struct evbuffer *buf, evutil_socket_t fd, int howmuch)
#ifdef USE_IOVEC_IMPL
remaining = n;
for (i=0; i < nvecs; ++i) {
- ev_ssize_t space = CHAIN_SPACE_LEN(chain);
+ ev_ssize_t space = CHAIN_SPACE_LEN(*chainp);
if (space < remaining) {
- chain->off += space;
+ (*chainp)->off += space;
remaining -= space;
} else {
- chain->off += remaining;
- buf->last_with_data = chain;
+ (*chainp)->off += remaining;
+ buf->last_with_datap = chainp;
break;
}
- chain = chain->next;
+ chainp = &(*chainp)->next;
}
#else
chain->off += n;
- buf->last_with_data = chain;
+ advance_last_with_data(buf);
#endif
buf->total_len += n;
buf->n_add_for_cb += n;
diff --git a/buffer_iocp.c b/buffer_iocp.c
index cdf2eaa5..6983a6ac 100644
--- a/buffer_iocp.c
+++ b/buffer_iocp.c
@@ -233,7 +233,7 @@ evbuffer_launch_read(struct evbuffer *buf, size_t at_most,
int r = -1, i;
int nvecs;
int npin=0;
- struct evbuffer_chain *chain=NULL;
+ struct evbuffer_chain *chain=NULL, **chainp;
DWORD bytesRead;
DWORD flags = 0;
struct evbuffer_iovec vecs[MAX_WSABUFS];
@@ -257,7 +257,7 @@ evbuffer_launch_read(struct evbuffer *buf, size_t at_most,
* not "2". But commit_read() above can't handle more than two
* buffers yet. */
nvecs = _evbuffer_read_setup_vecs(buf, at_most,
- vecs, 2, &chain, 1);
+ vecs, 2, &chainp, 1);
for (i=0;i<nvecs;++i) {
WSABUF_FROM_EVBUFFER_IOV(
&buf_o->buffers[i],
@@ -265,7 +265,7 @@ evbuffer_launch_read(struct evbuffer *buf, size_t at_most,
}
buf_o->n_buffers = nvecs;
- buf_o->first_pinned = chain;
+ buf_o->first_pinned = chain= *chainp;
npin=0;
for ( ; chain; chain = chain->next) {
_evbuffer_chain_pin(chain, EVBUFFER_MEM_PINNED_R);
diff --git a/evbuffer-internal.h b/evbuffer-internal.h
index ce1c347d..01f5703a 100644
--- a/evbuffer-internal.h
+++ b/evbuffer-internal.h
@@ -81,10 +81,20 @@ struct evbuffer {
/** The last chain in this buffer's linked list of chains. */
struct evbuffer_chain *last;
- /** The last chain that has any data in it. If all chains in the
- * buffer are empty, points to the first chain. If the buffer has no
- * chains, this is NULL. */
- struct evbuffer_chain *last_with_data;
+ /** Pointer to the next pointer pointing at the 'last_with_data' chain.
+ *
+ * To unpack:
+ *
+ * The last_with_data chain is the last chain that has any data in it.
+ * If all chains in the buffer are empty, it is the first chain.
+ * If the buffer has no chains, it is NULL.
+ *
+ * The last_with_datap pointer points at _whatever 'next' pointer_
+ * points at the last_with_datap chain. If the last_with_data chain
+ * is the first chain, or it is NULL, then the last_with_datap pointer
+ * is &buf->first.
+ */
+ struct evbuffer_chain **last_with_datap;
/** Total amount of bytes stored in all chains.*/
size_t total_len;
@@ -246,7 +256,7 @@ int _evbuffer_expand_fast(struct evbuffer *, size_t, int);
* Returns the number of vecs used.
*/
int _evbuffer_read_setup_vecs(struct evbuffer *buf, ev_ssize_t howmuch,
- struct evbuffer_iovec *vecs, int n_vecs, struct evbuffer_chain **chainp, int exact);
+ struct evbuffer_iovec *vecs, int n_vecs, struct evbuffer_chain ***chainp, int exact);
/* Helper macro: copies an evbuffer_iovec in ei to a win32 WSABUF in i. */
#define WSABUF_FROM_EVBUFFER_IOV(i,ei) do { \
diff --git a/test/regress_buffer.c b/test/regress_buffer.c
index a018d72d..120d4983 100644
--- a/test/regress_buffer.c
+++ b/test/regress_buffer.c
@@ -68,7 +68,7 @@ _evbuffer_validate(struct evbuffer *buf)
{
struct evbuffer_chain *chain;
size_t sum = 0;
- int found_last_with_data = 0;
+ int found_last_with_datap = 0;
if (buf->first == NULL) {
tt_assert(buf->last == NULL);
@@ -76,9 +76,14 @@ _evbuffer_validate(struct evbuffer *buf)
}
chain = buf->first;
+
+ tt_assert(buf->last_with_datap);
+ if (buf->last_with_datap == &buf->first)
+ found_last_with_datap = 1;
+
while (chain != NULL) {
- if (chain == buf->last_with_data)
- found_last_with_data = 1;
+ if (&chain->next == buf->last_with_datap)
+ found_last_with_datap = 1;
sum += chain->off;
if (chain->next == NULL) {
tt_assert(buf->last == chain);
@@ -88,10 +93,10 @@ _evbuffer_validate(struct evbuffer *buf)
}
if (buf->first)
- tt_assert(buf->last_with_data);
- if (buf->last_with_data) {
- tt_assert(found_last_with_data);
- chain = buf->last_with_data;
+ tt_assert(*buf->last_with_datap);
+
+ if (*buf->last_with_datap) {
+ chain = *buf->last_with_datap;
if (chain->off == 0 || buf->total_len == 0) {
tt_assert(chain->off == 0)
tt_assert(chain == buf->first);
@@ -102,7 +107,10 @@ _evbuffer_validate(struct evbuffer *buf)
tt_assert(chain->off == 0);
chain = chain->next;
}
+ } else {
+ tt_assert(buf->last_with_datap == &buf->first);
}
+ tt_assert(found_last_with_datap);
tt_assert(sum == buf->total_len);
return 1;
@@ -111,7 +119,7 @@ _evbuffer_validate(struct evbuffer *buf)
}
#define evbuffer_validate(buf) \
- TT_STMT_BEGIN if (!_evbuffer_validate(buf)) goto end; TT_STMT_END
+ TT_STMT_BEGIN if (!_evbuffer_validate(buf)) TT_DIE(("Buffer format invalid")); TT_STMT_END
static void
test_evbuffer(void *ptr)
@@ -481,7 +489,9 @@ test_evbuffer_add_file(void *ptr)
evbuffer_validate(src);
}
+ evbuffer_validate(src);
tt_assert(evbuffer_read(src, pair[1], strlen(data)) == strlen(data));
+ evbuffer_validate(src);
compare = (char *)evbuffer_pullup(src, strlen(data));
tt_assert(compare != NULL);
if (memcmp(compare, data, strlen(data)))
@@ -933,16 +943,20 @@ test_evbuffer_callbacks(void *ptr)
* adds a summary of length changes to buf_out1/buf_out2 when called. */
/* size: 0-> 36. */
evbuffer_add_printf(buf, "The %d magic words are spotty pudding", 2);
+ evbuffer_validate(buf);
evbuffer_cb_clear_flags(buf, cb2, EVBUFFER_CB_ENABLED);
evbuffer_drain(buf, 10); /*36->26*/
+ evbuffer_validate(buf);
evbuffer_prepend(buf, "Hello", 5);/*26->31*/
evbuffer_cb_set_flags(buf, cb2, EVBUFFER_CB_ENABLED);
evbuffer_add_reference(buf, "Goodbye", 7, NULL, NULL); /*31->38*/
evbuffer_remove_cb_entry(buf, cb1);
+ evbuffer_validate(buf);
evbuffer_drain(buf, evbuffer_get_length(buf)); /*38->0*/;
tt_assert(-1 == evbuffer_remove_cb(buf, log_change_callback, NULL));
evbuffer_add(buf, "X", 1); /* 0->1 */
tt_assert(!evbuffer_remove_cb(buf, log_change_callback, buf_out2));
+ evbuffer_validate(buf);
tt_str_op(evbuffer_pullup(buf_out1, -1), ==,
"0->36; 36->26; 26->31; 31->38; ");
@@ -950,7 +964,6 @@ test_evbuffer_callbacks(void *ptr)
"0->36; 31->38; 38->0; 0->1; ");
evbuffer_drain(buf_out1, evbuffer_get_length(buf_out1));
evbuffer_drain(buf_out2, evbuffer_get_length(buf_out2));
-
/* Let's test the obsolete buffer_setcb function too. */
cb1 = evbuffer_add_cb(buf, log_change_callback, buf_out1);
cb2 = evbuffer_add_cb(buf, log_change_callback, buf_out2);
@@ -962,11 +975,9 @@ test_evbuffer_callbacks(void *ptr)
evbuffer_setcb(buf, NULL, NULL);
evbuffer_add_printf(buf, "This will not.");
tt_str_op(evbuffer_pullup(buf, -1), ==, "This will not.");
-
evbuffer_validate(buf);
evbuffer_drain(buf, evbuffer_get_length(buf));
evbuffer_validate(buf);
-
#if 0
/* Now let's try a suspended callback. */
cb1 = evbuffer_add_cb(buf, log_change_callback, buf_out1);
@@ -1128,6 +1139,7 @@ test_evbuffer_prepend(void *ptr)
evbuffer_add_printf(buf1, "Here is string %d. ", n++);
evbuffer_prepend_buffer(buf2, buf1);
evbuffer_validate(buf2);
+ evbuffer_validate(buf1);
n = evbuffer_remove(buf2, tmp, sizeof(tmp)-1);
tmp[n]='\0';
tt_str_op(tmp,==,"Here is string 1000. Here is string 999. ");
@@ -1362,13 +1374,13 @@ struct testcase_t evbuffer_testcases[] = {
{ "search", test_evbuffer_search, 0, NULL, NULL },
{ "callbacks", test_evbuffer_callbacks, 0, NULL, NULL },
{ "add_reference", test_evbuffer_add_reference, 0, NULL, NULL },
- { "prepend", test_evbuffer_prepend, 0, NULL, NULL },
+ { "prepend", test_evbuffer_prepend, TT_FORK, NULL, NULL },
{ "peek", test_evbuffer_peek, 0, NULL, NULL },
{ "freeze_start", test_evbuffer_freeze, 0, &nil_setup, (void*)"start" },
{ "freeze_end", test_evbuffer_freeze, 0, &nil_setup, (void*)"end" },
#ifndef WIN32
/* TODO: need a temp file implementation for Windows */
- { "add_file", test_evbuffer_add_file, 0, NULL, NULL },
+ { "add_file", test_evbuffer_add_file, TT_FORK, NULL, NULL },
#endif
END_OF_TESTCASES