]> granicus.if.org Git - libevent/commitdiff
signal fixes from scott lamb
authorNiels Provos <provos@gmail.com>
Wed, 28 Feb 2007 04:29:18 +0000 (04:29 +0000)
committerNiels Provos <provos@gmail.com>
Wed, 28 Feb 2007 04:29:18 +0000 (04:29 +0000)
svn:r340

devpoll.c
epoll.c
evport.c
evsignal.h
poll.c
select.c
signal.c
test/regress.c

index 037bb5dc8b3a194c4aab98f45032293224e44768..359946c2f2f3557ae7c81c2f631e31b30d06cf1d 100644 (file)
--- a/devpoll.c
+++ b/devpoll.c
@@ -66,7 +66,6 @@ struct devpollop {
        struct pollfd *events;
        int nevents;
        int dpfd;
-       sigset_t evsigmask;
        struct pollfd *changes;
        int nchanges;
 };
@@ -180,7 +179,7 @@ devpoll_init(void)
                return (NULL);
        }
 
-       evsignal_init(&devpollop->evsigmask);
+       evsignal_init();
 
        return (devpollop);
 }
@@ -209,7 +208,7 @@ devpoll_recalc(struct event_base *base, void *arg, int max)
                devpollop->nfds = nfds;
        }
 
-       return (evsignal_recalc(&devpollop->evsigmask));
+       return (0);
 }
 
 int
@@ -221,9 +220,6 @@ devpoll_dispatch(struct event_base *base, void *arg, struct timeval *tv)
        struct evdevpoll *evdp;
        int i, res, timeout;
 
-       if (evsignal_deliver(&devpollop->evsigmask) == -1)
-               return (-1);
-
        if (devpollop->nchanges)
                devpoll_commit(devpollop);
 
@@ -235,9 +231,6 @@ devpoll_dispatch(struct event_base *base, void *arg, struct timeval *tv)
 
        res = ioctl(devpollop->dpfd, DP_POLL, &dvp);
 
-       if (evsignal_recalc(&devpollop->evsigmask) == -1)
-               return (-1);
-
        if (res == -1) {
                if (errno != EINTR) {
                        event_warn("ioctl: DP_POLL");
@@ -301,7 +294,7 @@ devpoll_add(void *arg, struct event *ev)
        int fd, events;
 
        if (ev->ev_events & EV_SIGNAL)
-               return (evsignal_add(&devpollop->evsigmask, ev));
+               return (evsignal_add(ev));
 
        fd = ev->ev_fd;
        if (fd >= devpollop->nfds) {
@@ -356,7 +349,7 @@ devpoll_del(void *arg, struct event *ev)
        int needwritedelete = 1, needreaddelete = 1;
 
        if (ev->ev_events & EV_SIGNAL)
-               return (evsignal_del(&devpollop->evsigmask, ev));
+               return (evsignal_del(ev));
 
        fd = ev->ev_fd;
        if (fd >= devpollop->nfds)
diff --git a/epoll.c b/epoll.c
index 555596b16caf99f5fb544d299775e30cbb4975e8..0d18d7623e91a83958d4c5b09d3be81719d6ffb3 100644 (file)
--- a/epoll.c
+++ b/epoll.c
@@ -68,7 +68,6 @@ struct epollop {
        struct epoll_event *events;
        int nevents;
        int epfd;
-       sigset_t evsigmask;
 };
 
 void *epoll_init       (void);
@@ -150,7 +149,7 @@ epoll_init(void)
        }
        epollop->nfds = nfiles;
 
-       evsignal_init(&epollop->evsigmask);
+       evsignal_init();
 
        return (epollop);
 }
@@ -179,7 +178,7 @@ epoll_recalc(struct event_base *base, void *arg, int max)
                epollop->nfds = nfds;
        }
 
-       return (evsignal_recalc(&epollop->evsigmask));
+       return (0);
 }
 
 int
@@ -190,15 +189,9 @@ epoll_dispatch(struct event_base *base, void *arg, struct timeval *tv)
        struct evepoll *evep;
        int i, res, timeout;
 
-       if (evsignal_deliver(&epollop->evsigmask) == -1)
-               return (-1);
-
        timeout = tv->tv_sec * 1000 + (tv->tv_usec + 999) / 1000;
        res = epoll_wait(epollop->epfd, events, epollop->nevents, timeout);
 
