From 763f6a77307f0ff66755f1e0732cb9f7cf3b43c3 Mon Sep 17 00:00:00 2001 From: Niels Provos Date: Thu, 25 Sep 2003 23:18:52 +0000 Subject: [PATCH] proper rtsig svn:r83 --- rtsig.c | 454 +++++++++++++++++++++++++++++--------------------------- 1 file changed, 236 insertions(+), 218 deletions(-) diff --git a/rtsig.c b/rtsig.c index 2674d401..81567f4b 100644 --- a/rtsig.c +++ b/rtsig.c @@ -134,277 +134,295 @@ struct eventop rtsigops = { rtsig_dispatch }; -void *rtsig_init(void) +void * +rtsig_init(void) { - struct rtsigop *op; - - if (getenv("EVENT_NORTSIG")) - return NULL; - - op = malloc(sizeof(*op)); - if (op == NULL) return NULL; - - memset(op, 0, sizeof(*op)); - - op->max = INIT_MAX; - op->poll = malloc(sizeof(*op->poll) * op->max); - if (op->poll == NULL) { - free(op); - return NULL; - } - op->toev = malloc(sizeof(*op->toev) * op->max); - if (op->toev == NULL) { - free(op->poll); - free(op); - return NULL; - } - - sigemptyset(&op->sigs); - sigaddset(&op->sigs, SIGIO); - sigaddset(&op->sigs, SIGRTMIN); - sigprocmask(SIG_BLOCK, &op->sigs, NULL); - return op; + struct rtsigop *op; + + if (getenv("EVENT_NORTSIG")) + return (NULL); + + op = malloc(sizeof(*op)); + if (op == NULL) return (NULL); + + memset(op, 0, sizeof(*op)); + + op->max = INIT_MAX; + op->poll = malloc(sizeof(*op->poll) * op->max); + if (op->poll == NULL) { + free(op); + return (NULL); + } + op->toev = malloc(sizeof(*op->toev) * op->max); + if (op->toev == NULL) { + free(op->poll); + free(op); + return (NULL); + } + + sigemptyset(&op->sigs); + sigaddset(&op->sigs, SIGIO); + sigaddset(&op->sigs, SIGRTMIN); + sigprocmask(SIG_BLOCK, &op->sigs, NULL); + + return (op); } -int rtsig_add(void *arg, struct event *ev) +int +rtsig_add(void *arg, struct event *ev) { - struct rtsigop *op = (struct rtsigop *) arg; - int flags, i; + struct rtsigop *op = (struct rtsigop *) arg; + int flags, i; #ifndef HAVE_WORKING_RTSIG - struct stat st; + struct stat st; #endif - if (ev->ev_events & EV_SIGNAL) { - sigaddset(&op->sigs, EVENT_SIGNAL(ev)); - return sigprocmask(SIG_BLOCK, &op->sigs, NULL); - } + if (ev->ev_events & EV_SIGNAL) { + sigaddset(&op->sigs, EVENT_SIGNAL(ev)); + return sigprocmask(SIG_BLOCK, &op->sigs, NULL); + } - if (!(ev->ev_events & (EV_READ | EV_WRITE))) return 0; + if (!(ev->ev_events & (EV_READ | EV_WRITE))) return 0; #ifndef HAVE_WORKING_RTSIG - if (fstat(ev->ev_fd, &st) == -1) return -1; - if (S_ISFIFO(st.st_mode)) { - ev->ev_flags |= EVLIST_X_NORT; - op->pollmode++; - } + if (fstat(ev->ev_fd, &st) == -1) return -1; + if (S_ISFIFO(st.st_mode)) { + ev->ev_flags |= EVLIST_X_NORT; + op->pollmode++; + } #endif - flags = fcntl(ev->ev_fd, F_GETFL); - if (flags == -1) return -1; + flags = fcntl(ev->ev_fd, F_GETFL); + if (flags == -1) + return (-1); - if (!(flags & O_ASYNC)) { - if (fcntl(ev->ev_fd, F_SETSIG, SIGRTMIN) == -1 - || fcntl(ev->ev_fd, F_SETOWN, (int) getpid()) == -1) - return -1; + if (!(flags & O_ASYNC)) { + if (fcntl(ev->ev_fd, F_SETSIG, SIGRTMIN) == -1 + || fcntl(ev->ev_fd, F_SETOWN, (int) getpid()) == -1) + return (-1); - if (fcntl(ev->ev_fd, F_SETFL, flags | O_ASYNC)) return -1; - } + if (fcntl(ev->ev_fd, F_SETFL, flags | O_ASYNC)) + return (-1); + } #ifdef O_ONESIGFD - fcntl(ev->ev_fd, F_SETAUXFL, O_ONESIGFD); + fcntl(ev->ev_fd, F_SETAUXFL, O_ONESIGFD); #endif - op->total++; - if (poll_add(op, ev) == -1) goto err; + op->total++; + if (poll_add(op, ev) == -1) + goto err; - return 0; + return (0); -err: - i = errno; - fcntl(ev->ev_fd, F_SETFL, flags); - errno = i; - return -1; + err: + i = errno; + fcntl(ev->ev_fd, F_SETFL, flags); + errno = i; + return (-1); } -int rtsig_del(void *arg, struct event *ev) +int +rtsig_del(void *arg, struct event *ev) { - struct rtsigop *op = (struct rtsigop *) arg; + struct rtsigop *op = (struct rtsigop *) arg; - if (ev->ev_events & EV_SIGNAL) { - sigset_t sigs; + if (ev->ev_events & EV_SIGNAL) { + sigset_t sigs; - sigdelset(&op->sigs, EVENT_SIGNAL(ev)); + sigdelset(&op->sigs, EVENT_SIGNAL(ev)); - sigemptyset(&sigs); - sigaddset(&sigs, EVENT_SIGNAL(ev)); - return sigprocmask(SIG_UNBLOCK, &sigs, NULL); - } + sigemptyset(&sigs); + sigaddset(&sigs, EVENT_SIGNAL(ev)); + return (sigprocmask(SIG_UNBLOCK, &sigs, NULL)); + } - if (!(ev->ev_events & (EV_READ | EV_WRITE))) return 0; + if (!(ev->ev_events & (EV_READ | EV_WRITE))) + return (0); #ifndef HAVE_WORKING_RTSIG - if (ev->ev_flags & EVLIST_X_NORT) op->pollmode--; + if (ev->ev_flags & EVLIST_X_NORT) + op->pollmode--; #endif - poll_remove(op, ev); - op->total--; + poll_remove(op, ev); + op->total--; - return 0; + return (0); } -int rtsig_recalc(void *arg, int max) +int +rtsig_recalc(void *arg, int max) { - return 0; + return (0); } -int rtsig_dispatch(void *arg, struct timeval *tv) +int +rtsig_dispatch(void *arg, struct timeval *tv) { - struct rtsigop *op = (struct rtsigop *) arg; - struct timespec ts; - int res, i; + struct rtsigop *op = (struct rtsigop *) arg; + struct timespec ts; + int res, i; - if (op->poll == NULL) goto retry_poll; + if (op->poll == NULL) + goto retry_poll; #ifndef HAVE_WORKING_RTSIG - if (op->pollmode) goto poll_all; + if (op->pollmode) + goto poll_all; #endif - if (op->cur) { - ts.tv_sec = ts.tv_nsec = 0; - } else { - ts.tv_sec = tv->tv_sec; - ts.tv_nsec = tv->tv_usec * 1000; - } - - for (;;) { - siginfo_t info; - struct event *ev; - int signum; - - signum = sigtimedwait(&op->sigs, &info, &ts); - - if (signum == -1) { - if (errno == EAGAIN) break; - return errno == EINTR ? 0 : -1; - } + if (op->cur) { + ts.tv_sec = ts.tv_nsec = 0; + } else { + ts.tv_sec = tv->tv_sec; + ts.tv_nsec = tv->tv_usec * 1000; + } - ts.tv_sec = ts.tv_nsec = 0; - - if (signum == SIGIO) { -poll_all: - free(op->poll); - free(op->toev); -retry_poll: - op->cur = 0; - op->max = op->total; - op->poll = malloc(sizeof(*op->poll) * op->total); - if (op->poll == NULL) return -1; - op->toev = malloc(sizeof(*op->toev) * op->total); - if (op->toev == NULL) { - free(op->poll); - op->poll = NULL; - return -1; - } - - TAILQ_FOREACH(ev, &eventqueue, ev_next) - if (!(ev->ev_flags & EVENT_NORT)) - poll_add(op, ev); + for (;;) { + siginfo_t info; + struct event *ev; + int signum; - break; - } + signum = sigtimedwait(&op->sigs, &info, &ts); - if (signum == SIGRTMIN) { - int flags, i, sigok = 0; - - if (info.si_band <= 0) { /* SI_SIGIO */ - flags = EV_READ | EV_WRITE; - } else { - flags = 0; - if (info.si_band & POLLIN) flags |= EV_READ; - if (info.si_band & POLLOUT) flags |= EV_WRITE; - if (!flags) continue; - } - - for (i = 0; flags && i < op->cur; i++) { - ev = op->toev[i]; - - if (ev->ev_fd == info.si_fd) { - flags &= ~ev->ev_events; - sigok = 1; - } - } - - for (ev = TAILQ_FIRST(&eventqueue); - flags && ev != TAILQ_END(&eventqueue); - ev = TAILQ_NEXT(ev, ev_next)) - { - if (ev->ev_fd == info.si_fd) { - if (flags & ev->ev_events) { - i = poll_add(op, ev); - if (i == -1) return -1; - flags &= ~ev->ev_events; - } - sigok = 1; - } - } - - if (!sigok) { - flags = fcntl(info.si_fd, F_GETFL); - if (flags == -1) return -1; - fcntl(info.si_fd, F_SETFL, flags & ~O_ASYNC); - } - } else { - TAILQ_FOREACH(ev, &signalqueue, ev_signal_next) { - if (EVENT_SIGNAL(ev) == signum) - activate(ev, EV_SIGNAL); - } - } - } + if (signum == -1) { + if (errno == EAGAIN) break; + return errno == EINTR ? 0 : -1; + } - if (!op->cur) return 0; + ts.tv_sec = ts.tv_nsec = 0; - res = poll(op->poll, op->cur, tv->tv_sec * 1000 + tv->tv_usec / 1000); - if (res < 0) return -1; - - i = 0; + if (signum == SIGIO) { +#ifndef HAVE_WORKING_RTSIG + poll_all: +#endif + free(op->poll); + free(op->toev); + retry_poll: + op->cur = 0; + op->max = op->total; + op->poll = malloc(sizeof(*op->poll) * op->total); + if (op->poll == NULL) + return (-1); + op->toev = malloc(sizeof(*op->toev) * op->total); + if (op->toev == NULL) { + free(op->poll); + op->poll = NULL; + return (-1); + } + + TAILQ_FOREACH(ev, &eventqueue, ev_next) + if (!(ev->ev_flags & EVLIST_X_NORT)) + poll_add(op, ev); + + break; + } + + if (signum == SIGRTMIN) { + int flags, i, sigok = 0; + + if (info.si_band <= 0) { /* SI_SIGIO */ + flags = EV_READ | EV_WRITE; + } else { + flags = 0; + if (info.si_band & POLLIN) flags |= EV_READ; + if (info.si_band & POLLOUT) flags |= EV_WRITE; + if (!flags) continue; + } + + for (i = 0; flags && i < op->cur; i++) { + ev = op->toev[i]; + + if (ev->ev_fd == info.si_fd) { + flags &= ~ev->ev_events; + sigok = 1; + } + } + + for (ev = TAILQ_FIRST(&eventqueue); + flags && ev != TAILQ_END(&eventqueue); + ev = TAILQ_NEXT(ev, ev_next)) { + if (ev->ev_fd == info.si_fd) { + if (flags & ev->ev_events) { + i = poll_add(op, ev); + if (i == -1) return -1; + flags &= ~ev->ev_events; + } + sigok = 1; + } + } + + if (!sigok) { + flags = fcntl(info.si_fd, F_GETFL); + if (flags == -1) return -1; + fcntl(info.si_fd, F_SETFL, flags & ~O_ASYNC); + } + } else { + TAILQ_FOREACH(ev, &signalqueue, ev_signal_next) { + if (EVENT_SIGNAL(ev) == signum) + activate(ev, EV_SIGNAL); + } + } + } + + if (!op->cur) + return (0); + + res = poll(op->poll, op->cur, tv->tv_sec * 1000 + tv->tv_usec / 1000); + if (res < 0) + return (-1); + + i = 0; #ifdef HAVE_WORKING_RTSIG - while (i < res) { + while (i < res) { #else - while (i < op->cur) { + while (i < op->cur) { #endif - if (op->poll[i].revents) { - int flags = 0; - struct event *ev = op->toev[i]; - - if (op->poll[i].revents & POLLIN) flags |= EV_READ; - if (op->poll[i].revents & POLLOUT) flags |= EV_WRITE; - - if (!(ev->ev_events & EV_PERSIST)) { - event_del(ev); - res--; - } else { - i++; - } - event_active(ev, flags, 1); - } else { + if (op->poll[i].revents) { + int flags = 0; + struct event *ev = op->toev[i]; + + if (op->poll[i].revents & POLLIN) flags |= EV_READ; + if (op->poll[i].revents & POLLOUT) flags |= EV_WRITE; + + if (!(ev->ev_events & EV_PERSIST)) { + event_del(ev); + res--; + } else { + i++; + } + event_active(ev, flags, 1); + } else { #ifndef HAVE_WORKING_RTSIG - if (op->toev[i]->ev_flags & EVLIST_X_NORT) { - i++; - res++; - continue; - } + if (op->toev[i]->ev_flags & EVLIST_X_NORT) { + i++; + res++; + continue; + } #endif - for (;;) { - op->cur--; - if (i == op->cur) break; - if (op->poll[op->cur].revents) { - memcpy(&op->poll[i], &op->poll[op->cur], sizeof(*op->poll)); - op->toev[i] = op->toev[op->cur]; - break; - } - } - } - } + for (;;) { + op->cur--; + if (i == op->cur) + break; + if (op->poll[op->cur].revents) { + memcpy(&op->poll[i], &op->poll[op->cur], sizeof(*op->poll)); + op->toev[i] = op->toev[op->cur]; + break; + } + } + } + } #ifdef HAVE_WORKING_RTSIG - op->cur = res; + op->cur = res; #endif - if (!op->cur) { - op->max = INIT_MAX; - free(op->poll); - free(op->toev); - /* We just freed it, we shouldn't have a problem getting it back. */ - op->poll = malloc(sizeof(*op->poll) * op->max); - op->toev = malloc(sizeof(*op->toev) * op->max); - } + if (!op->cur) { + op->max = INIT_MAX; + free(op->poll); + free(op->toev); + /* We just freed it, we shouldn't have a problem getting it back. */ + op->poll = malloc(sizeof(*op->poll) * op->max); + op->toev = malloc(sizeof(*op->toev) * op->max); + } - return 0; + return (0); } -- 2.40.0