struct pollfd *events;
int nevents;
int dpfd;
- sigset_t evsigmask;
struct pollfd *changes;
int nchanges;
};
return (NULL);
}
- evsignal_init(&devpollop->evsigmask);
+ evsignal_init();
return (devpollop);
}
devpollop->nfds = nfds;
}
- return (evsignal_recalc(&devpollop->evsigmask));
+ return (0);
}
int
struct evdevpoll *evdp;
int i, res, timeout;
- if (evsignal_deliver(&devpollop->evsigmask) == -1)
- return (-1);
-
if (devpollop->nchanges)
devpoll_commit(devpollop);
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");
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) {
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)
struct epoll_event *events;
int nevents;
int epfd;
- sigset_t evsigmask;
};
void *epoll_init (void);
}
epollop->nfds = nfiles;
- evsignal_init(&epollop->evsigmask);
+ evsignal_init();
return (epollop);
}
epollop->nfds = nfds;
}
- return (evsignal_recalc(&epollop->evsigmask));
+ return (0);
}
int
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");
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) {
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)
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 */
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);
}
}
}
-
-
- 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) {
check_evportop(epdp);
- if (evsignal_recalc(&epdp->ed_sigmask) == -1)
- return (-1);
-
return (0);
}
{
struct evport_data *evpd = arg;
check_evportop(evpd);
- return (evsignal_recalc(&evpd->ed_sigmask));
+ return (0);
}
* 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
* 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) {
#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_ */
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);
if (!(pollop = calloc(1, sizeof(struct pollop))))
return (NULL);
- evsignal_init(&pollop->evsigmask);
+ evsignal_init();
return (pollop);
}
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
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");
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);
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);
fd_set *event_writeset_out;
struct event **event_r_by_fd;
struct event **event_w_by_fd;
- sigset_t evsigmask;
};
void *select_init (void);
select_resize(sop, howmany(32 + 1, NFDBITS)*sizeof(fd_mask));
- evsignal_init(&sop->evsigmask);
+ evsignal_init();
return (sop);
}
}
#else
-#define check_selectop(sop) do {;} while (0)
+#define check_selectop(sop) do { (void) sop; } while (0)
#endif
/*
check_selectop(sop);
- return (evsignal_recalc(&sop->evsigmask));
+ return (0);
}
int
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) {
struct selectop *sop = arg;
if (ev->ev_events & EV_SIGNAL)
- return (evsignal_add(&sop->evsigmask, ev));
+ return (evsignal_add(ev));
check_selectop(sop);
/*
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);
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)
#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
}
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);
}
*/
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));
}
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;
}
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
test_simpletimeout();
#ifndef WIN32
test_simplesignal();
+ test_immediatesignal();
#endif
test_loopexit();