summaryrefslogtreecommitdiff
path: root/event-internal.h
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2010-08-17 13:18:18 -0400
committerNick Mathewson <nickm@torproject.org>2010-08-17 13:18:18 -0400
commite0972c21389a45c60606ce2b842311c27fea2147 (patch)
tree5e05f7e83500e7debb4921468c0b01f5370b558c /event-internal.h
parentd4977b52f07d61e215e5d5e98af2216719c06d16 (diff)
downloadlibevent-e0972c21389a45c60606ce2b842311c27fea2147.tar.gz
Use conditions instead of current_event_lock to fix a deadlock.
Avi Bab correctly noted as bug 3044479 the fact that any thread blocking on current_event_lock will do so while holding th_base_lock, making it impossible for the currently running event's callback to call any other functions that require th_base_lock. This patch switches the current_event_lock code to instead use a condition variable that we wait on if we're trying to mess with a currently-executing event, and that we signal when we're done executing a callback if anybody is waiting on it.
Diffstat (limited to 'event-internal.h')
-rw-r--r--event-internal.h13
1 files changed, 7 insertions, 6 deletions
diff --git a/event-internal.h b/event-internal.h
index d1620c5e..e52c129b 100644
--- a/event-internal.h
+++ b/event-internal.h
@@ -216,9 +216,6 @@ struct event_base {
/** The total size of common_timeout_queues. */
int n_common_timeouts_allocated;
- /** The event whose callback is executing right now */
- struct event *current_event;
-
/** List of defered_cb that are active. We run these after the active
* events. */
struct deferred_cb_queue defer_queue;
@@ -247,9 +244,13 @@ struct event_base {
unsigned long th_owner_id;
/** A lock to prevent conflicting accesses to this event_base */
void *th_base_lock;
- /** A lock to prevent event_del from deleting an event while its
- * callback is executing. */
- void *current_event_lock;
+ /** The event whose callback is executing right now */
+ struct event *current_event;
+ /** A condition that gets signalled when we're done processing an
+ * event with waiters on it. */
+ void *current_event_cond;
+ /** Number of threads blocking on current_event_cond. */
+ int current_event_waiters;
#endif
#ifdef WIN32