Remove in_callbacks check: allow full recursion in evbuffer callbacks. If you get yourself in an infinite loop, that's not our fault. Note this in the docs. Also reindent some docs now that my tabs match Niels's.

svn:r1046
This commit is contained in:
Nick Mathewson 2009-01-23 18:03:45 +00:00
parent b1495865aa
commit de7f7a84a3
3 changed files with 26 additions and 28 deletions

View File

@ -116,17 +116,14 @@ static inline void
evbuffer_invoke_callbacks(struct evbuffer *buffer, size_t old_size) evbuffer_invoke_callbacks(struct evbuffer *buffer, size_t old_size)
{ {
size_t new_size = buffer->total_len; size_t new_size = buffer->total_len;
if (!TAILQ_EMPTY(&buffer->callbacks) && old_size != new_size if (!TAILQ_EMPTY(&buffer->callbacks) && old_size != new_size) {
&& !buffer->in_callbacks) {
struct evbuffer_cb_entry *cbent, *next; struct evbuffer_cb_entry *cbent, *next;
buffer->in_callbacks = 1;
for (cbent = TAILQ_FIRST(&buffer->callbacks); for (cbent = TAILQ_FIRST(&buffer->callbacks);
cbent != TAILQ_END(&buffer->callbacks); cbent != TAILQ_END(&buffer->callbacks);
cbent = next) { cbent = next) {
next = TAILQ_NEXT(cbent, next); next = TAILQ_NEXT(cbent, next);
cbent->cb(buffer, old_size, new_size, cbent->cbarg); cbent->cb(buffer, old_size, new_size, cbent->cbarg);
} }
buffer->in_callbacks = 0;
} }
} }

View File

@ -56,7 +56,6 @@ struct evbuffer {
void *cbarg; void *cbarg;
TAILQ_HEAD(evbuffer_cb_queue, evbuffer_cb_entry) callbacks; TAILQ_HEAD(evbuffer_cb_queue, evbuffer_cb_entry) callbacks;
unsigned char in_callbacks;
}; };
struct evbuffer_chain { struct evbuffer_chain {

View File

@ -319,7 +319,7 @@ int evbuffer_read(struct evbuffer *buffer, evutil_socket_t fd, int howmuch);
unsigned char *evbuffer_find(struct evbuffer *buffer, const unsigned char *what, size_t len); unsigned char *evbuffer_find(struct evbuffer *buffer, const unsigned char *what, size_t len);
/** Type definition for a callback that is invoked whenever[1] data is added or /** Type definition for a callback that is invoked whenever data is added or
removed from an evbuffer. removed from an evbuffer.
An evbuffer may have one or more callbacks set at a time. The order An evbuffer may have one or more callbacks set at a time. The order
@ -329,8 +329,10 @@ unsigned char *evbuffer_find(struct evbuffer *buffer, const unsigned char *what,
list of callbacks, or add or remove data from the buffer. It may not list of callbacks, or add or remove data from the buffer. It may not
remove another callback from the list. remove another callback from the list.
[1] If the length of the buffer changes because of a callback, the If a callback adds or removes data from the buffer or from another
callbacks are not invoked again, to prevent an infinite loop. buffer, this can cause a recursive invocation of your callback or
other callbacks. If you ask for an infinite loop, you might just get
one: watch out!
@param buffer the buffer whose size has changed @param buffer the buffer whose size has changed
@param old_len the previous length of the buffer @param old_len the previous length of the buffer