From: Nick Mathewson Date: Fri, 17 Apr 2009 06:57:38 +0000 (+0000) Subject: Add reference counts to bufferevents. X-Git-Tag: release-2.0.1-alpha~3 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=91039e4d48c6306c749e44853891416d131cee6d;p=libevent Add reference counts to bufferevents. svn:r1189 --- diff --git a/bufferevent-internal.h b/bufferevent-internal.h index b1026f68..1fb78716 100644 --- a/bufferevent-internal.h +++ b/bufferevent-internal.h @@ -110,6 +110,8 @@ void bufferevent_wm_suspend_read(struct bufferevent *bufev); void bufferevent_wm_unsuspend_read(struct bufferevent *bufev); int bufferevent_enable_locking(struct bufferevent *bufev, void *lock); +void bufferevent_incref(struct bufferevent *bufev); +void _bufferevent_decref_and_unlock(struct bufferevent *bufev); #define BEV_UPCAST(b) EVUTIL_UPCAST((b), struct bufferevent_private, bev) diff --git a/bufferevent.c b/bufferevent.c index f0d7bfdf..7b6c94f2 100644 --- a/bufferevent.c +++ b/bufferevent.c @@ -128,6 +128,7 @@ bufferevent_init_common(struct bufferevent_private *bufev_private, return -1; } + bufev_private->refcnt = 1; bufev->ev_base = base; /* Disable timeouts. */ @@ -367,8 +368,16 @@ bufferevent_flush(struct bufferevent *bufev, } void -bufferevent_free(struct bufferevent *bufev) +_bufferevent_decref_and_unlock(struct bufferevent *bufev) { + struct bufferevent_private *bufev_private = + EVUTIL_UPCAST(bufev, struct bufferevent_private, bev); + + if (--bufev_private->refcnt) { + BEV_UNLOCK(bufev); + return; + } + /* Clean up the shared info */ if (bufev->be_ops->destruct) bufev->be_ops->destruct(bufev); @@ -377,9 +386,30 @@ bufferevent_free(struct bufferevent *bufev) evbuffer_free(bufev->input); evbuffer_free(bufev->output); + BEV_UNLOCK(bufev); + if (bufev_private->own_lock) + EVTHREAD_FREE_LOCK(bufev_private->lock); + /* Free the actual allocated memory. */ mm_free(bufev - bufev->be_ops->mem_offset); - /* Free lock XXX */ +} + +void +bufferevent_free(struct bufferevent *bufev) +{ + BEV_LOCK(bufev); + _bufferevent_decref_and_unlock(bufev); +} + +void +bufferevent_incref(struct bufferevent *bufev) +{ + struct bufferevent_private *bufev_private = + EVUTIL_UPCAST(bufev, struct bufferevent_private, bev); + + BEV_LOCK(bufev); + ++bufev_private->refcnt; + BEV_UNLOCK(bufev); } int