-       if (evsignal_recalc(&epollop->evsigmask) == -1)
-               return (-1);
-
        if (res == -1) {
                if (errno != EINTR) {
                        event_warn("epoll_wait");
@@ -262,7 +255,7 @@ epoll_add(void *arg, struct event *ev)
        int fd, op, events;
 
        if (ev->ev_events & EV_SIGNAL)
-               return (evsignal_add(&epollop->evsigmask, ev));
+               return (evsignal_add(ev));
 
        fd = ev->ev_fd;
        if (fd >= epollop->nfds) {
@@ -311,7 +304,7 @@ epoll_del(void *arg, struct event *ev)
        int needwritedelete = 1, needreaddelete = 1;
 
        if (ev->ev_events & EV_SIGNAL)
-               return (evsignal_del(&epollop->evsigmask, ev));
+               return (evsignal_del(ev));
 
        fd = ev->ev_fd;
        if (fd >= epollop->nfds)
index 095c17cffe8de3d1f9bb4f6439034f7e0d729654..818385b1cd3f0ffdcbd7be0d3fcafd610b524a9b 100644 (file)
--- a/evport.c
+++ b/evport.c
@@ -117,7 +117,6 @@ struct fd_info {
 
 struct evport_data {
        int             ed_port;        /* event port for system events  */
-       sigset_t        ed_sigmask;     /* for evsignal                  */
        int             ed_nevents;     /* number of allocated fdi's     */
        struct fd_info *ed_fds;         /* allocated fdi table           */
        /* fdi's that we need to reassoc */
@@ -173,7 +172,7 @@ evport_init(void)
        evpd->ed_nevents = DEFAULT_NFDS;
        memset(&evpd->ed_pending, 0, EVENTS_PER_GETN * sizeof(struct fd_info*));
 
-       evsignal_init(&evpd->ed_sigmask);
+       evsignal_init();
 
        return (evpd);
 }
@@ -330,11 +329,6 @@ evport_dispatch(struct event_base *base, void *arg, struct timeval *tv)
                }
        }
 
-       
-
-       if (evsignal_deliver(&epdp->ed_sigmask) == -1)
-               return (-1);
-
        if ((res = port_getn(epdp->ed_port, pevtlist, EVENTS_PER_GETN, 
                    &nevents, &ts)) == -1) {
                if (errno == EINTR) {
@@ -410,9 +404,6 @@ evport_dispatch(struct event_base *base, void *arg, struct timeval *tv)
 
        check_evportop(epdp);
 
-       if (evsignal_recalc(&epdp->ed_sigmask) == -1)
-               return (-1);
-
        return (0);
 }
 
@@ -426,7 +417,7 @@ evport_recalc(struct event_base *base, void *arg, int max)
 {
        struct evport_data *evpd = arg;
        check_evportop(evpd);
-       return (evsignal_recalc(&evpd->ed_sigmask));
+       return (0);
 }
 
 
@@ -448,7 +439,7 @@ evport_add(void *arg, struct event *ev)
         * Delegate, if it's not ours to handle.
         */
        if (ev->ev_events & EV_SIGNAL)
-               return (evsignal_add(&evpd->ed_sigmask, ev));
+               return (evsignal_add(ev));
 
        /*
         * If necessary, grow the file descriptor info table
@@ -489,7 +480,7 @@ evport_del(void *arg, struct event *ev)
         * Delegate, if it's not ours to handle
         */
        if (ev->ev_events & EV_SIGNAL) {
-               return (evsignal_del(&evpd->ed_sigmask, ev));
+               return (evsignal_del(ev));
        }
 
        if (evpd->ed_nevents < ev->ev_fd) {
index 8de27a5cec28b0a0397c9041a1d4c1075fce6879..5b92bd6e55fb14c06c1c098633204b5a350544ec 100644 (file)
 #ifndef _EVSIGNAL_H_
 #define _EVSIGNAL_H_
 
-void evsignal_init(sigset_t *);
+void evsignal_init(void);
 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 *);
+int evsignal_add(struct event *);
+int evsignal_del(struct event *);
 
 #endif /* _EVSIGNAL_H_ */
diff --git a/poll.c b/poll.c
index f0d9a1e228b38b2377c180816081ea5b8d05f1a4..b51c3d465b572d8e2c080b530f4885b501a59512 100644 (file)
--- a/poll.c
+++ b/poll.c
@@ -66,7 +66,6 @@ struct pollop {
        int *idxplus1_by_fd; /* Index into event_set by fd; we add 1 so
                              * that 0 (which is easy to memset) can mean
                              * "no entry." */
-       sigset_t evsigmask;
 };
 
 void *poll_init        (void);
@@ -98,7 +97,7 @@ poll_init(void)
        if (!(pollop = calloc(1, sizeof(struct pollop))))
                return (NULL);
 
-       evsignal_init(&pollop->evsigmask);
+       evsignal_init();
 
        return (pollop);
 }
@@ -111,9 +110,7 @@ poll_init(void)
 int
 poll_recalc(struct event_base *base, void *arg, int max)
 {
-       struct pollop *pop = arg;
-
-       return (evsignal_recalc(&pop->evsigmask));
+       return (0);
 }
 
 #ifdef CHECK_INVARIANTS
@@ -156,17 +153,11 @@ poll_dispatch(struct event_base *base, void *arg, struct timeval *tv)
        int res, i, sec, nfds;
        struct pollop *pop = arg;
 
-       if (evsignal_deliver(&pop->evsigmask) == -1)
-               return (-1);
-
        poll_check_ok(pop);
        sec = tv->tv_sec * 1000 + (tv->tv_usec + 999) / 1000;
        nfds = pop->nfds;
        res = poll(pop->event_set, nfds, sec);
 
-       if (evsignal_recalc(&pop->evsigmask) == -1)
-               return (-1);
-
        if (res == -1) {
                if (errno != EINTR) {
                         event_warn("poll");
@@ -228,7 +219,7 @@ poll_add(void *arg, struct event *ev)
        int i;
 
        if (ev->ev_events & EV_SIGNAL)
-               return (evsignal_add(&pop->evsigmask, ev));
+               return (evsignal_add(ev));
        if (!(ev->ev_events & (EV_READ|EV_WRITE)))
                return (0);
 
@@ -333,7 +324,7 @@ poll_del(void *arg, struct event *ev)
        int i;
 
        if (ev->ev_events & EV_SIGNAL)
-               return (evsignal_del(&pop->evsigmask, ev));
+               return (evsignal_del(ev));
 
        if (!(ev->ev_events & (EV_READ|EV_WRITE)))
                return (0);
index f26ec4544318fb3ace499464fc83944ae3ef3efc..804eacc20c444146d7c648bfd319c4a2552f8638 100644 (file)
--- a/select.c
+++ b/select.c
@@ -68,7 +68,6 @@ struct selectop {
        fd_set *event_writeset_out;
        struct event **event_r_by_fd;
        struct event **event_w_by_fd;
-       sigset_t evsigmask;
 };
 
 void *select_init      (void);
@@ -104,7 +103,7 @@ select_init(void)
 
        select_resize(sop, howmany(32 + 1, NFDBITS)*sizeof(fd_mask));
 
-       evsignal_init(&sop->evsigmask);
+       evsignal_init();
 
        return (sop);
 }
@@ -133,7 +132,7 @@ check_selectop(struct selectop *sop)
 
 }
 #else
-#define check_selectop(sop) do {;} while (0)
+#define check_selectop(sop) do { (void) sop; } while (0)
 #endif
 
 /*
@@ -148,7 +147,7 @@ select_recalc(struct event_base *base, void *arg, int max)
 
        check_selectop(sop);
 
-       return (evsignal_recalc(&sop->evsigmask));
+       return (0);
 }
 
 int
@@ -164,15 +163,10 @@ select_dispatch(struct event_base *base, void *arg, struct timeval *tv)
        memcpy(sop->event_writeset_out, sop->event_writeset_in,
               sop->event_fdsz);
 
-       if (evsignal_deliver(&sop->evsigmask) == -1)
-               return (-1);
-
        res = select(sop->event_fds + 1, sop->event_readset_out,
            sop->event_writeset_out, NULL, tv);
 
        check_selectop(sop);
-       if (evsignal_recalc(&sop->evsigmask) == -1)
-               return (-1);
 
        if (res == -1) {
                if (errno != EINTR) {
@@ -281,7 +275,7 @@ select_add(void *arg, struct event *ev)
        struct selectop *sop = arg;
 
        if (ev->ev_events & EV_SIGNAL)
-               return (evsignal_add(&sop->evsigmask, ev));
+               return (evsignal_add(ev));
 
        check_selectop(sop);
        /*
@@ -332,7 +326,7 @@ select_del(void *arg, struct event *ev)
 
        check_selectop(sop);
        if (ev->ev_events & EV_SIGNAL)
-               return (evsignal_del(&sop->evsigmask, ev));
+               return (evsignal_del(ev));
 
        if (sop->event_fds < ev->ev_fd) {
                check_selectop(sop);
index 7e442713fcc2b29abe20c6c5d752bdea47fb55e9..c9b967ed0b07e8428d088d729ea737842504cca8 100644 (file)
--- a/signal.c
+++ b/signal.c
 extern struct event_list signalqueue;
 
 static sig_atomic_t evsigcaught[NSIG];
-static int needrecalc;
 volatile sig_atomic_t evsignal_caught = 0;
 
 static struct event ev_signal;
 static int ev_signal_pair[2];
 static int ev_signal_added;
 
+static void evsignal_handler(int sig);
+
 /* Callback for when the signal handler write a byte to our signaling socket */
 static void
 evsignal_cb(int fd, short what, void *arg)
@@ -86,10 +87,8 @@ evsignal_cb(int fd, short what, void *arg)
 #endif
 
 void
-evsignal_init(sigset_t *evsigmask)
+evsignal_init(void)
 {
-       sigemptyset(evsigmask);
-
        /* 
         * Our signal handler is going to write to one end of the socket
         * pair to wake up our event loop.  The event loop then scans for
@@ -109,14 +108,27 @@ evsignal_init(sigset_t *evsigmask)
 }
 
 int
-evsignal_add(sigset_t *evsigmask, struct event *ev)
+evsignal_add(struct event *ev)
 {
        int evsignal;
+       struct sigaction sa;
 
        if (ev->ev_events & (EV_READ|EV_WRITE))
                event_errx(1, "%s: EV_SIGNAL incompatible use", __func__);
        evsignal = EVENT_SIGNAL(ev);
-       sigaddset(evsigmask, evsignal);
+
+       memset(&sa, 0, sizeof(sa));
+       sa.sa_handler = evsignal_handler;
+       sigfillset(&sa.sa_mask);
+       sa.sa_flags |= SA_RESTART;
+
+       if (sigaction(evsignal, &sa, NULL) == -1)
+               return (-1);
+
+       if (!ev_signal_added) {
+               ev_signal_added = 1;
+               event_add(&ev_signal, NULL);
+       }
 
        return (0);
 }
@@ -126,13 +138,11 @@ evsignal_add(sigset_t *evsigmask, struct event *ev)
  */
 
 int
-evsignal_del(sigset_t *evsigmask, struct event *ev)
+evsignal_del(struct event *ev)
 {
        int evsignal;
 
        evsignal = EVENT_SIGNAL(ev);
-       sigdelset(evsigmask, evsignal);
-       needrecalc = 1;
 
        return (sigaction(EVENT_SIGNAL(ev),(struct sigaction *)SIG_DFL, NULL));
 }
@@ -150,63 +160,21 @@ evsignal_handler(int sig)
        errno = save_errno;
 }
 
-int
-evsignal_recalc(sigset_t *evsigmask)
-{
-       struct sigaction sa;
-       struct event *ev;
-
-       if (!ev_signal_added) {
-               ev_signal_added = 1;
-               event_add(&ev_signal, NULL);
-       }
-
-       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 = *evsigmask;
-       sa.sa_flags |= SA_RESTART;
-
-       TAILQ_FOREACH(ev, &signalqueue, ev_signal_next) {
-               if (sigaction(EVENT_SIGNAL(ev), &sa, NULL) == -1)
-                       return (-1);
-       }
-       return (0);
-}
-
-int
-evsignal_deliver(sigset_t *evsigmask)
-{
-       if (TAILQ_FIRST(&signalqueue) == NULL)
-               return (0);
-
-       return (sigprocmask(SIG_UNBLOCK, evsigmask, NULL));
-       /* XXX - pending signals handled here */
-}
-
 void
 evsignal_process(void)
 {
        struct event *ev;
        sig_atomic_t ncalls;
 
+       evsignal_caught = 0;
        TAILQ_FOREACH(ev, &signalqueue, ev_signal_next) {
                ncalls = evsigcaught[EVENT_SIGNAL(ev)];
                if (ncalls) {
                        if (!(ev->ev_events & EV_PERSIST))
                                event_del(ev);
                        event_active(ev, EV_SIGNAL, ncalls);
+                       evsigcaught[EVENT_SIGNAL(ev)] = 0;
                }
        }
-
-       memset(evsigcaught, 0, sizeof(evsigcaught));
-       evsignal_caught = 0;
 }
 
index 671a15e79a3f87e8c772e3e300cff7845aa88398..d5e0bc45fd0f970816d70e4747d4e534cac51188 100644 (file)
@@ -451,6 +451,20 @@ test_simplesignal(void)
 
        cleanup_test();
 }
+
+void
+test_immediatesignal(void)
+{
+       struct event ev;
+
+       printf("Immediate signal: ");
+       signal_set(&ev, SIGUSR1, signal_cb, &ev);
+       signal_add(&ev, NULL);
+       raise(SIGUSR1);
+       event_loop(EVLOOP_NONBLOCK);
+       signal_del(&ev);
+       cleanup_test();
+}
 #endif
 
 void
@@ -901,6 +915,7 @@ main (int argc, char **argv)
        test_simpletimeout();
 #ifndef WIN32
        test_simplesignal();
+       test_immediatesignal();
 #endif
        test_loopexit();