From: Nick Mathewson Date: Thu, 20 Sep 2007 18:26:46 +0000 (+0000) Subject: r15217@catbus: nickm | 2007-09-20 14:04:32 -0400 X-Git-Tag: release-2.0.1-alpha~561 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f0e06d75e50913ce9786a675ff69dee68d41c3f5;p=libevent r15217@catbus: nickm | 2007-09-20 14:04:32 -0400 Fix win32 signals: teach win32 that we have per-base signal queues; teach signal.c that not everybody has sigaction(). svn:r442 --- diff --git a/WIN32-Code/win32.c b/WIN32-Code/win32.c index 44be2bce..282b6e89 100644 --- a/WIN32-Code/win32.c +++ b/WIN32-Code/win32.c @@ -52,7 +52,9 @@ extern struct event_list timequeue; extern struct event_list addqueue; +#if 0 extern struct event_list signalqueue; +#endif struct win_fd_set { u_int fd_count; @@ -64,10 +66,12 @@ volatile sig_atomic_t signal_caught = 0; /* MSDN says this is required to handle SIGFPE */ volatile double SIGFPE_REQ = 0.0f; +#if 0 static void signal_handler(int sig); void signal_process(void); int signal_recalc(void); +#endif struct win32op { int fd_setsz; @@ -193,6 +197,8 @@ win32_init(struct event_base *_base) winop->readset_out->fd_count = winop->writeset_out->fd_count = winop->exset_out->fd_count = 0; + evsignal_init(_base); + return (winop); err: XFREE(winop->readset_in); @@ -208,7 +214,10 @@ win32_init(struct event_base *_base) int win32_recalc(struct event_base *base, void *arg, int max) { - return (signal_recalc()); +#if 0 + return (evsignal_recalc()); +#endif + return (0); } int @@ -218,13 +227,7 @@ win32_insert(void *op, struct event *ev) int i; if (ev->ev_events & EV_SIGNAL) { - if (ev->ev_events & (EV_READ|EV_WRITE)) - event_errx(1, "%s: EV_SIGNAL incompatible use", - __func__); - if((int)signal(EVENT_SIGNAL(ev), signal_handler) == -1) - return (-1); - - return (0); + return (evsignal_add(ev)); } if (!(ev->ev_events & (EV_READ|EV_WRITE))) return (0); @@ -265,7 +268,7 @@ win32_del(void *op, struct event *ev) int i, found; if (ev->ev_events & EV_SIGNAL) - return ((int)signal(EVENT_SIGNAL(ev), SIG_IGN)); + return (evsignal_del(ev)); found = -1; for (i=0;in_events;++i) { @@ -330,7 +333,7 @@ win32_dispatch(struct event_base *base, void *op, if (!fd_count) { /* Windows doesn't like you to call select() with no sockets */ Sleep(timeval_to_ms(tv)); - signal_process(); + evsignal_process(base); return (0); } @@ -342,8 +345,10 @@ win32_dispatch(struct event_base *base, void *op, event_debug(("%s: select returned %d", __func__, res)); if(res <= 0) { - signal_process(); + evsignal_process(base); return res; + } else if (base->sig.evsignal_caught) { + evsignal_process(base); } for (i=0;in_events;++i) { @@ -369,8 +374,10 @@ win32_dispatch(struct event_base *base, void *op, event_active(ev,got,1); } +#if 0 if (signal_recalc() == -1) return (-1); +#endif return (0); } @@ -380,6 +387,7 @@ win32_dealloc(struct event_base *_base, void *arg) { struct win32op *win32op = arg; + evsignal_dealloc(_base); if (win32op->readset_in) free(win32op->readset_in); if (win32op->writeset_in) @@ -397,6 +405,7 @@ win32_dealloc(struct event_base *_base, void *arg) free(win32op); } +#if 0 static void signal_handler(int sig) { @@ -435,3 +444,5 @@ signal_process(void) memset(evsigcaught, 0, sizeof(evsigcaught)); signal_caught = 0; } +#endif + diff --git a/configure.in b/configure.in index 99de01d7..2bfc1771 100644 --- a/configure.in +++ b/configure.in @@ -135,7 +135,7 @@ AC_C_INLINE AC_HEADER_TIME dnl Checks for library functions. -AC_CHECK_FUNCS(gettimeofday vasprintf fcntl clock_gettime strtok_r strsep getaddrinfo getnameinfo strlcpy inet_ntop) +AC_CHECK_FUNCS(gettimeofday vasprintf fcntl clock_gettime strtok_r strsep getaddrinfo getnameinfo strlcpy inet_ntop signal sigaction) if test "x$ac_cv_func_clock_gettime" = "xyes"; then AC_DEFINE(DNS_USE_CPU_CLOCK_FOR_ID, 1, [Define if clock_gettime is available in libc]) @@ -333,6 +333,12 @@ if test "x$haveeventports" = "xyes" ; then AC_LIBOBJ(evport) needsignal=yes fi +if test "x$bwin32" = "xtrue"; then + needsignal=yes +fi +if test "x$bwin32" = "xtrue"; then + needsignal=yes +fi if test "x$needsignal" = "xyes" ; then AC_LIBOBJ(signal) fi diff --git a/signal.c b/signal.c index 6c0953d9..b8cb6890 100644 --- a/signal.c +++ b/signal.c @@ -30,6 +30,12 @@ #include "config.h" #endif +#ifdef WIN32 +#define WIN32_LEAN_AND_MEAN +#include +#include +#undef WIN32_LEAN_AND_MEAN +#endif #include #include #ifdef HAVE_SYS_TIME_H @@ -38,7 +44,9 @@ #include #endif #include +#ifdef HAVE_SYS_SOCKET_H #include +#endif #include #include #include @@ -53,6 +61,7 @@ #include "event.h" #include "event-internal.h" #include "evsignal.h" +#include "evutil.h" #include "log.h" struct event_base *evsignal_base = NULL; @@ -67,7 +76,7 @@ evsignal_cb(int fd, short what, void *arg) struct event *ev = arg; ssize_t n; - n = read(fd, signals, sizeof(signals)); + n = recv(fd, signals, sizeof(signals), 0); if (n == -1) event_err(1, "%s: read", __func__); event_add(ev, NULL); @@ -90,7 +99,7 @@ evsignal_init(struct event_base *base) * pair to wake up our event loop. The event loop then scans for * signals that got delivered. */ - if (socketpair(AF_UNIX, SOCK_STREAM, 0, base->sig.ev_signal_pair) == -1) + if (evutil_socketpair(AF_UNIX, SOCK_STREAM, 0, base->sig.ev_signal_pair) == -1) event_err(1, "%s: socketpair", __func__); FD_CLOSEONEXEC(base->sig.ev_signal_pair[0]); @@ -98,7 +107,7 @@ evsignal_init(struct event_base *base) base->sig.evsignal_caught = 0; memset(&base->sig.evsigcaught, 0, sizeof(sig_atomic_t)*NSIG); - fcntl(base->sig.ev_signal_pair[0], F_SETFL, O_NONBLOCK); + evutil_make_socket_nonblocking(base->sig.ev_signal_pair[0]); event_set(&base->sig.ev_signal, base->sig.ev_signal_pair[1], EV_READ, evsignal_cb, &base->sig.ev_signal); @@ -110,13 +119,16 @@ int evsignal_add(struct event *ev) { int evsignal; +#ifdef HAVE_SIGACTION struct sigaction sa; +#endif struct event_base *base = ev->ev_base; if (ev->ev_events & (EV_READ|EV_WRITE)) event_errx(1, "%s: EV_SIGNAL incompatible use", __func__); evsignal = EVENT_SIGNAL(ev); +#ifdef HAVE_SIGACTION memset(&sa, 0, sizeof(sa)); sa.sa_handler = evsignal_handler; sigfillset(&sa.sa_mask); @@ -126,6 +138,11 @@ evsignal_add(struct event *ev) if (sigaction(evsignal, &sa, NULL) == -1) return (-1); +#else + evsignal_base = base; + if (signal(evsignal, evsignal_handler) == SIG_ERR) + return (-1); +#endif if (!base->sig.ev_signal_added) { base->sig.ev_signal_added = 1; @@ -138,7 +155,11 @@ evsignal_add(struct event *ev) int evsignal_del(struct event *ev) { +#ifdef HAVE_SIGACTION return (sigaction(EVENT_SIGNAL(ev),(struct sigaction *)SIG_DFL, NULL)); +#else + return (signal(EVENT_SIGNAL(ev),SIG_DFL))==SIG_ERR ? -1 : 0; +#endif } static void @@ -156,8 +177,12 @@ evsignal_handler(int sig) evsignal_base->sig.evsigcaught[sig]++; evsignal_base->sig.evsignal_caught = 1; +#ifndef HAVE_SIGACTION + signal(sig, evsignal_handler); +#endif + /* Wake up our notification mechanism */ - write(evsignal_base->sig.ev_signal_pair[0], "a", 1); + send(evsignal_base->sig.ev_signal_pair[0], "a", 1, 0); errno = save_errno; } @@ -188,8 +213,8 @@ evsignal_dealloc(struct event_base *base) } assert(TAILQ_EMPTY(&base->sig.signalqueue)); - close(base->sig.ev_signal_pair[0]); + EVUTIL_CLOSESOCKET(base->sig.ev_signal_pair[0]); base->sig.ev_signal_pair[0] = -1; - close(base->sig.ev_signal_pair[1]); + EVUTIL_CLOSESOCKET(base->sig.ev_signal_pair[1]); base->sig.ev_signal_pair[1] = -1; }