Add a reference count to evbuffers.

svn:r1164
This commit is contained in:
Nick Mathewson 2009-04-13 03:06:27 +00:00
parent b01891fe1d
commit dcda7915ac
2 changed files with 23 additions and 3 deletions

View File

@ -257,10 +257,19 @@ evbuffer_new(void)
buffer = mm_calloc(1, sizeof(struct evbuffer));
TAILQ_INIT(&buffer->callbacks);
buffer->refcnt = 1;
return (buffer);
}
void
_evbuffer_incref(struct evbuffer *buf)
{
EVBUFFER_LOCK(buf, EVTHREAD_WRITE);
++buf->refcnt;
EVBUFFER_UNLOCK(buf, EVTHREAD_WRITE);
}
int
evbuffer_defer_callbacks(struct evbuffer *buffer, struct event_base *base)
{
@ -345,6 +354,9 @@ static inline void
evbuffer_invoke_callbacks(struct evbuffer *buffer)
{
if (buffer->deferred_cbs) {
if (buffer->deferred.queued)
return;
_evbuffer_incref(buffer);
event_deferred_cb_schedule(buffer->ev_base, &buffer->deferred);
} else {
evbuffer_run_callbacks(buffer);
@ -355,11 +367,10 @@ static void
evbuffer_deferred_callback(struct deferred_cb *cb, void *arg)
{
struct evbuffer *buffer = arg;
static int which = 0;
printf("FOO #%d\n", which++);
EVBUFFER_LOCK(buffer, EVTHREAD_WRITE);
evbuffer_run_callbacks(buffer);
evbuffer_free(buffer); /* release the reference */
EVBUFFER_UNLOCK(buffer, EVTHREAD_WRITE);
}
@ -379,7 +390,11 @@ evbuffer_free(struct evbuffer *buffer)
{
struct evbuffer_chain *chain, *next;
ASSERT_EVBUFFER_UNLOCKED(buffer);
EVBUFFER_LOCK(buffer, EVTHREAD_WRITE);
if (--buffer->refcnt > 0) {
EVBUFFER_UNLOCK(buffer, EVTHREAD_WRITE);
return;
}
for (chain = buffer->first; chain != NULL; chain = next) {
next = chain->next;
@ -388,6 +403,8 @@ evbuffer_free(struct evbuffer *buffer)
evbuffer_remove_all_callbacks(buffer);
if (buffer->deferred_cbs)
event_deferred_cb_cancel(buffer->ev_base, &buffer->deferred);
EVBUFFER_UNLOCK(buffer, EVTHREAD_WRITE);
if (buffer->own_lock)
EVTHREAD_FREE_LOCK(buffer->lock);
mm_free(buffer);

View File

@ -84,6 +84,7 @@ struct evbuffer {
struct event_base *ev_base;
int lock_count;
int refcnt;
struct deferred_cb deferred;
@ -192,6 +193,8 @@ struct evbuffer_chain_reference {
EVTHREAD_WRITE, EVTHREAD_WRITE); \
} while(0)
void _evbuffer_incref(struct evbuffer *buf);
#ifdef _EVENT_HAVE_SYS_UIO_H
int _evbuffer_read_setup_vecs(struct evbuffer *buf, ssize_t howmuch,
struct iovec *vecs, struct evbuffer_chain **chainp);