aboutsummaryrefslogtreecommitdiff
path: root/libevent
diff options
context:
space:
mode:
authorMax Laier <mlaier@FreeBSD.org>2008-12-10 21:08:42 +0000
committerMax Laier <mlaier@FreeBSD.org>2008-12-10 21:08:42 +0000
commit89a3159080a774bd9de50eaf1861a1f0c1657a9f (patch)
treec096fbed43e7e27c693d9c76d395f03a6c790ac2 /libevent
parenta13f3058fbd67e3bbda784171bacc8343faf6edf (diff)
Import OPENBSD_4_4_BASE and libevent 1.3evendor/pf/4.4
Notes
Notes: svn path=/vendor/pf/dist/; revision=185882 svn path=/vendor/pf/4.4/; revision=185883; tag=vendor/pf/4.4
Diffstat (limited to 'libevent')
-rw-r--r--libevent/buffer.c22
-rw-r--r--libevent/event-internal.h5
-rw-r--r--libevent/event.c170
-rw-r--r--libevent/event.h41
-rw-r--r--libevent/evsignal.h13
-rw-r--r--libevent/kqueue.c32
-rw-r--r--libevent/poll.c29
-rw-r--r--libevent/select.c25
-rw-r--r--libevent/signal.c85
9 files changed, 258 insertions, 164 deletions
diff --git a/libevent/buffer.c b/libevent/buffer.c
index 77efd0cfa3e2..0327eb549383 100644
--- a/libevent/buffer.c
+++ b/libevent/buffer.c
@@ -44,6 +44,7 @@
#include <sys/ioctl.h>
#endif
+#include <assert.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
@@ -106,7 +107,7 @@ evbuffer_add_buffer(struct evbuffer *outbuf, struct evbuffer *inbuf)
/*
* Optimization comes with a price; we need to notify the
* buffer if necessary of the changes. oldoff is the amount
- * of data that we tranfered from inbuf to outbuf
+ * of data that we transfered from inbuf to outbuf
*/
if (inbuf->off != oldoff && inbuf->cb != NULL)
(*inbuf->cb)(inbuf, oldoff, inbuf->off, inbuf->cbarg);
@@ -134,9 +135,13 @@ evbuffer_add_vprintf(struct evbuffer *buf, const char *fmt, va_list ap)
int sz;
va_list aq;
+ /* make sure that at least some space is available */
+ evbuffer_expand(buf, 64);
for (;;) {
+ size_t used = buf->misalign + buf->off;
buffer = (char *)buf->buffer + buf->off;
- space = buf->totallen - buf->misalign - buf->off;
+ assert(buf->totallen >= used);
+ space = buf->totallen - used;
#ifndef va_copy
#define va_copy(dst, src) memcpy(&(dst), &(src), sizeof(va_list))
@@ -152,7 +157,7 @@ evbuffer_add_vprintf(struct evbuffer *buf, const char *fmt, va_list ap)
va_end(aq);
- if (sz == -1)
+ if (sz < 0)
return (-1);
if (sz < space) {
buf->off += sz;
@@ -244,7 +249,7 @@ evbuffer_readline(struct evbuffer *buffer)
/* Adds data to an event buffer */
-static inline void
+static void
evbuffer_align(struct evbuffer *buf)
{
memmove(buf->orig_buffer, buf->buffer, buf->off);
@@ -431,13 +436,12 @@ evbuffer_write(struct evbuffer *buffer, int fd)
u_char *
evbuffer_find(struct evbuffer *buffer, const u_char *what, size_t len)
{
- size_t remain = buffer->off;
- u_char *search = buffer->buffer;
+ u_char *search = buffer->buffer, *end = search + buffer->off;
u_char *p;
- while ((p = memchr(search, *what, remain)) != NULL) {
- remain = buffer->off - (size_t)(search - buffer->buffer);
- if (remain < len)
+ while (search < end &&
+ (p = memchr(search, *what, end - search)) != NULL) {
+ if (p + len > end)
break;
if (memcmp(p, what, len) == 0)
return (p);
diff --git a/libevent/event-internal.h b/libevent/event-internal.h
index becb6691d52a..7fd4b6c690f3 100644
--- a/libevent/event-internal.h
+++ b/libevent/event-internal.h
@@ -31,6 +31,8 @@
extern "C" {
#endif
+#include "evsignal.h"
+
struct event_base {
const struct eventop *evsel;
void *evbase;
@@ -43,6 +45,9 @@ struct event_base {
struct event_list **activequeues;
int nactivequeues;
+ /* signal handling info */
+ struct evsignal_info sig;
+
struct event_list eventqueue;
struct timeval event_tv;
diff --git a/libevent/event.c b/libevent/event.c
index f6d2b1cc42ca..15bf14cf3b48 100644
--- a/libevent/event.c
+++ b/libevent/event.c
@@ -51,6 +51,7 @@
#include <signal.h>
#include <string.h>
#include <assert.h>
+#include <time.h>
#include "event.h"
#include "event-internal.h"
@@ -111,9 +112,9 @@ const struct eventop *eventops[] = {
};
/* Global state */
-struct event_list signalqueue;
-
struct event_base *current_base = NULL;
+extern struct event_base *evsignal_base;
+static int use_monotonic;
/* Handle signals - This is a deprecated interface */
int (*event_sigcb)(void); /* Signal callback when gotsig is set */
@@ -126,7 +127,7 @@ static int event_haveevents(struct event_base *);
static void event_process_active(struct event_base *);
-static int timeout_next(struct event_base *, struct timeval *);
+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 *);
@@ -144,25 +145,34 @@ compare(struct event *a, struct event *b)
return (0);
}
+static void
+detect_monotonic(void)
+{
+#if defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC)
+ struct timespec ts;
+
+ if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0)
+ use_monotonic = 1;
+#endif
+}
+
static int
gettime(struct timeval *tp)
{
-#ifdef HAVE_CLOCK_GETTIME
+#if defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC)
struct timespec ts;
-#ifdef HAVE_CLOCK_MONOTONIC
- if (clock_gettime(CLOCK_MONOTONIC, &ts) == -1)
-#else
- if (clock_gettime(CLOCK_REALTIME, &ts) == -1)
-#endif
- return (-1);
- tp->tv_sec = ts.tv_sec;
- tp->tv_usec = ts.tv_nsec / 1000;
-#else
- gettimeofday(tp, NULL);
+ if (use_monotonic) {
+ if (clock_gettime(CLOCK_MONOTONIC, &ts) == -1)
+ return (-1);
+
+ tp->tv_sec = ts.tv_sec;
+ tp->tv_usec = ts.tv_nsec / 1000;
+ return (0);
+ }
#endif
- return (0);
+ return (gettimeofday(tp, NULL));
}
RB_PROTOTYPE(event_tree, event, ev_timeout_node, compare);
@@ -174,36 +184,42 @@ void *
event_init(void)
{
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_sigcb = NULL;
event_gotsig = 0;
- gettime(&current_base->event_tv);
+
+ detect_monotonic();
+ gettime(&base->event_tv);
- RB_INIT(&current_base->timetree);
- TAILQ_INIT(&current_base->eventqueue);
- TAILQ_INIT(&signalqueue);
+ RB_INIT(&base->timetree);
+ TAILQ_INIT(&base->eventqueue);
+ TAILQ_INIT(&base->sig.signalqueue);
+ base->sig.ev_signal_pair[0] = -1;
+ base->sig.ev_signal_pair[1] = -1;
- current_base->evbase = NULL;
- for (i = 0; eventops[i] && !current_base->evbase; i++) {
- current_base->evsel = eventops[i];
+ base->evbase = NULL;
+ for (i = 0; eventops[i] && !base->evbase; 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__);
if (getenv("EVENT_SHOW_METHOD"))
event_msgx("libevent using: %s\n",
- current_base->evsel->name);
+ base->evsel->name);
/* 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
@@ -217,7 +233,8 @@ event_base_free(struct event_base *base)
current_base = NULL;
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)
assert(TAILQ_EMPTY(base->activequeues[i]));
@@ -227,8 +244,7 @@ event_base_free(struct event_base *base)
free(base->activequeues[i]);
free(base->activequeues);
- if (base->evsel->dealloc != NULL)
- base->evsel->dealloc(base->evbase);
+ assert(TAILQ_EMPTY(&base->eventqueue));
free(base);
}
@@ -343,7 +359,6 @@ event_loopexit_cb(int fd, short what, void *arg)
}
/* not thread safe */
-
int
event_loopexit(struct timeval *tv)
{
@@ -354,7 +369,7 @@ event_loopexit(struct timeval *tv)
int
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));
}
@@ -372,8 +387,13 @@ event_base_loop(struct event_base *base, int flags)
const struct eventop *evsel = base->evsel;
void *evbase = base->evbase;
struct timeval tv;
+ struct timeval *tv_p;
int res, done;
+#ifndef WIN32
+ if(!TAILQ_EMPTY(&base->sig.signalqueue))
+ evsignal_base = base;
+#endif
done = 0;
while (!done) {
/* Calculate the initial events that we are waiting for */
@@ -398,21 +418,18 @@ event_base_loop(struct event_base *base, int flags)
}
}
- /* Check if time is running backwards */
- gettime(&tv);
- if (timercmp(&tv, &base->event_tv, <)) {
- struct timeval off;
- event_debug(("%s: time is running backwards, corrected",
- __func__));
- timersub(&base->event_tv, &tv, &off);
- timeout_correct(base, &off);
- }
- base->event_tv = tv;
+ timeout_correct(base, &tv);
- if (!base->event_count_active && !(flags & EVLOOP_NONBLOCK))
- timeout_next(base, &tv);
- else
+ tv_p = &tv;
+ if (!base->event_count_active && !(flags & EVLOOP_NONBLOCK)) {
+ timeout_next(base, &tv_p);
+ } else {
+ /*
+ * if we have active events, we just poll new events
+ * without waiting.
+ */
timerclear(&tv);
+ }
/* If we have no events, we just exit */
if (!event_haveevents(base)) {
@@ -420,7 +437,8 @@ event_base_loop(struct event_base *base, int flags)
return (1);
}
- res = evsel->dispatch(base, evbase, &tv);
+ res = evsel->dispatch(base, evbase, tv_p);
+
if (res == -1)
return (-1);
@@ -459,12 +477,19 @@ event_once_cb(int fd, short events, void *arg)
free(eonce);
}
-/* Schedules an event once */
-
+/* not threadsafe, event scheduled once. */
int
event_once(int fd, short events,
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 timeval etv;
int res;
@@ -496,7 +521,9 @@ event_once(int fd, short events,
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) {
free(eonce);
return (res);
@@ -516,12 +543,14 @@ event_set(struct event *ev, int fd, short events,
ev->ev_arg = arg;
ev->ev_fd = fd;
ev->ev_events = events;
+ ev->ev_res = 0;
ev->ev_flags = EVLIST_INIT;
ev->ev_ncalls = 0;
ev->ev_pncalls = NULL;
/* 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
@@ -710,16 +739,16 @@ event_active(struct event *ev, int res, short ncalls)
event_queue_insert(ev->ev_base, ev, EVLIST_ACTIVE);
}
-int
-timeout_next(struct event_base *base, struct timeval *tv)
+static int
+timeout_next(struct event_base *base, struct timeval **tv_p)
{
- struct timeval dflt = TIMEOUT_DEFAULT;
-
struct timeval now;
struct event *ev;
+ struct timeval *tv = *tv_p;
if ((ev = RB_MIN(event_tree, &base->timetree)) == NULL) {
- *tv = dflt;
+ /* if no time-based events are active wait for I/O */
+ *tv_p = NULL;
return (0);
}
@@ -740,17 +769,38 @@ timeout_next(struct event_base *base, struct timeval *tv)
return (0);
}
+/*
+ * Determines if the time is running backwards by comparing the current
+ * time against the last time we checked. Not needed when using clock
+ * monotonic.
+ */
+
static void
-timeout_correct(struct event_base *base, struct timeval *off)
+timeout_correct(struct event_base *base, struct timeval *tv)
{
struct event *ev;
+ struct timeval off;
+
+ if (use_monotonic)
+ return;
+
+ /* Check if time is running backwards */
+ gettime(tv);
+ if (timercmp(tv, &base->event_tv, >=)) {
+ base->event_tv = *tv;
+ return;
+ }
+
+ event_debug(("%s: time is running backwards, corrected",
+ __func__));
+ timersub(&base->event_tv, tv, &off);
/*
* We can modify the key element of the node without destroying
* the key, beause we apply it to all in the right order.
*/
RB_FOREACH(ev, event_tree, &base->timetree)
- timersub(&ev->ev_timeout, off, &ev->ev_timeout);
+ timersub(&ev->ev_timeout, &off, &ev->ev_timeout);
}
void
@@ -801,7 +851,7 @@ event_queue_remove(struct event_base *base, struct event *ev, int queue)
ev, ev_active_next);
break;
case EVLIST_SIGNAL:
- TAILQ_REMOVE(&signalqueue, ev, ev_signal_next);
+ TAILQ_REMOVE(&base->sig.signalqueue, ev, ev_signal_next);
break;
case EVLIST_TIMEOUT:
RB_REMOVE(event_tree, &base->timetree, ev);
@@ -843,7 +893,7 @@ event_queue_insert(struct event_base *base, struct event *ev, int queue)
ev,ev_active_next);
break;
case EVLIST_SIGNAL:
- TAILQ_INSERT_TAIL(&signalqueue, ev, ev_signal_next);
+ TAILQ_INSERT_TAIL(&base->sig.signalqueue, ev, ev_signal_next);
break;
case EVLIST_TIMEOUT: {
struct event *tmp = RB_INSERT(event_tree, &base->timetree, ev);
diff --git a/libevent/event.h b/libevent/event.h
index 3f2032dd068e..4c39939cc501 100644
--- a/libevent/event.h
+++ b/libevent/event.h
@@ -31,6 +31,8 @@
extern "C" {
#endif
+#include <sys/time.h>
+#include <stdint.h>
#include <stdarg.h>
#ifdef WIN32
@@ -131,16 +133,14 @@ TAILQ_HEAD (evkeyvalq, evkeyval);
struct eventop {
char *name;
- void *(*init)(void);
+ void *(*init)(struct event_base *);
int (*add)(void *, struct event *);
int (*del)(void *, struct event *);
int (*recalc)(struct event_base *, void *, int);
int (*dispatch)(struct event_base *, void *, struct timeval *);
- void (*dealloc)(void *);
+ void (*dealloc)(struct event_base *, void *);
};
-#define TIMEOUT_DEFAULT {5, 0}
-
void *event_init(void);
int event_dispatch(void);
int event_base_dispatch(struct event_base *);
@@ -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 *);
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_del(struct event *);
@@ -299,39 +300,37 @@ void evbuffer_setcb(struct evbuffer *, void (*)(struct evbuffer *, size_t, size_
void evtag_init(void);
-void evtag_marshal(struct evbuffer *evbuf, u_int8_t tag, const void *data,
- u_int32_t len);
+void evtag_marshal(struct evbuffer *evbuf, uint8_t tag, const void *data,
+ uint32_t len);
-void encode_int(struct evbuffer *evbuf, u_int32_t number);
+void encode_int(struct evbuffer *evbuf, uint32_t number);
-void evtag_marshal_int(struct evbuffer *evbuf, u_int8_t tag,
- u_int32_t integer);
+void evtag_marshal_int(struct evbuffer *evbuf, uint8_t tag, uint32_t integer);
-void evtag_marshal_string(struct evbuffer *buf, u_int8_t tag,
+void evtag_marshal_string(struct evbuffer *buf, uint8_t tag,
const char *string);
-void evtag_marshal_timeval(struct evbuffer *evbuf, u_int8_t tag,
+void evtag_marshal_timeval(struct evbuffer *evbuf, uint8_t tag,
struct timeval *tv);
void evtag_test(void);
-int evtag_unmarshal(struct evbuffer *src, u_int8_t *ptag,
- struct evbuffer *dst);
-int evtag_peek(struct evbuffer *evbuf, u_int8_t *ptag);
-int evtag_peek_length(struct evbuffer *evbuf, u_int32_t *plength);
-int evtag_payload_length(struct evbuffer *evbuf, u_int32_t *plength);
+int evtag_unmarshal(struct evbuffer *src, uint8_t *ptag, struct evbuffer *dst);
+int evtag_peek(struct evbuffer *evbuf, uint8_t *ptag);
+int evtag_peek_length(struct evbuffer *evbuf, uint32_t *plength);
+int evtag_payload_length(struct evbuffer *evbuf, uint32_t *plength);
int evtag_consume(struct evbuffer *evbuf);
-int evtag_unmarshal_int(struct evbuffer *evbuf, u_int8_t need_tag,
- u_int32_t *pinteger);
+int evtag_unmarshal_int(struct evbuffer *evbuf, uint8_t need_tag,
+ uint32_t *pinteger);
-int evtag_unmarshal_fixed(struct evbuffer *src, u_int8_t need_tag, void *data,
+int evtag_unmarshal_fixed(struct evbuffer *src, uint8_t need_tag, void *data,
size_t len);
-int evtag_unmarshal_string(struct evbuffer *evbuf, u_int8_t need_tag,
+int evtag_unmarshal_string(struct evbuffer *evbuf, uint8_t need_tag,
char **pstring);
-int evtag_unmarshal_timeval(struct evbuffer *evbuf, u_int8_t need_tag,
+int evtag_unmarshal_timeval(struct evbuffer *evbuf, uint8_t need_tag,
struct timeval *ptv);
#ifdef __cplusplus
diff --git a/libevent/evsignal.h b/libevent/evsignal.h
index 5b92bd6e55fb..7efbcabec896 100644
--- a/libevent/evsignal.h
+++ b/libevent/evsignal.h
@@ -27,9 +27,18 @@
#ifndef _EVSIGNAL_H_
#define _EVSIGNAL_H_
-void evsignal_init(void);
-void evsignal_process(void);
+struct evsignal_info {
+ 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_del(struct event *);
+void evsignal_dealloc(struct event_base *);
#endif /* _EVSIGNAL_H_ */
diff --git a/libevent/kqueue.c b/libevent/kqueue.c
index 08369c6dd51d..059d94a0b4d5 100644
--- a/libevent/kqueue.c
+++ b/libevent/kqueue.c
@@ -48,10 +48,13 @@
#include <inttypes.h>
#endif
-#if defined(HAVE_INTTYPES_H) && !defined(__OpenBSD__) && !defined(__FreeBSD__)
-#define INTPTR(x) (intptr_t)x
+/* Some platforms apparently define the udata field of struct kevent as
+ * ntptr_t, whereas others define it as void*. There doesn't seem to be an
+ * easy way to tell them apart via autoconf, so we need to use OS macros. */
+#if defined(HAVE_INTTYPES_H) && !defined(__OpenBSD__) && !defined(__FreeBSD__) && !defined(__darwin__) && !defined(__APPLE__)
+#define PTR_TO_UDATA(x) ((intptr_t)(x))
#else
-#define INTPTR(x) x
+#define PTR_TO_UDATA(x) (x)
#endif
#include "event.h"
@@ -69,13 +72,13 @@ struct kqop {
int kq;
};
-void *kq_init (void);
+void *kq_init (struct event_base *);
int kq_add (void *, struct event *);
int kq_del (void *, struct event *);
int kq_recalc (struct event_base *, void *, int);
int kq_dispatch (struct event_base *, void *, struct timeval *);
int kq_insert (struct kqop *, struct kevent *);
-void kq_dealloc (void *);
+void kq_dealloc (struct event_base *, void *);
const struct eventop kqops = {
"kqueue",
@@ -88,7 +91,7 @@ const struct eventop kqops = {
};
void *
-kq_init(void)
+kq_init(struct event_base *base)
{
int kq;
struct kqop *kqueueop;
@@ -212,13 +215,16 @@ kq_dispatch(struct event_base *base, void *arg, struct timeval *tv)
struct kevent *changes = kqop->changes;
struct kevent *events = kqop->events;
struct event *ev;
- struct timespec ts;
+ struct timespec ts, *ts_p = NULL;
int i, res;
- TIMEVAL_TO_TIMESPEC(tv, &ts);
+ if (tv != NULL) {
+ TIMEVAL_TO_TIMESPEC(tv, &ts);
+ ts_p = &ts;
+ }
res = kevent(kqop->kq, changes, kqop->nchanges,
- events, kqop->nevents, &ts);
+ events, kqop->nevents, ts_p);
kqop->nchanges = 0;
if (res == -1) {
if (errno != EINTR) {
@@ -294,7 +300,7 @@ kq_add(void *arg, struct event *ev)
kev.flags = EV_ADD;
if (!(ev->ev_events & EV_PERSIST))
kev.flags |= EV_ONESHOT;
- kev.udata = INTPTR(ev);
+ kev.udata = PTR_TO_UDATA(ev);
if (kq_insert(kqop, &kev) == -1)
return (-1);
@@ -317,7 +323,7 @@ kq_add(void *arg, struct event *ev)
kev.flags = EV_ADD;
if (!(ev->ev_events & EV_PERSIST))
kev.flags |= EV_ONESHOT;
- kev.udata = INTPTR(ev);
+ kev.udata = PTR_TO_UDATA(ev);
if (kq_insert(kqop, &kev) == -1)
return (-1);
@@ -332,7 +338,7 @@ kq_add(void *arg, struct event *ev)
kev.flags = EV_ADD;
if (!(ev->ev_events & EV_PERSIST))
kev.flags |= EV_ONESHOT;
- kev.udata = INTPTR(ev);
+ kev.udata = PTR_TO_UDATA(ev);
if (kq_insert(kqop, &kev) == -1)
return (-1);
@@ -398,7 +404,7 @@ kq_del(void *arg, struct event *ev)
}
void
-kq_dealloc(void *arg)
+kq_dealloc(struct event_base *base, void *arg)
{
struct kqop *kqop = arg;
diff --git a/libevent/poll.c b/libevent/poll.c
index 14ca8453739b..123d36a56023 100644
--- a/libevent/poll.c
+++ b/libevent/poll.c
@@ -54,8 +54,6 @@
#include "evsignal.h"
#include "log.h"
-extern volatile sig_atomic_t evsignal_caught;
-
struct pollop {
int event_count; /* Highest number alloc */
int nfds; /* Size of event_* */
@@ -68,12 +66,12 @@ struct pollop {
* "no entry." */
};
-void *poll_init (void);
+void *poll_init (struct event_base *);
int poll_add (void *, struct event *);
int poll_del (void *, struct event *);
int poll_recalc (struct event_base *, void *, int);
int poll_dispatch (struct event_base *, void *, struct timeval *);
-void poll_dealloc (void *);
+void poll_dealloc (struct event_base *, void *);
const struct eventop pollops = {
"poll",
@@ -86,7 +84,7 @@ const struct eventop pollops = {
};
void *
-poll_init(void)
+poll_init(struct event_base *base)
{
struct pollop *pollop;
@@ -97,7 +95,7 @@ poll_init(void)
if (!(pollop = calloc(1, sizeof(struct pollop))))
return (NULL);
- evsignal_init();
+ evsignal_init(base);
return (pollop);
}
@@ -150,13 +148,16 @@ poll_check_ok(struct pollop *pop)
int
poll_dispatch(struct event_base *base, void *arg, struct timeval *tv)
{
- int res, i, sec, nfds;
+ int res, i, msec = -1, nfds;
struct pollop *pop = arg;
poll_check_ok(pop);
- sec = tv->tv_sec * 1000 + (tv->tv_usec + 999) / 1000;
+
+ if (tv != NULL)
+ msec = tv->tv_sec * 1000 + (tv->tv_usec + 999) / 1000;
+
nfds = pop->nfds;
- res = poll(pop->event_set, nfds, sec);
+ res = poll(pop->event_set, nfds, msec);
if (res == -1) {
if (errno != EINTR) {
@@ -164,10 +165,11 @@ poll_dispatch(struct event_base *base, void *arg, struct timeval *tv)
return (-1);
}
- evsignal_process();
+ evsignal_process(base);
return (0);
- } else if (evsignal_caught)
- evsignal_process();
+ } else if (base->sig.evsignal_caught) {
+ evsignal_process(base);
+ }
event_debug(("%s: poll reports %d", __func__, res));
@@ -370,10 +372,11 @@ poll_del(void *arg, struct event *ev)
}
void
-poll_dealloc(void *arg)
+poll_dealloc(struct event_base *base, void *arg)
{
struct pollop *pop = arg;
+ evsignal_dealloc(base);
if (pop->event_set)
free(pop->event_set);
if (pop->event_r_back)
diff --git a/libevent/select.c b/libevent/select.c
index 6ce81a232bbe..d645f1a37030 100644
--- a/libevent/select.c
+++ b/libevent/select.c
@@ -36,6 +36,9 @@
#else
#include <sys/_time.h>
#endif
+#ifdef HAVE_SYS_SELECT_H
+#include <sys/select.h>
+#endif
#include <sys/queue.h>
#include <sys/tree.h>
#include <signal.h>
@@ -57,8 +60,6 @@
#define howmany(x, y) (((x)+((y)-1))/(y))
#endif
-extern volatile sig_atomic_t evsignal_caught;
-
struct selectop {
int event_fds; /* Highest fd in fd set */
int event_fdsz;
@@ -70,12 +71,12 @@ struct selectop {
struct event **event_w_by_fd;
};
-void *select_init (void);
+void *select_init (struct event_base *);
int select_add (void *, struct event *);
int select_del (void *, struct event *);
int select_recalc (struct event_base *, void *, int);
int select_dispatch (struct event_base *, void *, struct timeval *);
-void select_dealloc (void *);
+void select_dealloc (struct event_base *, void *);
const struct eventop selectops = {
"select",
@@ -90,7 +91,7 @@ const struct eventop selectops = {
static int select_resize(struct selectop *sop, int fdsz);
void *
-select_init(void)
+select_init(struct event_base *base)
{
struct selectop *sop;
@@ -103,7 +104,7 @@ select_init(void)
select_resize(sop, howmany(32 + 1, NFDBITS)*sizeof(fd_mask));
- evsignal_init();
+ evsignal_init(base);
return (sop);
}
@@ -113,7 +114,7 @@ static void
check_selectop(struct selectop *sop)
{
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)) {
assert(sop->event_r_by_fd[i]);
assert(sop->event_r_by_fd[i]->ev_events & EV_READ);
@@ -174,10 +175,11 @@ select_dispatch(struct event_base *base, void *arg, struct timeval *tv)
return (-1);
}
- evsignal_process();
+ evsignal_process(base);
return (0);
- } else if (evsignal_caught)
- evsignal_process();
+ } else if (base->sig.evsignal_caught) {
+ evsignal_process(base);
+ }
event_debug(("%s: select reports %d", __func__, res));
@@ -348,10 +350,11 @@ select_del(void *arg, struct event *ev)
}
void
-select_dealloc(void *arg)
+select_dealloc(struct event_base *base, void *arg)
{
struct selectop *sop = arg;
+ evsignal_dealloc(base);
if (sop->event_readset_in)
free(sop->event_readset_in);
if (sop->event_writeset_in)
diff --git a/libevent/signal.c b/libevent/signal.c
index 71bcffcba5b3..6c0953d9e121 100644
--- a/libevent/signal.c
+++ b/libevent/signal.c
@@ -31,6 +31,7 @@
#endif
#include <sys/types.h>
+#include <sys/tree.h>
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#else
@@ -47,19 +48,14 @@
#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#endif
+#include <assert.h>
#include "event.h"
+#include "event-internal.h"
#include "evsignal.h"
#include "log.h"
-extern struct event_list signalqueue;
-
-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;
+struct event_base *evsignal_base = NULL;
static void evsignal_handler(int sig);
@@ -87,24 +83,27 @@ evsignal_cb(int fd, short what, void *arg)
#endif
void
-evsignal_init(void)
+evsignal_init(struct event_base *base)
{
/*
* 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
* 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__);
- FD_CLOSEONEXEC(ev_signal_pair[0]);
- FD_CLOSEONEXEC(ev_signal_pair[1]);
+ FD_CLOSEONEXEC(base->sig.ev_signal_pair[0]);
+ 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,
- evsignal_cb, &ev_signal);
- ev_signal.ev_flags |= EVLIST_INTERNAL;
+ event_set(&base->sig.ev_signal, base->sig.ev_signal_pair[1], EV_READ,
+ evsignal_cb, &base->sig.ev_signal);
+ base->sig.ev_signal.ev_base = base;
+ base->sig.ev_signal.ev_flags |= EVLIST_INTERNAL;
}
int
@@ -112,6 +111,7 @@ evsignal_add(struct event *ev)
{
int evsignal;
struct sigaction sa;
+ struct event_base *base = ev->ev_base;
if (ev->ev_events & (EV_READ|EV_WRITE))
event_errx(1, "%s: EV_SIGNAL incompatible use", __func__);
@@ -121,29 +121,23 @@ evsignal_add(struct event *ev)
sa.sa_handler = evsignal_handler;
sigfillset(&sa.sa_mask);
sa.sa_flags |= SA_RESTART;
+ /* catch signals if they happen quickly */
+ evsignal_base = base;
if (sigaction(evsignal, &sa, NULL) == -1)
return (-1);
- if (!ev_signal_added) {
- ev_signal_added = 1;
- event_add(&ev_signal, NULL);
+ if (!base->sig.ev_signal_added) {
+ base->sig.ev_signal_added = 1;
+ event_add(&base->sig.ev_signal, NULL);
}
return (0);
}
-/*
- * Nothing to be done here.
- */
-
int
evsignal_del(struct event *ev)
{
- int evsignal;
-
- evsignal = EVENT_SIGNAL(ev);
-
return (sigaction(EVENT_SIGNAL(ev),(struct sigaction *)SIG_DFL, NULL));
}
@@ -152,29 +146,50 @@ evsignal_handler(int sig)
{
int save_errno = errno;
- evsigcaught[sig]++;
- evsignal_caught = 1;
+ if(evsignal_base == NULL) {
+ 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 */
- write(ev_signal_pair[0], "a", 1);
+ write(evsignal_base->sig.ev_signal_pair[0], "a", 1);
errno = save_errno;
}
void
-evsignal_process(void)
+evsignal_process(struct event_base *base)
{
struct event *ev;
sig_atomic_t ncalls;
- evsignal_caught = 0;
- TAILQ_FOREACH(ev, &signalqueue, ev_signal_next) {
- ncalls = evsigcaught[EVENT_SIGNAL(ev)];
+ base->sig.evsignal_caught = 0;
+ TAILQ_FOREACH(ev, &base->sig.signalqueue, ev_signal_next) {
+ ncalls = base->sig.evsigcaught[EVENT_SIGNAL(ev)];
if (ncalls) {
if (!(ev->ev_events & EV_PERSIST))
event_del(ev);
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;
+}