diff options
author | Nick Mathewson <nickm@torproject.org> | 2010-08-17 13:18:18 -0400 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2010-08-17 13:18:18 -0400 |
commit | e0972c21389a45c60606ce2b842311c27fea2147 (patch) | |
tree | 5e05f7e83500e7debb4921468c0b01f5370b558c /event-internal.h | |
parent | d4977b52f07d61e215e5d5e98af2216719c06d16 (diff) | |
download | libevent-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.h | 13 |
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 |