From: Nick Mathewson Date: Fri, 22 May 2009 14:48:40 +0000 (+0000) Subject: Try to contain the failure when we are running without socketpair(). X-Git-Tag: release-2.0.3-alpha~216 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=8c66eb2e9b13e409cda3b296d292c3def1c20cd1;p=libevent Try to contain the failure when we are running without socketpair(). Some win32 systems (mostly those using Kaspersky, it would seem) prevent us from faking socketpair(). This makes our signal notification code just not work. Our response since 1.4 has been to assert. For users who would rather work without signals than not work at all, this has been a regression from 1.3e. This patch makes adding signal events fail in this case; there's no reason to kill the whole process. svn:r1303 --- diff --git a/ChangeLog b/ChangeLog index 939a2693..fe5077fa 100644 --- a/ChangeLog +++ b/ChangeLog @@ -32,6 +32,8 @@ Changes in 2.0.2-alpha: o Add a new evbuffer_peek() interface to inspect data in an evbuffer without removing it. o Fix a deadlock when suspending reads in a bufferevent due to a full buffer. (Spotted by Joachim Bauch.) o Fix a memory error when freeing a thread-enabled event base with registered events. (Spotted by Joachim Bauch.) + o Try to contain degree of failure when running on a win32 version so heavily firewalled that we can't fake a socketpair. + Changes in 2.0.1-alpha: o free minheap on event_base_free(); from Christopher Layne diff --git a/WIN32-Code/win32.c b/WIN32-Code/win32.c index b2dcc959..aa73192f 100644 --- a/WIN32-Code/win32.c +++ b/WIN32-Code/win32.c @@ -70,6 +70,7 @@ struct win32op { struct win_fd_set *readset_out; struct win_fd_set *writeset_out; struct win_fd_set *exset_out; + unsigned signals_are_broken : 1; }; static void *win32_init (struct event_base *); @@ -203,7 +204,8 @@ win32_init(struct event_base *_base) winop->readset_out->fd_count = winop->writeset_out->fd_count = winop->exset_out->fd_count = 0; - evsig_init(_base); + if (evsig_init(_base) < 0) + winop->signals_are_broken = 1; return (winop); err: @@ -223,6 +225,9 @@ win32_add(struct event_base *base, evutil_socket_t fd, struct win32op *win32op = base->evbase; struct idx_info *idx = _idx; + if ((events & EV_SIGNAL) && win32op->signals_are_broken) + return (-1); + if (!(events & (EV_READ|EV_WRITE))) return (0); diff --git a/evsignal-internal.h b/evsignal-internal.h index e706f920..00ef89e0 100644 --- a/evsignal-internal.h +++ b/evsignal-internal.h @@ -47,7 +47,7 @@ struct evsig_info { #endif int sh_old_max; }; -void evsig_init(struct event_base *); +int evsig_init(struct event_base *); void evsig_process(struct event_base *); void evsig_dealloc(struct event_base *); diff --git a/signal.c b/signal.c index 15f0dd01..2bbfeb44 100644 --- a/signal.c +++ b/signal.c @@ -108,7 +108,7 @@ evsig_cb(evutil_socket_t fd, short what, void *arg) #define FD_CLOSEONEXEC(x) #endif -void +int evsig_init(struct event_base *base) { /* @@ -117,8 +117,16 @@ evsig_init(struct event_base *base) * signals that got delivered. */ if (evutil_socketpair( - AF_UNIX, SOCK_STREAM, 0, base->sig.ev_signal_pair) == -1) + AF_UNIX, SOCK_STREAM, 0, base->sig.ev_signal_pair) == -1) { +#ifdef WIN32 + /* Make this nonfatal on win32, where sometimes people + have localhost firewalled. */ + event_sock_warn(1, -1, "%s: socketpair", __func__); +#else event_sock_err(1, -1, "%s: socketpair", __func__); +#endif + return -1; + } FD_CLOSEONEXEC(base->sig.ev_signal_pair[0]); FD_CLOSEONEXEC(base->sig.ev_signal_pair[1]); @@ -136,6 +144,8 @@ evsig_init(struct event_base *base) base->evsigsel = &evsigops; base->evsigbase = &base->sig; + + return 0; } /* Helper: set the signal handler for evsignal to handler in base, so that