mirror of
https://github.com/cuberite/libevent.git
synced 2025-09-12 13:58:58 -04:00
more the signal base into the event base; this removes global state and makes signals
work better with threading; from Wouter Wijngaards small fixes for kqueue and style by me svn:r351
This commit is contained in:
parent
a968da7425
commit
41b7cbc381
@ -81,12 +81,12 @@ struct win32op {
|
|||||||
struct event **events;
|
struct event **events;
|
||||||
};
|
};
|
||||||
|
|
||||||
void *win32_init (void);
|
void *win32_init (struct event_base *);
|
||||||
int win32_insert (void *, struct event *);
|
int win32_insert (void *, struct event *);
|
||||||
int win32_del (void *, struct event *);
|
int win32_del (void *, struct event *);
|
||||||
int win32_recalc (struct event_base *base, void *, int);
|
int win32_recalc (struct event_base *base, void *, int);
|
||||||
int win32_dispatch (struct event_base *base, void *, struct timeval *);
|
int win32_dispatch (struct event_base *base, void *, struct timeval *);
|
||||||
void win32_dealloc (void *);
|
void win32_dealloc (struct event_base *, void *);
|
||||||
|
|
||||||
struct eventop win32ops = {
|
struct eventop win32ops = {
|
||||||
"win32",
|
"win32",
|
||||||
@ -167,7 +167,7 @@ do_fd_clear(struct win32op *op, SOCKET s, int read)
|
|||||||
|
|
||||||
#define NEVENT 64
|
#define NEVENT 64
|
||||||
void *
|
void *
|
||||||
win32_init(void)
|
win32_init(struct event_base *)
|
||||||
{
|
{
|
||||||
struct win32op *winop;
|
struct win32op *winop;
|
||||||
size_t size;
|
size_t size;
|
||||||
@ -376,7 +376,7 @@ win32_dispatch(struct event_base *base, void *op,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
win32_dealloc(void *arg)
|
win32_dealloc(struct event_base *, void *arg)
|
||||||
{
|
{
|
||||||
struct win32op *win32op = arg;
|
struct win32op *win32op = arg;
|
||||||
|
|
||||||
|
20
devpoll.c
20
devpoll.c
@ -50,8 +50,6 @@
|
|||||||
#include "evsignal.h"
|
#include "evsignal.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
|
||||||
extern volatile sig_atomic_t evsignal_caught;
|
|
||||||
|
|
||||||
/* due to limitations in the devpoll interface, we need to keep track of
|
/* due to limitations in the devpoll interface, we need to keep track of
|
||||||
* all file descriptors outself.
|
* all file descriptors outself.
|
||||||
*/
|
*/
|
||||||
@ -70,12 +68,12 @@ struct devpollop {
|
|||||||
int nchanges;
|
int nchanges;
|
||||||
};
|
};
|
||||||
|
|
||||||
void *devpoll_init (void);
|
void *devpoll_init (struct event_base *);
|
||||||
int devpoll_add (void *, struct event *);
|
int devpoll_add (void *, struct event *);
|
||||||
int devpoll_del (void *, struct event *);
|
int devpoll_del (void *, struct event *);
|
||||||
int devpoll_recalc (struct event_base *, void *, int);
|
int devpoll_recalc (struct event_base *, void *, int);
|
||||||
int devpoll_dispatch (struct event_base *, void *, struct timeval *);
|
int devpoll_dispatch (struct event_base *, void *, struct timeval *);
|
||||||
void devpoll_dealloc (void *);
|
void devpoll_dealloc (struct event_base *, void *);
|
||||||
|
|
||||||
struct eventop devpollops = {
|
struct eventop devpollops = {
|
||||||
"devpoll",
|
"devpoll",
|
||||||
@ -126,7 +124,7 @@ devpoll_queue(struct devpollop *devpollop, int fd, int events) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void *
|
void *
|
||||||
devpoll_init(void)
|
devpoll_init(struct event_base *base)
|
||||||
{
|
{
|
||||||
int dpfd, nfiles = NEVENT;
|
int dpfd, nfiles = NEVENT;
|
||||||
struct rlimit rl;
|
struct rlimit rl;
|
||||||
@ -179,7 +177,7 @@ devpoll_init(void)
|
|||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
evsignal_init();
|
evsignal_init(base);
|
||||||
|
|
||||||
return (devpollop);
|
return (devpollop);
|
||||||
}
|
}
|
||||||
@ -237,10 +235,11 @@ devpoll_dispatch(struct event_base *base, void *arg, struct timeval *tv)
|
|||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
evsignal_process();
|
evsignal_process(base);
|
||||||
return (0);
|
return (0);
|
||||||
} else if (evsignal_caught)
|
} else if (base->sig.evsignal_caught) {
|
||||||
evsignal_process();
|
evsignal_process(base);
|
||||||
|
}
|
||||||
|
|
||||||
event_debug(("%s: devpoll_wait reports %d", __func__, res));
|
event_debug(("%s: devpoll_wait reports %d", __func__, res));
|
||||||
|
|
||||||
@ -398,10 +397,11 @@ devpoll_del(void *arg, struct event *ev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
devpoll_dealloc(void *arg)
|
devpoll_dealloc(struct event_base *base, void *arg)
|
||||||
{
|
{
|
||||||
struct devpollop *devpollop = arg;
|
struct devpollop *devpollop = arg;
|
||||||
|
|
||||||
|
evsignal_dealloc(base);
|
||||||
if (devpollop->fds)
|
if (devpollop->fds)
|
||||||
free(devpollop->fds);
|
free(devpollop->fds);
|
||||||
if (devpollop->events)
|
if (devpollop->events)
|
||||||
|
22
epoll.c
22
epoll.c
@ -30,6 +30,7 @@
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
#include <sys/tree.h>
|
||||||
#include <sys/resource.h>
|
#include <sys/resource.h>
|
||||||
#ifdef HAVE_SYS_TIME_H
|
#ifdef HAVE_SYS_TIME_H
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
@ -49,11 +50,10 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "event.h"
|
#include "event.h"
|
||||||
|
#include "event-internal.h"
|
||||||
#include "evsignal.h"
|
#include "evsignal.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
|
||||||
extern volatile sig_atomic_t evsignal_caught;
|
|
||||||
|
|
||||||
/* due to limitations in the epoll interface, we need to keep track of
|
/* due to limitations in the epoll interface, we need to keep track of
|
||||||
* all file descriptors outself.
|
* all file descriptors outself.
|
||||||
*/
|
*/
|
||||||
@ -70,12 +70,12 @@ struct epollop {
|
|||||||
int epfd;
|
int epfd;
|
||||||
};
|
};
|
||||||
|
|
||||||
void *epoll_init (void);
|
void *epoll_init (struct event_base *);
|
||||||
int epoll_add (void *, struct event *);
|
int epoll_add (void *, struct event *);
|
||||||
int epoll_del (void *, struct event *);
|
int epoll_del (void *, struct event *);
|
||||||
int epoll_recalc (struct event_base *, void *, int);
|
int epoll_recalc (struct event_base *, void *, int);
|
||||||
int epoll_dispatch (struct event_base *, void *, struct timeval *);
|
int epoll_dispatch (struct event_base *, void *, struct timeval *);
|
||||||
void epoll_dealloc (void *);
|
void epoll_dealloc (struct event_base *, void *);
|
||||||
|
|
||||||
struct eventop epollops = {
|
struct eventop epollops = {
|
||||||
"epoll",
|
"epoll",
|
||||||
@ -99,7 +99,7 @@ struct eventop epollops = {
|
|||||||
#define NEVENT 32000
|
#define NEVENT 32000
|
||||||
|
|
||||||
void *
|
void *
|
||||||
epoll_init(void)
|
epoll_init(struct event_base *base)
|
||||||
{
|
{
|
||||||
int epfd, nfiles = NEVENT;
|
int epfd, nfiles = NEVENT;
|
||||||
struct rlimit rl;
|
struct rlimit rl;
|
||||||
@ -149,7 +149,7 @@ epoll_init(void)
|
|||||||
}
|
}
|
||||||
epollop->nfds = nfiles;
|
epollop->nfds = nfiles;
|
||||||
|
|
||||||
evsignal_init();
|
evsignal_init(base);
|
||||||
|
|
||||||
return (epollop);
|
return (epollop);
|
||||||
}
|
}
|
||||||
@ -198,10 +198,11 @@ epoll_dispatch(struct event_base *base, void *arg, struct timeval *tv)
|
|||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
evsignal_process();
|
evsignal_process(base);
|
||||||
return (0);
|
return (0);
|
||||||
} else if (evsignal_caught)
|
} else if (base->sig.evsignal_caught) {
|
||||||
evsignal_process();
|
evsignal_process(base);
|
||||||
|
}
|
||||||
|
|
||||||
event_debug(("%s: epoll_wait reports %d", __func__, res));
|
event_debug(("%s: epoll_wait reports %d", __func__, res));
|
||||||
|
|
||||||
@ -346,10 +347,11 @@ epoll_del(void *arg, struct event *ev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
epoll_dealloc(void *arg)
|
epoll_dealloc(struct event_base *base, void *arg)
|
||||||
{
|
{
|
||||||
struct epollop *epollop = arg;
|
struct epollop *epollop = arg;
|
||||||
|
|
||||||
|
evsignal_dealloc(base);
|
||||||
if (epollop->fds)
|
if (epollop->fds)
|
||||||
free(epollop->fds);
|
free(epollop->fds);
|
||||||
if (epollop->events)
|
if (epollop->events)
|
||||||
|
@ -31,6 +31,8 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "evsignal.h"
|
||||||
|
|
||||||
struct event_base {
|
struct event_base {
|
||||||
const struct eventop *evsel;
|
const struct eventop *evsel;
|
||||||
void *evbase;
|
void *evbase;
|
||||||
@ -43,6 +45,9 @@ struct event_base {
|
|||||||
struct event_list **activequeues;
|
struct event_list **activequeues;
|
||||||
int nactivequeues;
|
int nactivequeues;
|
||||||
|
|
||||||
|
/* signal handling info */
|
||||||
|
struct evsignal_info sig;
|
||||||
|
|
||||||
struct event_list eventqueue;
|
struct event_list eventqueue;
|
||||||
struct timeval event_tv;
|
struct timeval event_tv;
|
||||||
|
|
||||||
|
3
event.3
3
event.3
@ -42,6 +42,7 @@
|
|||||||
.Nm event_add ,
|
.Nm event_add ,
|
||||||
.Nm event_del ,
|
.Nm event_del ,
|
||||||
.Nm event_once ,
|
.Nm event_once ,
|
||||||
|
.Nm event_base_once ,
|
||||||
.Nm event_pending ,
|
.Nm event_pending ,
|
||||||
.Nm event_initialized ,
|
.Nm event_initialized ,
|
||||||
.Nm event_priority_init ,
|
.Nm event_priority_init ,
|
||||||
@ -107,6 +108,8 @@
|
|||||||
.Ft int
|
.Ft int
|
||||||
.Fn "event_once" "int fd" "short event" "void (*fn)(int, short, void *)" "void *arg" "struct timeval *tv"
|
.Fn "event_once" "int fd" "short event" "void (*fn)(int, short, void *)" "void *arg" "struct timeval *tv"
|
||||||
.Ft int
|
.Ft int
|
||||||
|
.Fn "event_base_once" "struct event_base *base" "int fd" "short event" "void (*fn)(int, short, void *)" "void *arg" "struct timeval *tv"
|
||||||
|
.Ft int
|
||||||
.Fn "event_pending" "struct event *ev" "short event" "struct timeval *tv"
|
.Fn "event_pending" "struct event *ev" "short event" "struct timeval *tv"
|
||||||
.Ft int
|
.Ft int
|
||||||
.Fn "event_initialized" "struct event *ev"
|
.Fn "event_initialized" "struct event *ev"
|
||||||
|
67
event.c
67
event.c
@ -111,9 +111,8 @@ const struct eventop *eventops[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* Global state */
|
/* Global state */
|
||||||
struct event_list signalqueue;
|
|
||||||
|
|
||||||
struct event_base *current_base = NULL;
|
struct event_base *current_base = NULL;
|
||||||
|
extern struct event_base *evsignal_base;
|
||||||
|
|
||||||
/* Handle signals - This is a deprecated interface */
|
/* Handle signals - This is a deprecated interface */
|
||||||
int (*event_sigcb)(void); /* Signal callback when gotsig is set */
|
int (*event_sigcb)(void); /* Signal callback when gotsig is set */
|
||||||
@ -174,36 +173,40 @@ void *
|
|||||||
event_init(void)
|
event_init(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
struct event_base *base;
|
||||||
|
|
||||||
if ((current_base = calloc(1, sizeof(struct event_base))) == NULL)
|
if ((base = calloc(1, sizeof(struct event_base))) == NULL)
|
||||||
event_err(1, "%s: calloc");
|
event_err(1, "%s: calloc");
|
||||||
|
|
||||||
event_sigcb = NULL;
|
event_sigcb = NULL;
|
||||||
event_gotsig = 0;
|
event_gotsig = 0;
|
||||||
gettime(¤t_base->event_tv);
|
gettime(&base->event_tv);
|
||||||
|
|
||||||
RB_INIT(¤t_base->timetree);
|
RB_INIT(&base->timetree);
|
||||||
TAILQ_INIT(¤t_base->eventqueue);
|
TAILQ_INIT(&base->eventqueue);
|
||||||
TAILQ_INIT(&signalqueue);
|
TAILQ_INIT(&base->sig.signalqueue);
|
||||||
|
base->sig.ev_signal_pair[0] = -1;
|
||||||
|
base->sig.ev_signal_pair[1] = -1;
|
||||||
|
|
||||||
current_base->evbase = NULL;
|
base->evbase = NULL;
|
||||||
for (i = 0; eventops[i] && !current_base->evbase; i++) {
|
for (i = 0; eventops[i] && !base->evbase; i++) {
|
||||||
current_base->evsel = eventops[i];
|
base->evsel = eventops[i];
|
||||||
|
|
||||||
current_base->evbase = current_base->evsel->init();
|
base->evbase = base->evsel->init(base);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (current_base->evbase == NULL)
|
if (base->evbase == NULL)
|
||||||
event_errx(1, "%s: no event mechanism available", __func__);
|
event_errx(1, "%s: no event mechanism available", __func__);
|
||||||
|
|
||||||
if (getenv("EVENT_SHOW_METHOD"))
|
if (getenv("EVENT_SHOW_METHOD"))
|
||||||
event_msgx("libevent using: %s\n",
|
event_msgx("libevent using: %s\n",
|
||||||
current_base->evsel->name);
|
base->evsel->name);
|
||||||
|
|
||||||
/* allocate a single active event queue */
|
/* allocate a single active event queue */
|
||||||
event_base_priority_init(current_base, 1);
|
event_base_priority_init(base, 1);
|
||||||
|
|
||||||
return (current_base);
|
current_base = base;
|
||||||
|
return (base);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -217,7 +220,8 @@ event_base_free(struct event_base *base)
|
|||||||
current_base = NULL;
|
current_base = NULL;
|
||||||
|
|
||||||
assert(base);
|
assert(base);
|
||||||
assert(TAILQ_EMPTY(&base->eventqueue));
|
if (base->evsel->dealloc != NULL)
|
||||||
|
base->evsel->dealloc(base, base->evbase);
|
||||||
for (i=0; i < base->nactivequeues; ++i)
|
for (i=0; i < base->nactivequeues; ++i)
|
||||||
assert(TAILQ_EMPTY(base->activequeues[i]));
|
assert(TAILQ_EMPTY(base->activequeues[i]));
|
||||||
|
|
||||||
@ -227,8 +231,7 @@ event_base_free(struct event_base *base)
|
|||||||
free(base->activequeues[i]);
|
free(base->activequeues[i]);
|
||||||
free(base->activequeues);
|
free(base->activequeues);
|
||||||
|
|
||||||
if (base->evsel->dealloc != NULL)
|
assert(TAILQ_EMPTY(&base->eventqueue));
|
||||||
base->evsel->dealloc(base->evbase);
|
|
||||||
|
|
||||||
free(base);
|
free(base);
|
||||||
}
|
}
|
||||||
@ -343,7 +346,6 @@ event_loopexit_cb(int fd, short what, void *arg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* not thread safe */
|
/* not thread safe */
|
||||||
|
|
||||||
int
|
int
|
||||||
event_loopexit(struct timeval *tv)
|
event_loopexit(struct timeval *tv)
|
||||||
{
|
{
|
||||||
@ -354,7 +356,7 @@ event_loopexit(struct timeval *tv)
|
|||||||
int
|
int
|
||||||
event_base_loopexit(struct event_base *event_base, struct timeval *tv)
|
event_base_loopexit(struct event_base *event_base, struct timeval *tv)
|
||||||
{
|
{
|
||||||
return (event_once(-1, EV_TIMEOUT, event_loopexit_cb,
|
return (event_base_once(event_base, -1, EV_TIMEOUT, event_loopexit_cb,
|
||||||
event_base, tv));
|
event_base, tv));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -374,6 +376,8 @@ event_base_loop(struct event_base *base, int flags)
|
|||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
int res, done;
|
int res, done;
|
||||||
|
|
||||||
|
if(!TAILQ_EMPTY(&base->sig.signalqueue))
|
||||||
|
evsignal_base = base;
|
||||||
done = 0;
|
done = 0;
|
||||||
while (!done) {
|
while (!done) {
|
||||||
/* Calculate the initial events that we are waiting for */
|
/* Calculate the initial events that we are waiting for */
|
||||||
@ -422,6 +426,7 @@ event_base_loop(struct event_base *base, int flags)
|
|||||||
|
|
||||||
res = evsel->dispatch(base, evbase, &tv);
|
res = evsel->dispatch(base, evbase, &tv);
|
||||||
|
|
||||||
|
|
||||||
if (res == -1)
|
if (res == -1)
|
||||||
return (-1);
|
return (-1);
|
||||||
|
|
||||||
@ -459,11 +464,18 @@ event_once_cb(int fd, short events, void *arg)
|
|||||||
free(eonce);
|
free(eonce);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Schedules an event once */
|
/* not threadsafe, event scheduled once. */
|
||||||
|
|
||||||
int
|
int
|
||||||
event_once(int fd, short events,
|
event_once(int fd, short events,
|
||||||
void (*callback)(int, short, void *), void *arg, struct timeval *tv)
|
void (*callback)(int, short, void *), void *arg, struct timeval *tv)
|
||||||
|
{
|
||||||
|
return event_base_once(current_base, fd, events, callback, arg, tv);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Schedules an event once */
|
||||||
|
int
|
||||||
|
event_base_once(struct event_base *base, int fd, short events,
|
||||||
|
void (*callback)(int, short, void *), void *arg, struct timeval *tv)
|
||||||
{
|
{
|
||||||
struct event_once *eonce;
|
struct event_once *eonce;
|
||||||
struct timeval etv;
|
struct timeval etv;
|
||||||
@ -496,7 +508,9 @@ event_once(int fd, short events,
|
|||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
res = event_add(&eonce->ev, tv);
|
res = event_base_set(base, &eonce->ev);
|
||||||
|
if (res == 0)
|
||||||
|
res = event_add(&eonce->ev, tv);
|
||||||
if (res != 0) {
|
if (res != 0) {
|
||||||
free(eonce);
|
free(eonce);
|
||||||
return (res);
|
return (res);
|
||||||
@ -521,7 +535,8 @@ event_set(struct event *ev, int fd, short events,
|
|||||||
ev->ev_pncalls = NULL;
|
ev->ev_pncalls = NULL;
|
||||||
|
|
||||||
/* by default, we put new events into the middle priority */
|
/* by default, we put new events into the middle priority */
|
||||||
ev->ev_pri = current_base->nactivequeues/2;
|
if(current_base)
|
||||||
|
ev->ev_pri = current_base->nactivequeues/2;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
@ -801,7 +816,7 @@ event_queue_remove(struct event_base *base, struct event *ev, int queue)
|
|||||||
ev, ev_active_next);
|
ev, ev_active_next);
|
||||||
break;
|
break;
|
||||||
case EVLIST_SIGNAL:
|
case EVLIST_SIGNAL:
|
||||||
TAILQ_REMOVE(&signalqueue, ev, ev_signal_next);
|
TAILQ_REMOVE(&base->sig.signalqueue, ev, ev_signal_next);
|
||||||
break;
|
break;
|
||||||
case EVLIST_TIMEOUT:
|
case EVLIST_TIMEOUT:
|
||||||
RB_REMOVE(event_tree, &base->timetree, ev);
|
RB_REMOVE(event_tree, &base->timetree, ev);
|
||||||
@ -843,7 +858,7 @@ event_queue_insert(struct event_base *base, struct event *ev, int queue)
|
|||||||
ev,ev_active_next);
|
ev,ev_active_next);
|
||||||
break;
|
break;
|
||||||
case EVLIST_SIGNAL:
|
case EVLIST_SIGNAL:
|
||||||
TAILQ_INSERT_TAIL(&signalqueue, ev, ev_signal_next);
|
TAILQ_INSERT_TAIL(&base->sig.signalqueue, ev, ev_signal_next);
|
||||||
break;
|
break;
|
||||||
case EVLIST_TIMEOUT: {
|
case EVLIST_TIMEOUT: {
|
||||||
struct event *tmp = RB_INSERT(event_tree, &base->timetree, ev);
|
struct event *tmp = RB_INSERT(event_tree, &base->timetree, ev);
|
||||||
|
5
event.h
5
event.h
@ -131,12 +131,12 @@ TAILQ_HEAD (evkeyvalq, evkeyval);
|
|||||||
|
|
||||||
struct eventop {
|
struct eventop {
|
||||||
char *name;
|
char *name;
|
||||||
void *(*init)(void);
|
void *(*init)(struct event_base *);
|
||||||
int (*add)(void *, struct event *);
|
int (*add)(void *, struct event *);
|
||||||
int (*del)(void *, struct event *);
|
int (*del)(void *, struct event *);
|
||||||
int (*recalc)(struct event_base *, void *, int);
|
int (*recalc)(struct event_base *, void *, int);
|
||||||
int (*dispatch)(struct event_base *, void *, struct timeval *);
|
int (*dispatch)(struct event_base *, void *, struct timeval *);
|
||||||
void (*dealloc)(void *);
|
void (*dealloc)(struct event_base *, void *);
|
||||||
};
|
};
|
||||||
|
|
||||||
#define TIMEOUT_DEFAULT {5, 0}
|
#define TIMEOUT_DEFAULT {5, 0}
|
||||||
@ -184,6 +184,7 @@ int event_base_loopexit(struct event_base *, struct timeval *);
|
|||||||
|
|
||||||
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_once(int, short, void (*)(int, short, void *), void *, struct timeval *);
|
int event_once(int, short, void (*)(int, short, void *), void *, struct timeval *);
|
||||||
|
int event_base_once(struct event_base *, int, short, void (*)(int, short, void *), void *, struct timeval *);
|
||||||
|
|
||||||
int event_add(struct event *, struct timeval *);
|
int event_add(struct event *, struct timeval *);
|
||||||
int event_del(struct event *);
|
int event_del(struct event *);
|
||||||
|
14
evport.c
14
evport.c
@ -81,8 +81,6 @@
|
|||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "evsignal.h"
|
#include "evsignal.h"
|
||||||
|
|
||||||
extern volatile sig_atomic_t evsignal_caught;
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Default value for ed_nevents, which is the maximum file descriptor number we
|
* Default value for ed_nevents, which is the maximum file descriptor number we
|
||||||
@ -123,7 +121,7 @@ struct evport_data {
|
|||||||
struct fd_info *ed_pending[EVENTS_PER_GETN];
|
struct fd_info *ed_pending[EVENTS_PER_GETN];
|
||||||
};
|
};
|
||||||
|
|
||||||
static void* evport_init (void);
|
static void* evport_init (struct event_base *);
|
||||||
static int evport_add (void *, struct event *);
|
static int evport_add (void *, struct event *);
|
||||||
static int evport_del (void *, struct event *);
|
static int evport_del (void *, struct event *);
|
||||||
static int evport_recalc (struct event_base *, void *, int);
|
static int evport_recalc (struct event_base *, void *, int);
|
||||||
@ -143,7 +141,7 @@ const struct eventop evportops = {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
static void*
|
static void*
|
||||||
evport_init(void)
|
evport_init(struct event_base *base)
|
||||||
{
|
{
|
||||||
struct evport_data *evpd;
|
struct evport_data *evpd;
|
||||||
/*
|
/*
|
||||||
@ -172,7 +170,7 @@ evport_init(void)
|
|||||||
evpd->ed_nevents = DEFAULT_NFDS;
|
evpd->ed_nevents = DEFAULT_NFDS;
|
||||||
memset(&evpd->ed_pending, 0, EVENTS_PER_GETN * sizeof(struct fd_info*));
|
memset(&evpd->ed_pending, 0, EVENTS_PER_GETN * sizeof(struct fd_info*));
|
||||||
|
|
||||||
evsignal_init();
|
evsignal_init(base);
|
||||||
|
|
||||||
return (evpd);
|
return (evpd);
|
||||||
}
|
}
|
||||||
@ -332,7 +330,7 @@ evport_dispatch(struct event_base *base, void *arg, struct timeval *tv)
|
|||||||
if ((res = port_getn(epdp->ed_port, pevtlist, EVENTS_PER_GETN,
|
if ((res = port_getn(epdp->ed_port, pevtlist, EVENTS_PER_GETN,
|
||||||
&nevents, &ts)) == -1) {
|
&nevents, &ts)) == -1) {
|
||||||
if (errno == EINTR) {
|
if (errno == EINTR) {
|
||||||
evsignal_process();
|
evsignal_process(base);
|
||||||
return (0);
|
return (0);
|
||||||
} else if (errno == ETIME) {
|
} else if (errno == ETIME) {
|
||||||
if (nevents == 0)
|
if (nevents == 0)
|
||||||
@ -341,8 +339,8 @@ evport_dispatch(struct event_base *base, void *arg, struct timeval *tv)
|
|||||||
perror("port_getn");
|
perror("port_getn");
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
} else if (evsignal_caught) {
|
} else if (base->sig.evsignal_caught) {
|
||||||
evsignal_process();
|
evsignal_process(base);
|
||||||
}
|
}
|
||||||
|
|
||||||
event_debug(("%s: port_getn reports %d events", __func__, nevents));
|
event_debug(("%s: port_getn reports %d events", __func__, nevents));
|
||||||
|
13
evsignal.h
13
evsignal.h
@ -27,9 +27,18 @@
|
|||||||
#ifndef _EVSIGNAL_H_
|
#ifndef _EVSIGNAL_H_
|
||||||
#define _EVSIGNAL_H_
|
#define _EVSIGNAL_H_
|
||||||
|
|
||||||
void evsignal_init(void);
|
struct evsignal_info {
|
||||||
void evsignal_process(void);
|
struct event_list signalqueue;
|
||||||
|
struct event ev_signal;
|
||||||
|
int ev_signal_pair[2];
|
||||||
|
int ev_signal_added;
|
||||||
|
volatile sig_atomic_t evsignal_caught;
|
||||||
|
sig_atomic_t evsigcaught[NSIG];
|
||||||
|
};
|
||||||
|
void evsignal_init(struct event_base *);
|
||||||
|
void evsignal_process(struct event_base *);
|
||||||
int evsignal_add(struct event *);
|
int evsignal_add(struct event *);
|
||||||
int evsignal_del(struct event *);
|
int evsignal_del(struct event *);
|
||||||
|
void evsignal_dealloc(struct event_base *);
|
||||||
|
|
||||||
#endif /* _EVSIGNAL_H_ */
|
#endif /* _EVSIGNAL_H_ */
|
||||||
|
8
kqueue.c
8
kqueue.c
@ -69,13 +69,13 @@ struct kqop {
|
|||||||
int kq;
|
int kq;
|
||||||
};
|
};
|
||||||
|
|
||||||
void *kq_init (void);
|
void *kq_init (struct event_base *);
|
||||||
int kq_add (void *, struct event *);
|
int kq_add (void *, struct event *);
|
||||||
int kq_del (void *, struct event *);
|
int kq_del (void *, struct event *);
|
||||||
int kq_recalc (struct event_base *, void *, int);
|
int kq_recalc (struct event_base *, void *, int);
|
||||||
int kq_dispatch (struct event_base *, void *, struct timeval *);
|
int kq_dispatch (struct event_base *, void *, struct timeval *);
|
||||||
int kq_insert (struct kqop *, struct kevent *);
|
int kq_insert (struct kqop *, struct kevent *);
|
||||||
void kq_dealloc (void *);
|
void kq_dealloc (struct event_base *, void *);
|
||||||
|
|
||||||
const struct eventop kqops = {
|
const struct eventop kqops = {
|
||||||
"kqueue",
|
"kqueue",
|
||||||
@ -88,7 +88,7 @@ const struct eventop kqops = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
void *
|
void *
|
||||||
kq_init(void)
|
kq_init(struct event_base *base)
|
||||||
{
|
{
|
||||||
int kq;
|
int kq;
|
||||||
struct kqop *kqueueop;
|
struct kqop *kqueueop;
|
||||||
@ -398,7 +398,7 @@ kq_del(void *arg, struct event *ev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
kq_dealloc(void *arg)
|
kq_dealloc(struct event_base *base, void *arg)
|
||||||
{
|
{
|
||||||
struct kqop *kqop = arg;
|
struct kqop *kqop = arg;
|
||||||
|
|
||||||
|
20
poll.c
20
poll.c
@ -54,8 +54,6 @@
|
|||||||
#include "evsignal.h"
|
#include "evsignal.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
|
||||||
extern volatile sig_atomic_t evsignal_caught;
|
|
||||||
|
|
||||||
struct pollop {
|
struct pollop {
|
||||||
int event_count; /* Highest number alloc */
|
int event_count; /* Highest number alloc */
|
||||||
int nfds; /* Size of event_* */
|
int nfds; /* Size of event_* */
|
||||||
@ -68,12 +66,12 @@ struct pollop {
|
|||||||
* "no entry." */
|
* "no entry." */
|
||||||
};
|
};
|
||||||
|
|
||||||
void *poll_init (void);
|
void *poll_init (struct event_base *);
|
||||||
int poll_add (void *, struct event *);
|
int poll_add (void *, struct event *);
|
||||||
int poll_del (void *, struct event *);
|
int poll_del (void *, struct event *);
|
||||||
int poll_recalc (struct event_base *, void *, int);
|
int poll_recalc (struct event_base *, void *, int);
|
||||||
int poll_dispatch (struct event_base *, void *, struct timeval *);
|
int poll_dispatch (struct event_base *, void *, struct timeval *);
|
||||||
void poll_dealloc (void *);
|
void poll_dealloc (struct event_base *, void *);
|
||||||
|
|
||||||
const struct eventop pollops = {
|
const struct eventop pollops = {
|
||||||
"poll",
|
"poll",
|
||||||
@ -86,7 +84,7 @@ const struct eventop pollops = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
void *
|
void *
|
||||||
poll_init(void)
|
poll_init(struct event_base *base)
|
||||||
{
|
{
|
||||||
struct pollop *pollop;
|
struct pollop *pollop;
|
||||||
|
|
||||||
@ -97,7 +95,7 @@ poll_init(void)
|
|||||||
if (!(pollop = calloc(1, sizeof(struct pollop))))
|
if (!(pollop = calloc(1, sizeof(struct pollop))))
|
||||||
return (NULL);
|
return (NULL);
|
||||||
|
|
||||||
evsignal_init();
|
evsignal_init(base);
|
||||||
|
|
||||||
return (pollop);
|
return (pollop);
|
||||||
}
|
}
|
||||||
@ -164,10 +162,11 @@ poll_dispatch(struct event_base *base, void *arg, struct timeval *tv)
|
|||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
evsignal_process();
|
evsignal_process(base);
|
||||||
return (0);
|
return (0);
|
||||||
} else if (evsignal_caught)
|
} else if (base->sig.evsignal_caught) {
|
||||||
evsignal_process();
|
evsignal_process(base);
|
||||||
|
}
|
||||||
|
|
||||||
event_debug(("%s: poll reports %d", __func__, res));
|
event_debug(("%s: poll reports %d", __func__, res));
|
||||||
|
|
||||||
@ -370,10 +369,11 @@ poll_del(void *arg, struct event *ev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
poll_dealloc(void *arg)
|
poll_dealloc(struct event_base *base, void *arg)
|
||||||
{
|
{
|
||||||
struct pollop *pop = arg;
|
struct pollop *pop = arg;
|
||||||
|
|
||||||
|
evsignal_dealloc(base);
|
||||||
if (pop->event_set)
|
if (pop->event_set)
|
||||||
free(pop->event_set);
|
free(pop->event_set);
|
||||||
if (pop->event_r_back)
|
if (pop->event_r_back)
|
||||||
|
4
rtsig.c
4
rtsig.c
@ -223,7 +223,7 @@ struct rtdata {
|
|||||||
int poll_position;
|
int poll_position;
|
||||||
};
|
};
|
||||||
|
|
||||||
void *rtsig_init(void);
|
void *rtsig_init(struct event_base *);
|
||||||
int rtsig_add(void *, struct event *);
|
int rtsig_add(void *, struct event *);
|
||||||
int rtsig_del(void *, struct event *);
|
int rtsig_del(void *, struct event *);
|
||||||
int rtsig_recalc(struct event_base *, void *, int);
|
int rtsig_recalc(struct event_base *, void *, int);
|
||||||
@ -544,7 +544,7 @@ activate(struct event *ev, int flags)
|
|||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
void *
|
void *
|
||||||
rtsig_init(void)
|
rtsig_init(struct event_base *)
|
||||||
{
|
{
|
||||||
struct rtsigop *op;
|
struct rtsigop *op;
|
||||||
int sockets[2];
|
int sockets[2];
|
||||||
|
22
select.c
22
select.c
@ -57,8 +57,6 @@
|
|||||||
#define howmany(x, y) (((x)+((y)-1))/(y))
|
#define howmany(x, y) (((x)+((y)-1))/(y))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern volatile sig_atomic_t evsignal_caught;
|
|
||||||
|
|
||||||
struct selectop {
|
struct selectop {
|
||||||
int event_fds; /* Highest fd in fd set */
|
int event_fds; /* Highest fd in fd set */
|
||||||
int event_fdsz;
|
int event_fdsz;
|
||||||
@ -70,12 +68,12 @@ struct selectop {
|
|||||||
struct event **event_w_by_fd;
|
struct event **event_w_by_fd;
|
||||||
};
|
};
|
||||||
|
|
||||||
void *select_init (void);
|
void *select_init (struct event_base *);
|
||||||
int select_add (void *, struct event *);
|
int select_add (void *, struct event *);
|
||||||
int select_del (void *, struct event *);
|
int select_del (void *, struct event *);
|
||||||
int select_recalc (struct event_base *, void *, int);
|
int select_recalc (struct event_base *, void *, int);
|
||||||
int select_dispatch (struct event_base *, void *, struct timeval *);
|
int select_dispatch (struct event_base *, void *, struct timeval *);
|
||||||
void select_dealloc (void *);
|
void select_dealloc (struct event_base *, void *);
|
||||||
|
|
||||||
const struct eventop selectops = {
|
const struct eventop selectops = {
|
||||||
"select",
|
"select",
|
||||||
@ -90,7 +88,7 @@ const struct eventop selectops = {
|
|||||||
static int select_resize(struct selectop *sop, int fdsz);
|
static int select_resize(struct selectop *sop, int fdsz);
|
||||||
|
|
||||||
void *
|
void *
|
||||||
select_init(void)
|
select_init(struct event_base *base)
|
||||||
{
|
{
|
||||||
struct selectop *sop;
|
struct selectop *sop;
|
||||||
|
|
||||||
@ -103,7 +101,7 @@ select_init(void)
|
|||||||
|
|
||||||
select_resize(sop, howmany(32 + 1, NFDBITS)*sizeof(fd_mask));
|
select_resize(sop, howmany(32 + 1, NFDBITS)*sizeof(fd_mask));
|
||||||
|
|
||||||
evsignal_init();
|
evsignal_init(base);
|
||||||
|
|
||||||
return (sop);
|
return (sop);
|
||||||
}
|
}
|
||||||
@ -113,7 +111,7 @@ static void
|
|||||||
check_selectop(struct selectop *sop)
|
check_selectop(struct selectop *sop)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
for (i=0;i<=sop->event_fds;++i) {
|
for (i = 0; i <= sop->event_fds; ++i) {
|
||||||
if (FD_ISSET(i, sop->event_readset_in)) {
|
if (FD_ISSET(i, sop->event_readset_in)) {
|
||||||
assert(sop->event_r_by_fd[i]);
|
assert(sop->event_r_by_fd[i]);
|
||||||
assert(sop->event_r_by_fd[i]->ev_events & EV_READ);
|
assert(sop->event_r_by_fd[i]->ev_events & EV_READ);
|
||||||
@ -174,10 +172,11 @@ select_dispatch(struct event_base *base, void *arg, struct timeval *tv)
|
|||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
evsignal_process();
|
evsignal_process(base);
|
||||||
return (0);
|
return (0);
|
||||||
} else if (evsignal_caught)
|
} else if (base->sig.evsignal_caught) {
|
||||||
evsignal_process();
|
evsignal_process(base);
|
||||||
|
}
|
||||||
|
|
||||||
event_debug(("%s: select reports %d", __func__, res));
|
event_debug(("%s: select reports %d", __func__, res));
|
||||||
|
|
||||||
@ -348,10 +347,11 @@ select_del(void *arg, struct event *ev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
select_dealloc(void *arg)
|
select_dealloc(struct event_base *base, void *arg)
|
||||||
{
|
{
|
||||||
struct selectop *sop = arg;
|
struct selectop *sop = arg;
|
||||||
|
|
||||||
|
evsignal_dealloc(base);
|
||||||
if (sop->event_readset_in)
|
if (sop->event_readset_in)
|
||||||
free(sop->event_readset_in);
|
free(sop->event_readset_in);
|
||||||
if (sop->event_writeset_in)
|
if (sop->event_writeset_in)
|
||||||
|
85
signal.c
85
signal.c
@ -31,6 +31,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
#include <sys/tree.h>
|
||||||
#ifdef HAVE_SYS_TIME_H
|
#ifdef HAVE_SYS_TIME_H
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#else
|
#else
|
||||||
@ -47,19 +48,14 @@
|
|||||||
#ifdef HAVE_FCNTL_H
|
#ifdef HAVE_FCNTL_H
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#endif
|
#endif
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
#include "event.h"
|
#include "event.h"
|
||||||
|
#include "event-internal.h"
|
||||||
#include "evsignal.h"
|
#include "evsignal.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
|
||||||
extern struct event_list signalqueue;
|
struct event_base *evsignal_base = NULL;
|
||||||
|
|
||||||
static sig_atomic_t evsigcaught[NSIG];
|
|
||||||
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);
|
static void evsignal_handler(int sig);
|
||||||
|
|
||||||
@ -87,24 +83,27 @@ evsignal_cb(int fd, short what, void *arg)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
void
|
void
|
||||||
evsignal_init(void)
|
evsignal_init(struct event_base *base)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Our signal handler is going to write to one end of the socket
|
* 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
|
* pair to wake up our event loop. The event loop then scans for
|
||||||
* signals that got delivered.
|
* signals that got delivered.
|
||||||
*/
|
*/
|
||||||
if (socketpair(AF_UNIX, SOCK_STREAM, 0, ev_signal_pair) == -1)
|
if (socketpair(AF_UNIX, SOCK_STREAM, 0, base->sig.ev_signal_pair) == -1)
|
||||||
event_err(1, "%s: socketpair", __func__);
|
event_err(1, "%s: socketpair", __func__);
|
||||||
|
|
||||||
FD_CLOSEONEXEC(ev_signal_pair[0]);
|
FD_CLOSEONEXEC(base->sig.ev_signal_pair[0]);
|
||||||
FD_CLOSEONEXEC(ev_signal_pair[1]);
|
FD_CLOSEONEXEC(base->sig.ev_signal_pair[1]);
|
||||||
|
base->sig.evsignal_caught = 0;
|
||||||
|
memset(&base->sig.evsigcaught, 0, sizeof(sig_atomic_t)*NSIG);
|
||||||
|
|
||||||
fcntl(ev_signal_pair[0], F_SETFL, O_NONBLOCK);
|
fcntl(base->sig.ev_signal_pair[0], F_SETFL, O_NONBLOCK);
|
||||||
|
|
||||||
event_set(&ev_signal, ev_signal_pair[1], EV_READ,
|
event_set(&base->sig.ev_signal, base->sig.ev_signal_pair[1], EV_READ,
|
||||||
evsignal_cb, &ev_signal);
|
evsignal_cb, &base->sig.ev_signal);
|
||||||
ev_signal.ev_flags |= EVLIST_INTERNAL;
|
base->sig.ev_signal.ev_base = base;
|
||||||
|
base->sig.ev_signal.ev_flags |= EVLIST_INTERNAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
@ -112,6 +111,7 @@ evsignal_add(struct event *ev)
|
|||||||
{
|
{
|
||||||
int evsignal;
|
int evsignal;
|
||||||
struct sigaction sa;
|
struct sigaction sa;
|
||||||
|
struct event_base *base = ev->ev_base;
|
||||||
|
|
||||||
if (ev->ev_events & (EV_READ|EV_WRITE))
|
if (ev->ev_events & (EV_READ|EV_WRITE))
|
||||||
event_errx(1, "%s: EV_SIGNAL incompatible use", __func__);
|
event_errx(1, "%s: EV_SIGNAL incompatible use", __func__);
|
||||||
@ -121,29 +121,23 @@ evsignal_add(struct event *ev)
|
|||||||
sa.sa_handler = evsignal_handler;
|
sa.sa_handler = evsignal_handler;
|
||||||
sigfillset(&sa.sa_mask);
|
sigfillset(&sa.sa_mask);
|
||||||
sa.sa_flags |= SA_RESTART;
|
sa.sa_flags |= SA_RESTART;
|
||||||
|
/* catch signals if they happen quickly */
|
||||||
|
evsignal_base = base;
|
||||||
|
|
||||||
if (sigaction(evsignal, &sa, NULL) == -1)
|
if (sigaction(evsignal, &sa, NULL) == -1)
|
||||||
return (-1);
|
return (-1);
|
||||||
|
|
||||||
if (!ev_signal_added) {
|
if (!base->sig.ev_signal_added) {
|
||||||
ev_signal_added = 1;
|
base->sig.ev_signal_added = 1;
|
||||||
event_add(&ev_signal, NULL);
|
event_add(&base->sig.ev_signal, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Nothing to be done here.
|
|
||||||
*/
|
|
||||||
|
|
||||||
int
|
int
|
||||||
evsignal_del(struct event *ev)
|
evsignal_del(struct event *ev)
|
||||||
{
|
{
|
||||||
int evsignal;
|
|
||||||
|
|
||||||
evsignal = EVENT_SIGNAL(ev);
|
|
||||||
|
|
||||||
return (sigaction(EVENT_SIGNAL(ev),(struct sigaction *)SIG_DFL, NULL));
|
return (sigaction(EVENT_SIGNAL(ev),(struct sigaction *)SIG_DFL, NULL));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -152,29 +146,50 @@ evsignal_handler(int sig)
|
|||||||
{
|
{
|
||||||
int save_errno = errno;
|
int save_errno = errno;
|
||||||
|
|
||||||
evsigcaught[sig]++;
|
if(evsignal_base == NULL) {
|
||||||
evsignal_caught = 1;
|
event_warn(
|
||||||
|
"%s: received signal %s, but have no base configured",
|
||||||
|
__func__, sig);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
evsignal_base->sig.evsigcaught[sig]++;
|
||||||
|
evsignal_base->sig.evsignal_caught = 1;
|
||||||
|
|
||||||
/* Wake up our notification mechanism */
|
/* Wake up our notification mechanism */
|
||||||
write(ev_signal_pair[0], "a", 1);
|
write(evsignal_base->sig.ev_signal_pair[0], "a", 1);
|
||||||
errno = save_errno;
|
errno = save_errno;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
evsignal_process(void)
|
evsignal_process(struct event_base *base)
|
||||||
{
|
{
|
||||||
struct event *ev;
|
struct event *ev;
|
||||||
sig_atomic_t ncalls;
|
sig_atomic_t ncalls;
|
||||||
|
|
||||||
evsignal_caught = 0;
|
base->sig.evsignal_caught = 0;
|
||||||
TAILQ_FOREACH(ev, &signalqueue, ev_signal_next) {
|
TAILQ_FOREACH(ev, &base->sig.signalqueue, ev_signal_next) {
|
||||||
ncalls = evsigcaught[EVENT_SIGNAL(ev)];
|
ncalls = base->sig.evsigcaught[EVENT_SIGNAL(ev)];
|
||||||
if (ncalls) {
|
if (ncalls) {
|
||||||
if (!(ev->ev_events & EV_PERSIST))
|
if (!(ev->ev_events & EV_PERSIST))
|
||||||
event_del(ev);
|
event_del(ev);
|
||||||
event_active(ev, EV_SIGNAL, ncalls);
|
event_active(ev, EV_SIGNAL, ncalls);
|
||||||
evsigcaught[EVENT_SIGNAL(ev)] = 0;
|
base->sig.evsigcaught[EVENT_SIGNAL(ev)] = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
evsignal_dealloc(struct event_base *base)
|
||||||
|
{
|
||||||
|
if(base->sig.ev_signal_added) {
|
||||||
|
event_del(&base->sig.ev_signal);
|
||||||
|
base->sig.ev_signal_added = 0;
|
||||||
|
}
|
||||||
|
assert(TAILQ_EMPTY(&base->sig.signalqueue));
|
||||||
|
|
||||||
|
close(base->sig.ev_signal_pair[0]);
|
||||||
|
base->sig.ev_signal_pair[0] = -1;
|
||||||
|
close(base->sig.ev_signal_pair[1]);
|
||||||
|
base->sig.ev_signal_pair[1] = -1;
|
||||||
|
}
|
||||||
|
@ -35,6 +35,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
#include <sys/tree.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#ifdef HAVE_SYS_TIME_H
|
#ifdef HAVE_SYS_TIME_H
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
@ -53,6 +54,7 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
#include "event.h"
|
#include "event.h"
|
||||||
|
#include "event-internal.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
|
||||||
#include "regress.h"
|
#include "regress.h"
|
||||||
@ -465,6 +467,96 @@ test_immediatesignal(void)
|
|||||||
signal_del(&ev);
|
signal_del(&ev);
|
||||||
cleanup_test();
|
cleanup_test();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
test_signal_dealloc(void)
|
||||||
|
{
|
||||||
|
/* make sure that signal_event is event_del'ed and pipe closed */
|
||||||
|
struct event ev;
|
||||||
|
struct event_base *base = event_init();
|
||||||
|
printf("Signal dealloc: ");
|
||||||
|
signal_set(&ev, SIGUSR1, signal_cb, &ev);
|
||||||
|
signal_add(&ev, NULL);
|
||||||
|
signal_del(&ev);
|
||||||
|
event_base_free(base);
|
||||||
|
errno = EINTR;
|
||||||
|
if (base->sig.ev_signal_added) {
|
||||||
|
printf("ev_signal not removed (evsignal_dealloc needed) ");
|
||||||
|
test_ok = 0;
|
||||||
|
} else if (close(base->sig.ev_signal_pair[0]) != -1 ||
|
||||||
|
errno != EBADF) {
|
||||||
|
/* fd must be closed, so second close gives -1, EBADF */
|
||||||
|
printf("signal pipe still open (evsignal_dealloc needed) ");
|
||||||
|
test_ok = 0;
|
||||||
|
} else {
|
||||||
|
test_ok = 1;
|
||||||
|
}
|
||||||
|
cleanup_test();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
test_signal_pipeloss(void)
|
||||||
|
{
|
||||||
|
/* make sure that the base1 pipe is closed correctly. */
|
||||||
|
struct event_base *base1, *base2;
|
||||||
|
int pipe1;
|
||||||
|
printf("Signal pipeloss: ");
|
||||||
|
base1 = event_init();
|
||||||
|
pipe1 = base1->sig.ev_signal_pair[0];
|
||||||
|
base2 = event_init();
|
||||||
|
event_base_free(base2);
|
||||||
|
event_base_free(base1);
|
||||||
|
if (close(pipe1) != -1 || errno!=EBADF) {
|
||||||
|
/* fd must be closed, so second close gives -1, EBADF */
|
||||||
|
printf("signal pipe not closed. ");
|
||||||
|
test_ok = 0;
|
||||||
|
} else {
|
||||||
|
test_ok = 1;
|
||||||
|
}
|
||||||
|
cleanup_test();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* make two bases to catch signals, use both of them. this only works
|
||||||
|
* for event mechanisms that use our signal pipe trick. kqueue handles
|
||||||
|
* signals internally, and it looks like the first kqueue always gets the
|
||||||
|
* signal.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
test_signal_switchbase(void)
|
||||||
|
{
|
||||||
|
struct event ev1, ev2;
|
||||||
|
struct event_base *base1, *base2;
|
||||||
|
printf("Signal switchbase: ");
|
||||||
|
base1 = event_init();
|
||||||
|
base2 = event_init();
|
||||||
|
signal_set(&ev1, SIGUSR1, signal_cb, &ev1);
|
||||||
|
signal_set(&ev2, SIGUSR1, signal_cb, &ev2);
|
||||||
|
if (event_base_set(base1, &ev1) ||
|
||||||
|
event_base_set(base2, &ev2) ||
|
||||||
|
event_add(&ev1, NULL) ||
|
||||||
|
event_add(&ev2, NULL)) {
|
||||||
|
fprintf(stderr, "%s: cannot set base, add\n", __func__);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
test_ok = 0;
|
||||||
|
/* can handle signal before loop is called */
|
||||||
|
raise(SIGUSR1);
|
||||||
|
event_base_loop(base2, EVLOOP_NONBLOCK);
|
||||||
|
event_base_loop(base1, EVLOOP_NONBLOCK);
|
||||||
|
if (test_ok) {
|
||||||
|
test_ok = 0;
|
||||||
|
/* set base1 to handle signals */
|
||||||
|
event_base_loop(base1, EVLOOP_NONBLOCK);
|
||||||
|
raise(SIGUSR1);
|
||||||
|
event_base_loop(base1, EVLOOP_NONBLOCK);
|
||||||
|
event_base_loop(base2, EVLOOP_NONBLOCK);
|
||||||
|
}
|
||||||
|
event_base_free(base1);
|
||||||
|
event_base_free(base2);
|
||||||
|
cleanup_test();
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -930,6 +1022,12 @@ main (int argc, char **argv)
|
|||||||
test_multiple_events_for_same_fd();
|
test_multiple_events_for_same_fd();
|
||||||
|
|
||||||
test_want_only_once();
|
test_want_only_once();
|
||||||
|
|
||||||
|
#ifndef WIN32
|
||||||
|
test_signal_dealloc();
|
||||||
|
test_signal_pipeloss();
|
||||||
|
test_signal_switchbase();
|
||||||
|
#endif
|
||||||
|
|
||||||
evtag_test();
|
evtag_test();
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user