diff options
Diffstat (limited to 'extra/libevent/event.c')
-rw-r--r-- | extra/libevent/event.c | 989 |
1 files changed, 0 insertions, 989 deletions
diff --git a/extra/libevent/event.c b/extra/libevent/event.c deleted file mode 100644 index 07498c709c8..00000000000 --- a/extra/libevent/event.c +++ /dev/null @@ -1,989 +0,0 @@ -/* - * Copyright (c) 2000-2004 Niels Provos <provos@citi.umich.edu> - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#ifdef WIN32 -#define WIN32_LEAN_AND_MEAN -#include <windows.h> -#undef WIN32_LEAN_AND_MEAN -#include "misc.h" -#endif -#include <sys/types.h> -#ifdef HAVE_SYS_TIME_H -#include <sys/time.h> -#else -#include <sys/_time.h> -#endif -#include <sys/queue.h> -#include <stdio.h> -#include <stdlib.h> -#ifndef WIN32 -#include <unistd.h> -#endif -#include <errno.h> -#include <signal.h> -#include <string.h> -#include <assert.h> -#include <time.h> - -#include "event.h" -#include "event-internal.h" -#include "evutil.h" -#include "log.h" - -#ifdef HAVE_EVENT_PORTS -extern const struct eventop evportops; -#endif -#ifdef HAVE_SELECT -extern const struct eventop selectops; -#endif -#ifdef HAVE_POLL -extern const struct eventop pollops; -#endif -#ifdef HAVE_EPOLL -extern const struct eventop epollops; -#endif -#ifdef HAVE_WORKING_KQUEUE -extern const struct eventop kqops; -#endif -#ifdef HAVE_DEVPOLL -extern const struct eventop devpollops; -#endif -#ifdef WIN32 -extern const struct eventop win32ops; -#endif - -/* In order of preference */ -const struct eventop *eventops[] = { -#ifdef HAVE_EVENT_PORTS - &evportops, -#endif -#ifdef HAVE_WORKING_KQUEUE - &kqops, -#endif -#ifdef HAVE_EPOLL - &epollops, -#endif -#ifdef HAVE_DEVPOLL - &devpollops, -#endif -#ifdef HAVE_POLL - &pollops, -#endif -#ifdef HAVE_SELECT - &selectops, -#endif -#ifdef WIN32 - &win32ops, -#endif - NULL -}; - -/* Global state */ -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 */ -volatile sig_atomic_t event_gotsig; /* Set in signal handler */ - -/* Prototypes */ -static void event_queue_insert(struct event_base *, struct event *, int); -static void event_queue_remove(struct event_base *, struct event *, int); -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 void timeout_process(struct event_base *); -static void timeout_correct(struct event_base *, struct timeval *); - -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) -{ -#if defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC) - struct timespec ts; - - 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 (gettimeofday(tp, NULL)); -} - -struct event_base * -event_init(void) -{ - struct event_base *base = event_base_new(); - - if (base != NULL) - current_base = base; - - return (base); -} - -struct event_base * -event_base_new(void) -{ - int i; - struct event_base *base; - - if ((base = calloc(1, sizeof(struct event_base))) == NULL) - event_err(1, "%s: calloc", __func__); - - event_sigcb = NULL; - event_gotsig = 0; - - detect_monotonic(); - gettime(&base->event_tv); - - min_heap_ctor(&base->timeheap); - TAILQ_INIT(&base->eventqueue); - TAILQ_INIT(&base->sig.signalqueue); - base->sig.ev_signal_pair[0] = -1; - base->sig.ev_signal_pair[1] = -1; - - base->evbase = NULL; - for (i = 0; eventops[i] && !base->evbase; i++) { - base->evsel = eventops[i]; - - base->evbase = base->evsel->init(base); - } - - if (base->evbase == NULL) - event_errx(1, "%s: no event mechanism available", __func__); - - if (getenv("EVENT_SHOW_METHOD")) - event_msgx("libevent using: %s\n", - base->evsel->name); - - /* allocate a single active event queue */ - event_base_priority_init(base, 1); - - return (base); -} - -void -event_base_free(struct event_base *base) -{ - int i, n_deleted=0; - struct event *ev; - - if (base == NULL && current_base) - base = current_base; - if (base == current_base) - current_base = NULL; - - /* XXX(niels) - check for internal events first */ - assert(base); - /* Delete all non-internal events. */ - for (ev = TAILQ_FIRST(&base->eventqueue); ev; ) { - struct event *next = TAILQ_NEXT(ev, ev_next); - if (!(ev->ev_flags & EVLIST_INTERNAL)) { - event_del(ev); - ++n_deleted; - } - ev = next; - } - while ((ev = min_heap_top(&base->timeheap)) != NULL) { - event_del(ev); - ++n_deleted; - } - - if (n_deleted) - event_debug(("%s: %d events were still set in base", - __func__, n_deleted)); - - if (base->evsel->dealloc != NULL) - base->evsel->dealloc(base, base->evbase); - - for (i = 0; i < base->nactivequeues; ++i) - assert(TAILQ_EMPTY(base->activequeues[i])); - - assert(min_heap_empty(&base->timeheap)); - min_heap_dtor(&base->timeheap); - - for (i = 0; i < base->nactivequeues; ++i) - free(base->activequeues[i]); - free(base->activequeues); - - assert(TAILQ_EMPTY(&base->eventqueue)); - - free(base); -} - -/* reinitialized the event base after a fork */ -int -event_reinit(struct event_base *base) -{ - const struct eventop *evsel = base->evsel; - void *evbase = base->evbase; - int res = 0; - struct event *ev; - - /* check if this event mechanism requires reinit */ - if (!evsel->need_reinit) - return (0); - - if (base->evsel->dealloc != NULL) - base->evsel->dealloc(base, base->evbase); - base->evbase = evsel->init(base); - if (base->evbase == NULL) - event_errx(1, "%s: could not reinitialize event mechanism", - __func__); - - TAILQ_FOREACH(ev, &base->eventqueue, ev_next) { - if (evsel->add(evbase, ev) == -1) - res = -1; - } - - return (res); -} - -int -event_priority_init(int npriorities) -{ - return event_base_priority_init(current_base, npriorities); -} - -int -event_base_priority_init(struct event_base *base, int npriorities) -{ - int i; - - if (base->event_count_active) - return (-1); - - if (base->nactivequeues && npriorities != base->nactivequeues) { - for (i = 0; i < base->nactivequeues; ++i) { - free(base->activequeues[i]); - } - free(base->activequeues); - } - - /* Allocate our priority queues */ - base->nactivequeues = npriorities; - base->activequeues = (struct event_list **)calloc(base->nactivequeues, - npriorities * sizeof(struct event_list *)); - if (base->activequeues == NULL) - event_err(1, "%s: calloc", __func__); - - for (i = 0; i < base->nactivequeues; ++i) { - base->activequeues[i] = malloc(sizeof(struct event_list)); - if (base->activequeues[i] == NULL) - event_err(1, "%s: malloc", __func__); - TAILQ_INIT(base->activequeues[i]); - } - - return (0); -} - -int -event_haveevents(struct event_base *base) -{ - return (base->event_count > 0); -} - -/* - * Active events are stored in priority queues. Lower priorities are always - * process before higher priorities. Low priority events can starve high - * priority ones. - */ - -static void -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) { - activeq = base->activequeues[i]; - break; - } - } - - assert(activeq != NULL); - - for (ev = TAILQ_FIRST(activeq); ev; ev = TAILQ_FIRST(activeq)) { - if (ev->ev_events & EV_PERSIST) - event_queue_remove(base, ev, EVLIST_ACTIVE); - 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; - } - } -} - -/* - * Wait continously for events. We exit only if no events are left. - */ - -int -event_dispatch(void) -{ - return (event_loop(0)); -} - -int -event_base_dispatch(struct event_base *event_base) -{ - return (event_base_loop(event_base, 0)); -} - -const char * -event_base_get_method(struct event_base *base) -{ - assert(base); - return (base->evsel->name); -} - -static void -event_loopexit_cb(int fd __attribute__((unused)), - short what __attribute__((unused)), void *arg) -{ - struct event_base *base = arg; - base->event_gotterm = 1; -} - -/* not thread safe */ -int -event_loopexit(struct timeval *tv) -{ - return (event_once(-1, EV_TIMEOUT, &event_loopexit_cb, - current_base, tv)); -} - -int -event_base_loopexit(struct event_base *event_base, struct timeval *tv) -{ - return (event_base_once(event_base, -1, EV_TIMEOUT, event_loopexit_cb, - event_base, tv)); -} - -/* not thread safe */ -int -event_loopbreak(void) -{ - return (event_base_loopbreak(current_base)); -} - -int -event_base_loopbreak(struct event_base *event_base) -{ - if (event_base == NULL) - return (-1); - - event_base->event_break = 1; - return (0); -} - - - -/* not thread safe */ - -int -event_loop(int flags) -{ - return event_base_loop(current_base, flags); -} - -int -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; - - if(!TAILQ_EMPTY(&base->sig.signalqueue)) - evsignal_base = base; - done = 0; - while (!done) { - /* Terminate the loop if we have been asked to */ - if (base->event_gotterm) { - base->event_gotterm = 0; - break; - } - - if (base->event_break) { - base->event_break = 0; - break; - } - - /* You cannot use this interface for multi-threaded apps */ - while (event_gotsig) { - event_gotsig = 0; - if (event_sigcb) { - res = (*event_sigcb)(); - if (res == -1) { - errno = EINTR; - return (-1); - } - } - } - - timeout_correct(base, &tv); - - 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. - */ - evutil_timerclear(&tv); - } - - /* If we have no events, we just exit */ - if (!event_haveevents(base)) { - event_debug(("%s: no events registered.", __func__)); - return (1); - } - - res = evsel->dispatch(base, evbase, tv_p); - - if (res == -1) - return (-1); - - timeout_process(base); - - if (base->event_count_active) { - event_process_active(base); - if (!base->event_count_active && (flags & EVLOOP_ONCE)) - done = 1; - } else if (flags & EVLOOP_NONBLOCK) - done = 1; - } - - event_debug(("%s: asked to terminate loop.", __func__)); - return (0); -} - -/* Sets up an event for processing once */ - -struct event_once { - struct event ev; - - void (*cb)(int, short, void *); - void *arg; -}; - -/* One-time callback, it deletes itself */ - -static void -event_once_cb(int fd, short events, void *arg) -{ - struct event_once *eonce = arg; - - (*eonce->cb)(fd, events, eonce->arg); - free(eonce); -} - -/* 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; - - /* We cannot support signals that just fire once */ - if (events & EV_SIGNAL) - return (-1); - - if ((eonce = calloc(1, sizeof(struct event_once))) == NULL) - return (-1); - - eonce->cb = callback; - eonce->arg = arg; - - if (events == EV_TIMEOUT) { - if (tv == NULL) { - evutil_timerclear(&etv); - tv = &etv; - } - - evtimer_set(&eonce->ev, event_once_cb, eonce); - } else if (events & (EV_READ|EV_WRITE)) { - events &= EV_READ|EV_WRITE; - - event_set(&eonce->ev, fd, events, event_once_cb, eonce); - } else { - /* Bad event combination */ - free(eonce); - return (-1); - } - - res = event_base_set(base, &eonce->ev); - if (res == 0) - res = event_add(&eonce->ev, tv); - if (res != 0) { - free(eonce); - return (res); - } - - return (0); -} - -void -event_set(struct event *ev, int fd, short events, - void (*callback)(int, short, void *), void *arg) -{ - /* Take the current base - caller needs to set the real base later */ - ev->ev_base = current_base; - - ev->ev_callback = callback; - 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; - - min_heap_elem_init(ev); - - /* by default, we put new events into the middle priority */ - if(current_base) - ev->ev_pri = current_base->nactivequeues/2; -} - -int -event_base_set(struct event_base *base, struct event *ev) -{ - /* Only innocent events may be assigned to a different base */ - if (ev->ev_flags != EVLIST_INIT) - return (-1); - - ev->ev_base = base; - ev->ev_pri = base->nactivequeues/2; - - return (0); -} - -/* - * Set's the priority of an event - if an event is already scheduled - * changing the priority is going to fail. - */ - -int -event_priority_set(struct event *ev, int pri) -{ - if (ev->ev_flags & EVLIST_ACTIVE) - return (-1); - if (pri < 0 || pri >= ev->ev_base->nactivequeues) - return (-1); - - ev->ev_pri = pri; - - return (0); -} - -/* - * Checks if a specific event is pending or scheduled. - */ - -int -event_pending(struct event *ev, short event, struct timeval *tv) -{ - struct timeval now, res; - int flags = 0; - - if (ev->ev_flags & EVLIST_INSERTED) - flags |= (ev->ev_events & (EV_READ|EV_WRITE)); - if (ev->ev_flags & EVLIST_ACTIVE) - flags |= ev->ev_res; - if (ev->ev_flags & EVLIST_TIMEOUT) - flags |= EV_TIMEOUT; - if (ev->ev_flags & EVLIST_SIGNAL) - flags |= EV_SIGNAL; - - event &= (EV_TIMEOUT|EV_READ|EV_WRITE|EV_SIGNAL); - - /* See if there is a timeout that we should report */ - if (tv != NULL && (flags & event & EV_TIMEOUT)) { - gettime(&now); - evutil_timersub(&ev->ev_timeout, &now, &res); - /* correctly remap to real time */ - gettimeofday(&now, NULL); - evutil_timeradd(&now, &res, tv); - } - - return (flags & event); -} - -int -event_add(struct event *ev, struct timeval *tv) -{ - struct event_base *base = ev->ev_base; - const struct eventop *evsel = base->evsel; - void *evbase = base->evbase; - - event_debug(( - "event_add: event: %p, %s%s%scall %p", - ev, - ev->ev_events & EV_READ ? "EV_READ " : " ", - ev->ev_events & EV_WRITE ? "EV_WRITE " : " ", - tv ? "EV_TIMEOUT " : " ", - ev->ev_callback)); - - assert(!(ev->ev_flags & ~EVLIST_ALL)); - - if (tv != NULL) { - struct timeval now; - - if (ev->ev_flags & EVLIST_TIMEOUT) - event_queue_remove(base, ev, EVLIST_TIMEOUT); - else if (min_heap_reserve(&base->timeheap, - 1 + min_heap_size(&base->timeheap)) == -1) - return (-1); /* ENOMEM == errno */ - - /* Check if it is active due to a timeout. Rescheduling - * this timeout before the callback can be executed - * 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; - } - - event_queue_remove(base, ev, EVLIST_ACTIVE); - } - - gettime(&now); - evutil_timeradd(&now, tv, &ev->ev_timeout); - - event_debug(( - "event_add: timeout in %d seconds, call %p", - tv->tv_sec, ev->ev_callback)); - - event_queue_insert(base, ev, EVLIST_TIMEOUT); - } - - if ((ev->ev_events & (EV_READ|EV_WRITE)) && - !(ev->ev_flags & (EVLIST_INSERTED|EVLIST_ACTIVE))) { - int res = evsel->add(evbase, ev); - if (res != -1) - event_queue_insert(base, ev, EVLIST_INSERTED); - - return (res); - } else if ((ev->ev_events & EV_SIGNAL) && - !(ev->ev_flags & EVLIST_SIGNAL)) { - int res = evsel->add(evbase, ev); - if (res != -1) - event_queue_insert(base, ev, EVLIST_SIGNAL); - - return (res); - } - - return (0); -} - -int -event_del(struct event *ev) -{ - struct event_base *base; - const struct eventop *evsel; - void *evbase; - - event_debug(("event_del: %p, callback %p", - ev, ev->ev_callback)); - - /* An event without a base has not been added */ - if (ev->ev_base == NULL) - return (-1); - - base = ev->ev_base; - evsel = base->evsel; - evbase = base->evbase; - - 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_TIMEOUT) - event_queue_remove(base, ev, EVLIST_TIMEOUT); - - if (ev->ev_flags & EVLIST_ACTIVE) - event_queue_remove(base, ev, EVLIST_ACTIVE); - - if (ev->ev_flags & EVLIST_INSERTED) { - event_queue_remove(base, ev, EVLIST_INSERTED); - return (evsel->del(evbase, ev)); - } else if (ev->ev_flags & EVLIST_SIGNAL) { - event_queue_remove(base, ev, EVLIST_SIGNAL); - return (evsel->del(evbase, ev)); - } - - return (0); -} - -void -event_active(struct event *ev, int res, short ncalls) -{ - /* We get different kinds of events, add them together */ - if (ev->ev_flags & EVLIST_ACTIVE) { - ev->ev_res |= res; - return; - } - - ev->ev_res = res; - ev->ev_ncalls = ncalls; - ev->ev_pncalls = NULL; - event_queue_insert(ev->ev_base, ev, EVLIST_ACTIVE); -} - -static int -timeout_next(struct event_base *base, struct timeval **tv_p) -{ - struct timeval now; - struct event *ev; - struct timeval *tv = *tv_p; - - if ((ev = min_heap_top(&base->timeheap)) == NULL) { - /* if no time-based events are active wait for I/O */ - *tv_p = NULL; - return (0); - } - - if (gettime(&now) == -1) - return (-1); - - if (evutil_timercmp(&ev->ev_timeout, &now, <=)) { - evutil_timerclear(tv); - return (0); - } - - evutil_timersub(&ev->ev_timeout, &now, tv); - - assert(tv->tv_sec >= 0); - assert(tv->tv_usec >= 0); - - event_debug(("timeout_next: in %d seconds", tv->tv_sec)); - 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 *tv) -{ - struct event **pev; - unsigned int size; - struct timeval off; - - if (use_monotonic) - return; - - /* Check if time is running backwards */ - gettime(tv); - if (evutil_timercmp(tv, &base->event_tv, >=)) { - base->event_tv = *tv; - return; - } - - event_debug(("%s: time is running backwards, corrected", - __func__)); - evutil_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. - */ - pev = base->timeheap.p; - size = base->timeheap.n; - for (; size-- > 0; ++pev) { - struct timeval *ev_tv = &(**pev).ev_timeout; - evutil_timersub(ev_tv, &off, ev_tv); - } -} - -void -timeout_process(struct event_base *base) -{ - struct timeval now; - struct event *ev; - - if (min_heap_empty(&base->timeheap)) - return; - - gettime(&now); - - while ((ev = min_heap_top(&base->timeheap))) { - if (evutil_timercmp(&ev->ev_timeout, &now, >)) - break; - - /* delete this event from the I/O queues */ - event_del(ev); - - event_debug(("timeout_process: call %p", - ev->ev_callback)); - event_active(ev, EV_TIMEOUT, 1); - } -} - -void -event_queue_remove(struct event_base *base, struct event *ev, int queue) -{ - if (!(ev->ev_flags & queue)) - event_errx(1, "%s: %p(fd %d) not on queue %x", __func__, - ev, ev->ev_fd, queue); - - if (~ev->ev_flags & EVLIST_INTERNAL) - base->event_count--; - - ev->ev_flags &= ~queue; - switch (queue) { - case EVLIST_ACTIVE: - base->event_count_active--; - TAILQ_REMOVE(base->activequeues[ev->ev_pri], - ev, ev_active_next); - break; - case EVLIST_SIGNAL: - TAILQ_REMOVE(&base->sig.signalqueue, ev, ev_signal_next); - break; - case EVLIST_TIMEOUT: - min_heap_erase(&base->timeheap, ev); - break; - case EVLIST_INSERTED: - TAILQ_REMOVE(&base->eventqueue, ev, ev_next); - break; - default: - event_errx(1, "%s: unknown queue %x", __func__, queue); - } -} - -void -event_queue_insert(struct event_base *base, struct event *ev, int queue) -{ - if (ev->ev_flags & queue) { - /* Double insertion is possible for active events */ - if (queue & EVLIST_ACTIVE) - return; - - event_errx(1, "%s: %p(fd %d) already on queue %x", __func__, - ev, ev->ev_fd, queue); - } - - if (~ev->ev_flags & EVLIST_INTERNAL) - base->event_count++; - - ev->ev_flags |= queue; - switch (queue) { - case EVLIST_ACTIVE: - base->event_count_active++; - TAILQ_INSERT_TAIL(base->activequeues[ev->ev_pri], - ev,ev_active_next); - break; - case EVLIST_SIGNAL: - TAILQ_INSERT_TAIL(&base->sig.signalqueue, ev, ev_signal_next); - break; - case EVLIST_TIMEOUT: { - min_heap_push(&base->timeheap, ev); - break; - } - case EVLIST_INSERTED: - TAILQ_INSERT_TAIL(&base->eventqueue, ev, ev_next); - break; - default: - event_errx(1, "%s: unknown queue %x", __func__, queue); - } -} - -/* Functions for debugging */ - -const char * -event_get_version(void) -{ - return (VERSION); -} - -/* - * No thread-safe interface needed - the information should be the same - * for all threads. - */ - -const char * -event_get_method(void) -{ - return (current_base->evsel->name); -} |