|
From: Nick M. <ni...@us...> - 2010-02-23 05:40:16
|
Author: Nick Mathewson <ni...@to...>
Date: Mon, 22 Feb 2010 15:38:23 -0500
Subject: Make bufferevent_free() clear all callbacks immediately.
Commit: b2fbeb3f074258e4559aa879ef0cbe0ef415ed0f
This should end the family of bugs where we call bufferevent_free()
while a pending callback is holding a reference on the bufferevent,
and the callback tries to invoke the user callbacks before it releases
its own final reference.
This means that bufferevent_decref() is now a separate function from
bufferevent_free().
---
buffer.c | 2 +-
bufferevent-internal.h | 4 ++--
bufferevent.c | 8 ++++++++
3 files changed, 11 insertions(+), 3 deletions(-)
diff --git a/buffer.c b/buffer.c
index 7185bd1..08b9cba 100644
--- a/buffer.c
+++ b/buffer.c
@@ -413,7 +413,7 @@ evbuffer_deferred_callback(struct deferred_cb *cb, void *arg)
evbuffer_run_callbacks(buffer, 1);
_evbuffer_decref_and_unlock(buffer);
if (parent)
- bufferevent_free(parent);
+ bufferevent_decref(parent);
}
static void
diff --git a/bufferevent-internal.h b/bufferevent-internal.h
index ad1f844..9cc9fbb 100644
--- a/bufferevent-internal.h
+++ b/bufferevent-internal.h
@@ -274,11 +274,11 @@ void bufferevent_incref(struct bufferevent *bufev);
/** Internal: Lock bufev and increase its reference count.
* unlocking it otherwise. */
void _bufferevent_incref_and_lock(struct bufferevent *bufev);
+/** Internal: Increment the reference count on bufev. */
+void bufferevent_decref(struct bufferevent *bufev);
/** Internal: Drop the reference count on bufev, freeing as necessary, and
* unlocking it otherwise. */
void _bufferevent_decref_and_unlock(struct bufferevent *bufev);
-/** Sometimes it is more clear to say "decref" than "free" */
-#define bufferevent_decref(b) bufferevent_free(b)
/** Internal: If callbacks are deferred and we have a read callback, schedule
* a readcb. Otherwise just run the readcb. */
diff --git a/bufferevent.c b/bufferevent.c
index 4a7b46a..3864cec 100644
--- a/bufferevent.c
+++ b/bufferevent.c
@@ -561,9 +561,17 @@ _bufferevent_decref_and_unlock(struct bufferevent *bufev)
}
void
+bufferevent_decref(struct bufferevent *bufev)
+{
+ BEV_LOCK(bufev);
+ _bufferevent_decref_and_unlock(bufev);
+}
+
+void
bufferevent_free(struct bufferevent *bufev)
{
BEV_LOCK(bufev);
+ bufferevent_setcb(bufev, NULL, NULL, NULL, NULL);
_bufferevent_decref_and_unlock(bufev);
}
--
1.6.3
|