From 495ed66705d5790de031f9591b47afcbe4fc1156 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Wed, 1 Sep 2010 16:36:30 -0400 Subject: [PATCH] Close th_notify_fds and open a new pair on reinit After a fork, you want subthreads to wake up the event_base in the child process, not to have the child process and the main process fight over who wakes up whom. Related to a problem found by Nicholas Marriott while debugging 3048812. --- event.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/event.c b/event.c index dbf1c2f3..ee741e7b 100644 --- a/event.c +++ b/event.c @@ -742,6 +742,7 @@ event_reinit(struct event_base *base) const struct eventop *evsel; int res = 0; struct event *ev; + int was_notifiable = 0; EVBASE_ACQUIRE_LOCK(base, th_base_lock); @@ -769,6 +770,23 @@ event_reinit(struct event_base *base) EVLIST_ACTIVE); base->sig.ev_signal_added = 0; } + if (base->th_notify_fd[0] != -1) { + /* we cannot call event_del here because the base has + * not been reinitialized yet. */ + was_notifiable = 1; + event_queue_remove(base, &base->th_notify, + EVLIST_INSERTED); + if (base->th_notify.ev_flags & EVLIST_ACTIVE) + event_queue_remove(base, &base->th_notify, + EVLIST_ACTIVE); + base->sig.ev_signal_added = 0; + EVUTIL_CLOSESOCKET(base->th_notify_fd[0]); + if (base->th_notify_fd[1] != -1) + EVUTIL_CLOSESOCKET(base->th_notify_fd[1]); + base->th_notify_fd[0] = -1; + base->th_notify_fd[1] = -1; + event_debug_unassign(&base->th_notify); + } if (base->evsel->dealloc != NULL) base->evsel->dealloc(base); @@ -794,6 +812,9 @@ event_reinit(struct event_base *base) } } + if (was_notifiable && res == 0) + res = evthread_make_base_notifiable(base); + done: EVBASE_RELEASE_LOCK(base, th_base_lock); return (res);