mirror of
https://github.com/libevent/libevent.git
synced 2025-01-31 09:12:55 +08:00
signal support for kqueue; support of EV_PERSIST flag to event_set
svn:r18
This commit is contained in:
parent
b855bc5500
commit
d10f85dbce
8
event.c
8
event.c
@ -143,7 +143,8 @@ event_process_active(void)
|
||||
ev = TAILQ_FIRST(&activequeue)) {
|
||||
event_queue_remove(ev, EVLIST_ACTIVE);
|
||||
|
||||
(*ev->ev_callback)(ev->ev_fd, ev->ev_res, ev->ev_arg);
|
||||
while (ev->ev_ncalls--)
|
||||
(*ev->ev_callback)(ev->ev_fd, ev->ev_res, ev->ev_arg);
|
||||
}
|
||||
}
|
||||
|
||||
@ -324,9 +325,10 @@ event_del(struct event *ev)
|
||||
}
|
||||
|
||||
void
|
||||
event_active(struct event *ev, int res)
|
||||
event_active(struct event *ev, int res, short ncalls)
|
||||
{
|
||||
ev->ev_res = res;
|
||||
ev->ev_ncalls = ncalls;
|
||||
event_queue_insert(ev, EVLIST_ACTIVE);
|
||||
}
|
||||
|
||||
@ -389,7 +391,7 @@ timeout_process(void)
|
||||
|
||||
LOG_DBG((LOG_MISC, 60, "timeout_process: call %p",
|
||||
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_WRITE 0x04
|
||||
#define EV_SIGNAL 0x08
|
||||
#define EV_PERSIST 0x10 /* Persistant event */
|
||||
|
||||
/* Fix so that ppl dont have to run with <sys/queue.h> */
|
||||
#ifndef TAILQ_ENTRY
|
||||
@ -76,6 +77,7 @@ struct event {
|
||||
|
||||
int ev_fd;
|
||||
short ev_events;
|
||||
short ev_ncalls;
|
||||
|
||||
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_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 *);
|
||||
int event_add(struct event *, struct timeval *);
|
||||
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 *);
|
||||
|
||||
|
51
kqueue.c
51
kqueue.c
@ -33,6 +33,7 @@
|
||||
#include <sys/time.h>
|
||||
#include <sys/queue.h>
|
||||
#include <sys/event.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
@ -215,12 +216,17 @@ kq_dispatch(void *arg, struct timeval *tv)
|
||||
which |= EV_READ;
|
||||
} else if (events[i].filter == EVFILT_WRITE) {
|
||||
which |= EV_WRITE;
|
||||
} else if (events[i].filter == EVFILT_SIGNAL) {
|
||||
which |= EV_SIGNAL;
|
||||
}
|
||||
|
||||
if (which) {
|
||||
ev->ev_flags &= ~EVLIST_X_KQINKERNEL;
|
||||
event_del(ev);
|
||||
event_active(ev, which);
|
||||
if (!(ev->ev_events & EV_PERSIST)) {
|
||||
ev->ev_flags &= ~EVLIST_X_KQINKERNEL;
|
||||
event_del(ev);
|
||||
}
|
||||
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 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) {
|
||||
memset(&kev, 0, sizeof(kev));
|
||||
kev.ident = ev->ev_fd;
|
||||
@ -272,6 +299,24 @@ kq_del(void *arg, struct event *ev)
|
||||
if (!(ev->ev_flags & EVLIST_X_KQINKERNEL))
|
||||
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) {
|
||||
memset(&kev, 0, sizeof(kev));
|
||||
kev.ident = ev->ev_fd;
|
||||
|
@ -41,7 +41,8 @@ main (int argc, char **argv)
|
||||
event_init();
|
||||
|
||||
/* 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);
|
||||
|
||||
|
16
select.c
16
select.c
@ -56,7 +56,7 @@ extern struct event_list signalqueue;
|
||||
#define howmany(x, y) (((x)+((y)-1))/(y))
|
||||
#endif
|
||||
|
||||
int evsigcaught[NSIG];
|
||||
short evsigcaught[NSIG];
|
||||
|
||||
struct selectop {
|
||||
int event_fds; /* Highest fd in fd set */
|
||||
@ -192,8 +192,9 @@ select_dispatch(void *arg, struct timeval *tv)
|
||||
res &= ev->ev_events;
|
||||
|
||||
if (res) {
|
||||
event_del(ev);
|
||||
event_active(ev, res);
|
||||
if (!(ev->ev_events & EV_PERSIST))
|
||||
event_del(ev);
|
||||
event_active(ev, res, 1);
|
||||
} else if (ev->ev_fd > maxfd)
|
||||
maxfd = ev->ev_fd;
|
||||
}
|
||||
@ -291,10 +292,15 @@ void
|
||||
signal_process(void)
|
||||
{
|
||||
struct event *ev;
|
||||
short ncalls;
|
||||
|
||||
TAILQ_FOREACH(ev, &signalqueue, ev_signal_next) {
|
||||
if (evsigcaught[EVENT_SIGNAL(ev)])
|
||||
event_active(ev, EV_SIGNAL);
|
||||
ncalls = evsigcaught[EVENT_SIGNAL(ev)];
|
||||
if (ncalls) {
|
||||
if (!(ev->ev_events & EV_PERSIST))
|
||||
event_del(ev);
|
||||
event_active(ev, EV_SIGNAL, ncalls);
|
||||
}
|
||||
}
|
||||
|
||||
memset(evsigcaught, 0, sizeof(evsigcaught));
|
||||
|
Loading…
x
Reference in New Issue
Block a user