mirror of
https://github.com/cuberite/libevent.git
synced 2025-09-19 01:04:58 -04:00
signal fixes from scott lamb
svn:r340
This commit is contained in:
parent
127c260bb7
commit
8d94bd03eb
15
devpoll.c
15
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)
|
||||
|
15
epoll.c
15
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)
|
||||
|
17
evport.c
17
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) {
|
||||
|
@ -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_ */
|
||||
|
17
poll.c
17
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);
|
||||
|
16
select.c
16
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);
|
||||
|
74
signal.c
74
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;
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user