summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNiels Provos <provos@gmail.com>2007-02-28 04:29:18 +0000
committerNiels Provos <provos@gmail.com>2007-02-28 04:29:18 +0000
commit8d94bd03ebac666171fbbc75a598ef01f63390f5 (patch)
treed99325c870751dd2560e43bac7f11498634119ee
parent127c260bb7f8e972fffab9bc72bd1f53eae48730 (diff)
downloadlibevent-8d94bd03ebac666171fbbc75a598ef01f63390f5.tar.gz
signal fixes from scott lamb
svn:r340
-rw-r--r--devpoll.c15
-rw-r--r--epoll.c15
-rw-r--r--evport.c17
-rw-r--r--evsignal.h8
-rw-r--r--poll.c17
-rw-r--r--select.c16
-rw-r--r--signal.c74
-rw-r--r--test/regress.c15
8 files changed, 60 insertions, 117 deletions
diff --git a/devpoll.c b/devpoll.c
index 037bb5dc..359946c2 100644
--- 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 555596b1..0d18d762 100644
--- 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)
diff --git a/evport.c b/evport.c
index 095c17cf..818385b1 100644
--- 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) {
diff --git a/evsignal.h b/evsignal.h
index 8de27a5c..5b92bd6e 100644
--- a/evsignal.h
+++ b/evsignal.h
@@ -27,11 +27,9 @@
#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 f0d9a1e2..b51c3d46 100644
--- 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);
diff --git a/select.c b/select.c
index f26ec454..804eacc2 100644
--- 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);
diff --git a/signal.c b/signal.c
index 7e442713..c9b967ed 100644
--- a/signal.c
+++ b/signal.c
@@ -55,13 +55,14 @@
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;
}
diff --git a/test/regress.c b/test/regress.c
index 671a15e7..d5e0bc45 100644
--- a/test/regress.c
+++ b/test/regress.c
@@ -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();