mirror of
https://github.com/cuberite/libevent.git
synced 2025-09-09 20:41:27 -04:00
signal support for kqueue; support of EV_PERSIST flag to event_set
svn:r18
This commit is contained in:
parent
b855bc5500
commit
d10f85dbce
6
event.c
6
event.c
@ -143,6 +143,7 @@ event_process_active(void)
|
|||||||
ev = TAILQ_FIRST(&activequeue)) {
|
ev = TAILQ_FIRST(&activequeue)) {
|
||||||
event_queue_remove(ev, EVLIST_ACTIVE);
|
event_queue_remove(ev, EVLIST_ACTIVE);
|
||||||
|
|
||||||
|
while (ev->ev_ncalls--)
|
||||||
(*ev->ev_callback)(ev->ev_fd, ev->ev_res, ev->ev_arg);
|
(*ev->ev_callback)(ev->ev_fd, ev->ev_res, ev->ev_arg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -324,9 +325,10 @@ event_del(struct event *ev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
event_active(struct event *ev, int res)
|
event_active(struct event *ev, int res, short ncalls)
|
||||||
{
|
{
|
||||||
ev->ev_res = res;
|
ev->ev_res = res;
|
||||||
|
ev->ev_ncalls = ncalls;
|
||||||
event_queue_insert(ev, EVLIST_ACTIVE);
|
event_queue_insert(ev, EVLIST_ACTIVE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -389,7 +391,7 @@ timeout_process(void)
|
|||||||
|
|
||||||
LOG_DBG((LOG_MISC, 60, "timeout_process: call %p",
|
LOG_DBG((LOG_MISC, 60, "timeout_process: call %p",
|
||||||
ev->ev_callback));
|
ev->ev_callback));
|
||||||
event_active(ev, EV_TIMEOUT);
|
event_active(ev, EV_TIMEOUT, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
11
event.h
11
event.h
@ -47,6 +47,7 @@ extern "C" {
|
|||||||
#define EV_READ 0x02
|
#define EV_READ 0x02
|
||||||
#define EV_WRITE 0x04
|
#define EV_WRITE 0x04
|
||||||
#define EV_SIGNAL 0x08
|
#define EV_SIGNAL 0x08
|
||||||
|
#define EV_PERSIST 0x10 /* Persistant event */
|
||||||
|
|
||||||
/* Fix so that ppl dont have to run with <sys/queue.h> */
|
/* Fix so that ppl dont have to run with <sys/queue.h> */
|
||||||
#ifndef TAILQ_ENTRY
|
#ifndef TAILQ_ENTRY
|
||||||
@ -76,6 +77,7 @@ struct event {
|
|||||||
|
|
||||||
int ev_fd;
|
int ev_fd;
|
||||||
short ev_events;
|
short ev_events;
|
||||||
|
short ev_ncalls;
|
||||||
|
|
||||||
struct timeval ev_timeout;
|
struct timeval ev_timeout;
|
||||||
|
|
||||||
@ -128,10 +130,17 @@ void timeout_process(void);
|
|||||||
#define timeout_pending(ev, tv) event_pending(ev, EV_TIMEOUT, tv)
|
#define timeout_pending(ev, tv) event_pending(ev, EV_TIMEOUT, tv)
|
||||||
#define timeout_initialized(ev) ((ev)->ev_flags & EVLIST_INIT)
|
#define timeout_initialized(ev) ((ev)->ev_flags & EVLIST_INIT)
|
||||||
|
|
||||||
|
#define signal_add(ev, tv) event_add(ev, tv)
|
||||||
|
#define signal_set(ev, x, cb, arg) \
|
||||||
|
event_set(ev, x, EV_SIGNAL|EV_PERSIST, cb, arg)
|
||||||
|
#define signal_del(ev) event_del(ev)
|
||||||
|
#define signal_pending(ev, tv) event_pending(ev, EV_SIGNAL, tv)
|
||||||
|
#define signal_initialized(ev) ((ev)->ev_flags & EVLIST_INIT)
|
||||||
|
|
||||||
void event_set(struct event *, int, short, void (*)(int, short, void *), void *);
|
void event_set(struct event *, int, short, void (*)(int, short, void *), void *);
|
||||||
int event_add(struct event *, struct timeval *);
|
int event_add(struct event *, struct timeval *);
|
||||||
int event_del(struct event *);
|
int event_del(struct event *);
|
||||||
void event_active(struct event *, int);
|
void event_active(struct event *, int, short);
|
||||||
|
|
||||||
int event_pending(struct event *, short, struct timeval *);
|
int event_pending(struct event *, short, struct timeval *);
|
||||||
|
|
||||||
|
47
kqueue.c
47
kqueue.c
@ -33,6 +33,7 @@
|
|||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <sys/queue.h>
|
#include <sys/queue.h>
|
||||||
#include <sys/event.h>
|
#include <sys/event.h>
|
||||||
|
#include <signal.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@ -215,12 +216,17 @@ kq_dispatch(void *arg, struct timeval *tv)
|
|||||||
which |= EV_READ;
|
which |= EV_READ;
|
||||||
} else if (events[i].filter == EVFILT_WRITE) {
|
} else if (events[i].filter == EVFILT_WRITE) {
|
||||||
which |= EV_WRITE;
|
which |= EV_WRITE;
|
||||||
|
} else if (events[i].filter == EVFILT_SIGNAL) {
|
||||||
|
which |= EV_SIGNAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (which) {
|
if (which) {
|
||||||
|
if (!(ev->ev_events & EV_PERSIST)) {
|
||||||
ev->ev_flags &= ~EVLIST_X_KQINKERNEL;
|
ev->ev_flags &= ~EVLIST_X_KQINKERNEL;
|
||||||
event_del(ev);
|
event_del(ev);
|
||||||
event_active(ev, which);
|
}
|
||||||
|
event_active(ev, which,
|
||||||
|
ev->ev_events & EV_SIGNAL ? events[i].data : 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -234,6 +240,27 @@ kq_add(void *arg, struct event *ev)
|
|||||||
struct kqop *kqop = arg;
|
struct kqop *kqop = arg;
|
||||||
struct kevent kev;
|
struct kevent kev;
|
||||||
|
|
||||||
|
if (ev->ev_events & EV_SIGNAL) {
|
||||||
|
int nsignal = EVENT_SIGNAL(ev);
|
||||||
|
|
||||||
|
memset(&kev, 0, sizeof(kev));
|
||||||
|
kev.ident = nsignal;
|
||||||
|
kev.filter = EVFILT_SIGNAL;
|
||||||
|
kev.flags = EV_ADD;
|
||||||
|
if (!(ev->ev_events & EV_PERSIST))
|
||||||
|
kev.filter |= EV_ONESHOT;
|
||||||
|
kev.udata = ev;
|
||||||
|
|
||||||
|
if (kq_insert(kqop, &kev) == -1)
|
||||||
|
return (-1);
|
||||||
|
|
||||||
|
if (signal(nsignal, SIG_IGN) == SIG_ERR)
|
||||||
|
return (-1);
|
||||||
|
|
||||||
|
ev->ev_flags |= EVLIST_X_KQINKERNEL;
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
if (ev->ev_events & EV_READ) {
|
if (ev->ev_events & EV_READ) {
|
||||||
memset(&kev, 0, sizeof(kev));
|
memset(&kev, 0, sizeof(kev));
|
||||||
kev.ident = ev->ev_fd;
|
kev.ident = ev->ev_fd;
|
||||||
@ -272,6 +299,24 @@ kq_del(void *arg, struct event *ev)
|
|||||||
if (!(ev->ev_flags & EVLIST_X_KQINKERNEL))
|
if (!(ev->ev_flags & EVLIST_X_KQINKERNEL))
|
||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
|
if (ev->ev_events & EV_SIGNAL) {
|
||||||
|
int nsignal = EVENT_SIGNAL(ev);
|
||||||
|
|
||||||
|
memset(&kev, 0, sizeof(kev));
|
||||||
|
kev.ident = signal;
|
||||||
|
kev.filter = EVFILT_SIGNAL;
|
||||||
|
kev.flags = EV_DELETE;
|
||||||
|
|
||||||
|
if (kq_insert(kqop, &kev) == -1)
|
||||||
|
return (-1);
|
||||||
|
|
||||||
|
if (signal(nsignal, SIG_DFL) == SIG_ERR)
|
||||||
|
return (-1);
|
||||||
|
|
||||||
|
ev->ev_flags &= ~EVLIST_X_KQINKERNEL;
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
if (ev->ev_events & EV_READ) {
|
if (ev->ev_events & EV_READ) {
|
||||||
memset(&kev, 0, sizeof(kev));
|
memset(&kev, 0, sizeof(kev));
|
||||||
kev.ident = ev->ev_fd;
|
kev.ident = ev->ev_fd;
|
||||||
|
@ -41,7 +41,8 @@ main (int argc, char **argv)
|
|||||||
event_init();
|
event_init();
|
||||||
|
|
||||||
/* Initalize one event */
|
/* Initalize one event */
|
||||||
event_set(&signal_int, SIGINT, EV_SIGNAL, signal_cb, &signal_int);
|
event_set(&signal_int, SIGINT, EV_SIGNAL|EV_PERSIST, signal_cb,
|
||||||
|
&signal_int);
|
||||||
|
|
||||||
event_add(&signal_int, NULL);
|
event_add(&signal_int, NULL);
|
||||||
|
|
||||||
|
14
select.c
14
select.c
@ -56,7 +56,7 @@ extern struct event_list signalqueue;
|
|||||||
#define howmany(x, y) (((x)+((y)-1))/(y))
|
#define howmany(x, y) (((x)+((y)-1))/(y))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int evsigcaught[NSIG];
|
short evsigcaught[NSIG];
|
||||||
|
|
||||||
struct selectop {
|
struct selectop {
|
||||||
int event_fds; /* Highest fd in fd set */
|
int event_fds; /* Highest fd in fd set */
|
||||||
@ -192,8 +192,9 @@ select_dispatch(void *arg, struct timeval *tv)
|
|||||||
res &= ev->ev_events;
|
res &= ev->ev_events;
|
||||||
|
|
||||||
if (res) {
|
if (res) {
|
||||||
|
if (!(ev->ev_events & EV_PERSIST))
|
||||||
event_del(ev);
|
event_del(ev);
|
||||||
event_active(ev, res);
|
event_active(ev, res, 1);
|
||||||
} else if (ev->ev_fd > maxfd)
|
} else if (ev->ev_fd > maxfd)
|
||||||
maxfd = ev->ev_fd;
|
maxfd = ev->ev_fd;
|
||||||
}
|
}
|
||||||
@ -291,10 +292,15 @@ void
|
|||||||
signal_process(void)
|
signal_process(void)
|
||||||
{
|
{
|
||||||
struct event *ev;
|
struct event *ev;
|
||||||
|
short ncalls;
|
||||||
|
|
||||||
TAILQ_FOREACH(ev, &signalqueue, ev_signal_next) {
|
TAILQ_FOREACH(ev, &signalqueue, ev_signal_next) {
|
||||||
if (evsigcaught[EVENT_SIGNAL(ev)])
|
ncalls = evsigcaught[EVENT_SIGNAL(ev)];
|
||||||
event_active(ev, EV_SIGNAL);
|
if (ncalls) {
|
||||||
|
if (!(ev->ev_events & EV_PERSIST))
|
||||||
|
event_del(ev);
|
||||||
|
event_active(ev, EV_SIGNAL, ncalls);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(evsigcaught, 0, sizeof(evsigcaught));
|
memset(evsigcaught, 0, sizeof(evsigcaught));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user