mirror of
https://github.com/libevent/libevent.git
synced 2025-01-31 09:12:55 +08:00
from trunk: separate signal events from io events
svn:r761
This commit is contained in:
parent
bfdf56c22e
commit
974a75431d
@ -8,6 +8,7 @@ Changes in 1.4.4-stable:
|
||||
o introduce bufferevent_setcb and bufferevent_setfd to allow better manipulation of bufferevents
|
||||
o use libevent's internal timercmp on all platforms, to avoid bugs on old platforms where timercmp(a,b,<=) is buggy.
|
||||
o reduce system calls for getting current time by caching it.
|
||||
o separate signal events from io events; making the code less complex.
|
||||
|
||||
|
||||
Changes in 1.4.3-stable:
|
||||
|
@ -35,6 +35,16 @@ extern "C" {
|
||||
#include "min_heap.h"
|
||||
#include "evsignal.h"
|
||||
|
||||
/* map union members back */
|
||||
|
||||
/* mutually exclusive */
|
||||
#define ev_next _ev.ev_io.ev_next
|
||||
#define ev_signal_next _ev.ev_signal.ev_signal_next
|
||||
|
||||
/* used only by signals */
|
||||
#define ev_ncalls _ev.ev_signal.ev_ncalls
|
||||
#define ev_pncalls _ev.ev_signal.ev_pncalls
|
||||
|
||||
struct eventop {
|
||||
const char *name;
|
||||
void *(*init)(struct event_base *);
|
||||
|
76
event.c
76
event.c
@ -125,6 +125,8 @@ static int timeout_next(struct event_base *, struct timeval **);
|
||||
static void timeout_process(struct event_base *);
|
||||
static void timeout_correct(struct event_base *, struct timeval *);
|
||||
|
||||
static void event_signal_closure(struct event_base *, struct event *ev);
|
||||
|
||||
static void
|
||||
detect_monotonic(void)
|
||||
{
|
||||
@ -333,6 +335,23 @@ event_haveevents(struct event_base *base)
|
||||
return (base->event_count > 0);
|
||||
}
|
||||
|
||||
static void
|
||||
event_signal_closure(struct event_base *base, struct event *ev)
|
||||
{
|
||||
short ncalls;
|
||||
|
||||
/* Allows deletes to work */
|
||||
ncalls = ev->ev_ncalls;
|
||||
ev->ev_pncalls = &ncalls;
|
||||
while (ncalls) {
|
||||
ncalls--;
|
||||
ev->ev_ncalls = ncalls;
|
||||
(*ev->ev_callback)((int)ev->ev_fd, ev->ev_res, ev->ev_arg);
|
||||
if (event_gotsig || base->event_break)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Active events are stored in priority queues. Lower priorities are always
|
||||
* process before higher priorities. Low priority events can starve high
|
||||
@ -345,7 +364,6 @@ event_process_active(struct event_base *base)
|
||||
struct event *ev;
|
||||
struct event_list *activeq = NULL;
|
||||
int i;
|
||||
short ncalls;
|
||||
|
||||
for (i = 0; i < base->nactivequeues; ++i) {
|
||||
if (TAILQ_FIRST(base->activequeues[i]) != NULL) {
|
||||
@ -362,16 +380,13 @@ event_process_active(struct event_base *base)
|
||||
else
|
||||
event_del(ev);
|
||||
|
||||
/* Allows deletes to work */
|
||||
ncalls = ev->ev_ncalls;
|
||||
ev->ev_pncalls = &ncalls;
|
||||
while (ncalls) {
|
||||
ncalls--;
|
||||
ev->ev_ncalls = ncalls;
|
||||
(*ev->ev_callback)((int)ev->ev_fd, ev->ev_res, ev->ev_arg);
|
||||
if (event_gotsig || base->event_break)
|
||||
return;
|
||||
}
|
||||
if (ev->ev_closure != NULL)
|
||||
(*ev->ev_closure)(base, ev);
|
||||
else
|
||||
(*ev->ev_callback)(
|
||||
(int)ev->ev_fd, ev->ev_res, ev->ev_arg);
|
||||
if (event_gotsig || base->event_break)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@ -619,6 +634,15 @@ event_set(struct event *ev, int fd, short events,
|
||||
ev->ev_ncalls = 0;
|
||||
ev->ev_pncalls = NULL;
|
||||
|
||||
if (events & EV_SIGNAL) {
|
||||
if ((events & (EV_READ|EV_WRITE)) != 0)
|
||||
event_errx(1, "%s: EV_SIGNAL incompatible use",
|
||||
__func__);
|
||||
ev->ev_closure = event_signal_closure;
|
||||
} else {
|
||||
ev->ev_closure = NULL;
|
||||
}
|
||||
|
||||
min_heap_elem_init(ev);
|
||||
|
||||
/* by default, we put new events into the middle priority */
|
||||
@ -721,12 +745,14 @@ event_add(struct event *ev, struct timeval *tv)
|
||||
* removes it from the active list. */
|
||||
if ((ev->ev_flags & EVLIST_ACTIVE) &&
|
||||
(ev->ev_res & EV_TIMEOUT)) {
|
||||
/* See if we are just active executing this
|
||||
* event in a loop
|
||||
*/
|
||||
if (ev->ev_ncalls && ev->ev_pncalls) {
|
||||
/* Abort loop */
|
||||
*ev->ev_pncalls = 0;
|
||||
if (ev->ev_flags & EVLIST_SIGNAL) {
|
||||
/* See if we are just active executing
|
||||
* this event in a loop
|
||||
*/
|
||||
if (ev->ev_ncalls && ev->ev_pncalls) {
|
||||
/* Abort loop */
|
||||
*ev->ev_pncalls = 0;
|
||||
}
|
||||
}
|
||||
|
||||
event_queue_remove(base, ev, EVLIST_ACTIVE);
|
||||
@ -782,9 +808,11 @@ event_del(struct event *ev)
|
||||
assert(!(ev->ev_flags & ~EVLIST_ALL));
|
||||
|
||||
/* See if we are just active executing this event in a loop */
|
||||
if (ev->ev_ncalls && ev->ev_pncalls) {
|
||||
/* Abort loop */
|
||||
*ev->ev_pncalls = 0;
|
||||
if (ev->ev_flags & EVLIST_SIGNAL) {
|
||||
if (ev->ev_ncalls && ev->ev_pncalls) {
|
||||
/* Abort loop */
|
||||
*ev->ev_pncalls = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (ev->ev_flags & EVLIST_TIMEOUT)
|
||||
@ -814,8 +842,12 @@ event_active(struct event *ev, int res, short ncalls)
|
||||
}
|
||||
|
||||
ev->ev_res = res;
|
||||
ev->ev_ncalls = ncalls;
|
||||
ev->ev_pncalls = NULL;
|
||||
|
||||
if (ev->ev_flags & EVLIST_SIGNAL) {
|
||||
ev->ev_ncalls = ncalls;
|
||||
ev->ev_pncalls = NULL;
|
||||
}
|
||||
|
||||
event_queue_insert(ev->ev_base, ev, EVLIST_ACTIVE);
|
||||
}
|
||||
|
||||
|
23
event.h
23
event.h
@ -210,22 +210,35 @@ struct { \
|
||||
|
||||
struct event_base;
|
||||
struct event {
|
||||
TAILQ_ENTRY (event) ev_next;
|
||||
TAILQ_ENTRY (event) ev_active_next;
|
||||
TAILQ_ENTRY (event) ev_signal_next;
|
||||
TAILQ_ENTRY (event) (ev_active_next);
|
||||
unsigned int min_heap_idx; /* for managing timeouts */
|
||||
|
||||
struct event_base *ev_base;
|
||||
|
||||
int ev_fd;
|
||||
union {
|
||||
/* used by io events */
|
||||
struct {
|
||||
TAILQ_ENTRY (event) (ev_next);
|
||||
} ev_io;
|
||||
|
||||
/* used by signal events */
|
||||
struct {
|
||||
TAILQ_ENTRY (event) (ev_signal_next);
|
||||
short ev_ncalls;
|
||||
/* Allows deletes in callback */
|
||||
short *ev_pncalls;
|
||||
} ev_signal;
|
||||
} _ev;
|
||||
|
||||
short ev_events;
|
||||
short ev_ncalls;
|
||||
short *ev_pncalls; /* Allows deletes in callback */
|
||||
|
||||
struct timeval ev_timeout;
|
||||
|
||||
int ev_pri; /* smaller numbers are higher priority */
|
||||
|
||||
/* allows us to adopt for different types of events */
|
||||
void (*ev_closure)(struct event_base *, struct event *);
|
||||
void (*ev_callback)(int, short, void *arg);
|
||||
void *ev_arg;
|
||||
|
||||
|
2
signal.c
2
signal.c
@ -186,8 +186,6 @@ evsignal_add(struct event *ev)
|
||||
struct event_base *base = ev->ev_base;
|
||||
struct evsignal_info *sig = &ev->ev_base->sig;
|
||||
|
||||
if (ev->ev_events & (EV_READ|EV_WRITE))
|
||||
event_errx(1, "%s: EV_SIGNAL incompatible use", __func__);
|
||||
evsignal = EVENT_SIGNAL(ev);
|
||||
|
||||
event_debug(("%s: %p: changing signal handler", __func__, ev));
|
||||
|
Loading…
x
Reference in New Issue
Block a user