From: Niels Provos Date: Sat, 8 Mar 2003 06:37:56 +0000 (+0000) Subject: fix signal usage X-Git-Tag: release-1.1b~124 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=cde7a3528d38baf89b1c1022191397904bec9ed0;p=libevent fix signal usage svn:r45 --- diff --git a/epoll.c b/epoll.c index 95dab907..d0d5f24f 100644 --- a/epoll.c +++ b/epoll.c @@ -58,6 +58,7 @@ #endif #include "event.h" +#include "evsignal.h" extern struct event_list eventqueue; @@ -80,13 +81,6 @@ struct epollop { sigset_t evsigmask; } epollop; -void evsignal_init(sigset_t *); -void evsignal_process(void); -int evsignal_recalc(sigset_t *); -int evsignal_deliver(void); -int evsignal_add(sigset_t *, struct event *); -int evsignal_del(sigset_t *, struct event *); - void *epoll_init (void); int epoll_add (void *, struct event *); int epoll_del (void *, struct event *); @@ -178,7 +172,7 @@ epoll_dispatch(void *arg, struct timeval *tv) struct event *ev; int i, res, timeout; - if (evsignal_deliver() == -1) + if (evsignal_deliver(&epollop->evsigmask) == -1) return (-1); timeout = tv->tv_sec * 1000 + tv->tv_usec / 1000; diff --git a/evsignal.h b/evsignal.h new file mode 100644 index 00000000..630c18f0 --- /dev/null +++ b/evsignal.h @@ -0,0 +1,40 @@ +/* + * Copyright 2000-2002 Niels Provos + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Niels Provos. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _EVSIGNAL_H_ +#define _EVSIGNAL_H_ + +void evsignal_init(sigset_t *); +void evsignal_process(void); +int evsignal_recalc(sigset_t *); +int evsignal_deliver(sigset_t *); +int evsignal_add(sigset_t *, struct event *); +int evsignal_del(sigset_t *, struct event *); + +#endif /* _EVSIGNAL_H_ */ diff --git a/poll.c b/poll.c index 36284059..cda0d394 100644 --- a/poll.c +++ b/poll.c @@ -57,6 +57,7 @@ #endif #include "event.h" +#include "evsignal.h" extern struct event_list eventqueue; @@ -69,13 +70,6 @@ struct pollop { sigset_t evsigmask; } pop; -void evsignal_init(sigset_t *); -void evsignal_process(void); -int evsignal_recalc(sigset_t *); -int evsignal_deliver(void); -int evsignal_add(sigset_t *, struct event *); -int evsignal_del(sigset_t *, struct event *); - void *poll_init (void); int poll_add (void *, struct event *); int poll_del (void *, struct event *); @@ -172,7 +166,7 @@ poll_dispatch(void *arg, struct timeval *tv) } } - if (evsignal_deliver() == -1) + if (evsignal_deliver(&pop->evsigmask) == -1) return (-1); sec = tv->tv_sec * 1000 + tv->tv_usec / 1000; diff --git a/select.c b/select.c index 7749f0c7..870852bd 100644 --- a/select.c +++ b/select.c @@ -56,6 +56,7 @@ #endif #include "event.h" +#include "evsignal.h" extern struct event_list eventqueue; @@ -73,13 +74,6 @@ struct selectop { sigset_t evsigmask; } sop; -void evsignal_init(sigset_t *); -void evsignal_process(void); -int evsignal_recalc(sigset_t *); -int evsignal_deliver(void); -int evsignal_add(sigset_t *, struct event *); -int evsignal_del(sigset_t *, struct event *); - void *select_init (void); int select_add (void *, struct event *); int select_del (void *, struct event *); @@ -174,7 +168,7 @@ select_dispatch(void *arg, struct timeval *tv) FD_SET(ev->ev_fd, sop->event_readset); } - if (evsignal_deliver() == -1) + if (evsignal_deliver(&sop->evsigmask) == -1) return (-1); res = select(sop->event_fds + 1, sop->event_readset, diff --git a/signal.c b/signal.c index 8b638ff0..7fa490ac 100644 --- a/signal.c +++ b/signal.c @@ -55,24 +55,15 @@ #include "event.h" -extern struct event_list timequeue; -extern struct event_list eventqueue; extern struct event_list signalqueue; -short evsigcaught[NSIG]; +static short evsigcaught[NSIG]; +static int needrecalc; volatile sig_atomic_t evsignal_caught = 0; -struct selectop { - int event_fds; /* Highest fd in fd set */ - int event_fdsz; - fd_set *event_readset; - fd_set *event_writeset; - sigset_t evsigmask; -} sop; - void evsignal_process(void); int evsignal_recalc(sigset_t *); -int evsignal_deliver(void); +int evsignal_deliver(sigset_t *); void evsignal_init(sigset_t *evsigmask) @@ -104,6 +95,7 @@ evsignal_del(sigset_t *evsigmask, struct event *ev) signal = EVENT_SIGNAL(ev); sigdelset(evsigmask, signal); + needrecalc = 1; return (sigaction(EVENT_SIGNAL(ev),(struct sigaction *)SIG_DFL, NULL)); } @@ -121,13 +113,17 @@ evsignal_recalc(sigset_t *evsigmask) struct sigaction sa; struct event *ev; + if (TAILQ_FIRST(&signalqueue) == NULL && !needrecalc) + return (0); + needrecalc = 0; + if (sigprocmask(SIG_BLOCK, evsigmask, NULL) == -1) return (-1); /* Reinstall our signal handler. */ memset(&sa, 0, sizeof(sa)); sa.sa_handler = evsignal_handler; - sa.sa_mask = sop.evsigmask; + sa.sa_mask = *evsigmask; sa.sa_flags |= SA_RESTART; TAILQ_FOREACH(ev, &signalqueue, ev_signal_next) { @@ -138,9 +134,12 @@ evsignal_recalc(sigset_t *evsigmask) } int -evsignal_deliver(void) +evsignal_deliver(sigset_t *evsigmask) { - return (sigprocmask(SIG_UNBLOCK, &sop.evsigmask, NULL)); + if (TAILQ_FIRST(&signalqueue) == NULL) + return (0); + + return (sigprocmask(SIG_UNBLOCK, evsigmask, NULL)); /* XXX - pending signals handled here */ }