15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Copyright (c) 2000-2004 Niels Provos <provos@citi.umich.edu> 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * All rights reserved. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Redistribution and use in source and binary forms, with or without 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * modification, are permitted provided that the following conditions 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * are met: 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 1. Redistributions of source code must retain the above copyright 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * notice, this list of conditions and the following disclaimer. 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 2. Redistributions in binary form must reproduce the above copyright 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * notice, this list of conditions and the following disclaimer in the 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * documentation and/or other materials provided with the distribution. 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 3. The name of the author may not be used to endorse or promote products 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * derived from this software without specific prior written permission. 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef HAVE_CONFIG_H 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "config.h" 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef WIN32 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define WIN32_LEAN_AND_MEAN 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <windows.h> 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef WIN32_LEAN_AND_MEAN 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/types.h> 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef HAVE_SYS_TIME_H 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/time.h> 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/_libevent_time.h> 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/queue.h> 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdio.h> 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdlib.h> 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef WIN32 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <unistd.h> 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <errno.h> 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <signal.h> 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string.h> 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <assert.h> 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <time.h> 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "event.h" 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "event-internal.h" 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "evutil.h" 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "log.h" 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef HAVE_EVENT_PORTS 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern const struct eventop evportops; 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef HAVE_SELECT 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern const struct eventop selectops; 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef HAVE_POLL 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern const struct eventop pollops; 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef HAVE_EPOLL 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern const struct eventop epollops; 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef HAVE_WORKING_KQUEUE 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern const struct eventop kqops; 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef HAVE_DEVPOLL 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern const struct eventop devpollops; 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef WIN32 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern const struct eventop win32ops; 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* In order of preference */ 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const struct eventop *eventops[] = { 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef HAVE_EVENT_PORTS 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &evportops, 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef HAVE_WORKING_KQUEUE 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &kqops, 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef HAVE_EPOLL 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &epollops, 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef HAVE_DEVPOLL 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &devpollops, 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef HAVE_POLL 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &pollops, 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef HAVE_SELECT 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &selectops, 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef WIN32 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &win32ops, 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Global state */ 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct event_base *current_base = NULL; 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern struct event_base *evsignal_base; 110c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochstatic int use_monotonic = 1; 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Prototypes */ 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void event_queue_insert(struct event_base *, struct event *, int); 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void event_queue_remove(struct event_base *, struct event *, int); 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int event_haveevents(struct event_base *); 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void event_process_active(struct event_base *); 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int timeout_next(struct event_base *, struct timeval **); 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void timeout_process(struct event_base *); 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void timeout_correct(struct event_base *, struct timeval *); 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gettime(struct event_base *base, struct timeval *tp) 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (base->tv_cache.tv_sec) { 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *tp = base->tv_cache; 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (0); 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC) 132c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch struct timespec ts; 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 134c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (use_monotonic && 135c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch clock_gettime(CLOCK_MONOTONIC, &ts) == 0) { 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tp->tv_sec = ts.tv_sec; 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tp->tv_usec = ts.tv_nsec / 1000; 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (0); 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 142c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch use_monotonic = 0; 143c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (evutil_gettimeofday(tp, NULL)); 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct event_base * 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)event_init(void) 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct event_base *base = event_base_new(); 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (base != NULL) 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) current_base = base; 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (base); 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct event_base * 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)event_base_new(void) 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct event_base *base; 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((base = calloc(1, sizeof(struct event_base))) == NULL) 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_err(1, "%s: calloc", __func__); 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gettime(base, &base->event_tv); 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) min_heap_ctor(&base->timeheap); 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TAILQ_INIT(&base->eventqueue); 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base->sig.ev_signal_pair[0] = -1; 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base->sig.ev_signal_pair[1] = -1; 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base->evbase = NULL; 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; eventops[i] && !base->evbase; i++) { 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base->evsel = eventops[i]; 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base->evbase = base->evsel->init(base); 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (base->evbase == NULL) 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_errx(1, "%s: no event mechanism available", __func__); 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (evutil_getenv("EVENT_SHOW_METHOD")) 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_msgx("libevent using: %s\n", 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base->evsel->name); 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* allocate a single active event queue */ 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_base_priority_init(base, 1); 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (base); 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)event_base_free(struct event_base *base) 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i, n_deleted=0; 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct event *ev; 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (base == NULL && current_base) 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base = current_base; 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (base == current_base) 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) current_base = NULL; 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* XXX(niels) - check for internal events first */ 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(base); 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Delete all non-internal events. */ 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (ev = TAILQ_FIRST(&base->eventqueue); ev; ) { 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct event *next = TAILQ_NEXT(ev, ev_next); 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!(ev->ev_flags & EVLIST_INTERNAL)) { 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_del(ev); 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++n_deleted; 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ev = next; 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while ((ev = min_heap_top(&base->timeheap)) != NULL) { 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_del(ev); 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++n_deleted; 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < base->nactivequeues; ++i) { 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (ev = TAILQ_FIRST(base->activequeues[i]); ev; ) { 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct event *next = TAILQ_NEXT(ev, ev_active_next); 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!(ev->ev_flags & EVLIST_INTERNAL)) { 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_del(ev); 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++n_deleted; 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ev = next; 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (n_deleted) 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_debug(("%s: %d events were still set in base", 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __func__, n_deleted)); 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (base->evsel->dealloc != NULL) 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base->evsel->dealloc(base, base->evbase); 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < base->nactivequeues; ++i) 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(TAILQ_EMPTY(base->activequeues[i])); 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(min_heap_empty(&base->timeheap)); 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) min_heap_dtor(&base->timeheap); 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < base->nactivequeues; ++i) 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) free(base->activequeues[i]); 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) free(base->activequeues); 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(TAILQ_EMPTY(&base->eventqueue)); 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) free(base); 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* reinitialized the event base after a fork */ 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)event_reinit(struct event_base *base) 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const struct eventop *evsel = base->evsel; 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void *evbase = base->evbase; 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int res = 0; 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct event *ev; 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* check if this event mechanism requires reinit */ 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!evsel->need_reinit) 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (0); 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* prevent internal delete */ 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (base->sig.ev_signal_added) { 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* we cannot call event_del here because the base has 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * not been reinitialized yet. */ 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_queue_remove(base, &base->sig.ev_signal, 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EVLIST_INSERTED); 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (base->sig.ev_signal.ev_flags & EVLIST_ACTIVE) 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_queue_remove(base, &base->sig.ev_signal, 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EVLIST_ACTIVE); 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base->sig.ev_signal_added = 0; 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (base->evsel->dealloc != NULL) 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base->evsel->dealloc(base, base->evbase); 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) evbase = base->evbase = evsel->init(base); 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (base->evbase == NULL) 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_errx(1, "%s: could not reinitialize event mechanism", 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __func__); 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TAILQ_FOREACH(ev, &base->eventqueue, ev_next) { 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (evsel->add(evbase, ev) == -1) 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) res = -1; 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (res); 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)event_priority_init(int npriorities) 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return event_base_priority_init(current_base, npriorities); 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)event_base_priority_init(struct event_base *base, int npriorities) 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (base->event_count_active) 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (-1); 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (base->nactivequeues && npriorities != base->nactivequeues) { 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < base->nactivequeues; ++i) { 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) free(base->activequeues[i]); 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) free(base->activequeues); 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Allocate our priority queues */ 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base->nactivequeues = npriorities; 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base->activequeues = (struct event_list **) 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) calloc(base->nactivequeues, sizeof(struct event_list *)); 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (base->activequeues == NULL) 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_err(1, "%s: calloc", __func__); 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < base->nactivequeues; ++i) { 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base->activequeues[i] = malloc(sizeof(struct event_list)); 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (base->activequeues[i] == NULL) 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_err(1, "%s: malloc", __func__); 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TAILQ_INIT(base->activequeues[i]); 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (0); 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)event_haveevents(struct event_base *base) 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (base->event_count > 0); 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Active events are stored in priority queues. Lower priorities are always 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * process before higher priorities. Low priority events can starve high 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * priority ones. 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)event_process_active(struct event_base *base) 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct event *ev; 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct event_list *activeq = NULL; 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) short ncalls; 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < base->nactivequeues; ++i) { 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (TAILQ_FIRST(base->activequeues[i]) != NULL) { 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) activeq = base->activequeues[i]; 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(activeq != NULL); 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (ev = TAILQ_FIRST(activeq); ev; ev = TAILQ_FIRST(activeq)) { 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ev->ev_events & EV_PERSIST) 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_queue_remove(base, ev, EVLIST_ACTIVE); 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_del(ev); 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Allows deletes to work */ 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ncalls = ev->ev_ncalls; 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ev->ev_pncalls = &ncalls; 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (ncalls) { 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ncalls--; 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ev->ev_ncalls = ncalls; 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (*ev->ev_callback)((int)ev->ev_fd, ev->ev_res, ev->ev_arg); 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (base->event_break) 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Wait continously for events. We exit only if no events are left. 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)event_dispatch(void) 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (event_loop(0)); 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)event_base_dispatch(struct event_base *event_base) 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (event_base_loop(event_base, 0)); 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char * 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)event_base_get_method(struct event_base *base) 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(base); 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (base->evsel->name); 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)event_loopexit_cb(int fd, short what, void *arg) 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct event_base *base = arg; 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base->event_gotterm = 1; 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* not thread safe */ 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)event_loopexit(const struct timeval *tv) 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (event_once(-1, EV_TIMEOUT, event_loopexit_cb, 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) current_base, tv)); 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)event_base_loopexit(struct event_base *event_base, const struct timeval *tv) 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (event_base_once(event_base, -1, EV_TIMEOUT, event_loopexit_cb, 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_base, tv)); 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* not thread safe */ 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)event_loopbreak(void) 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (event_base_loopbreak(current_base)); 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)event_base_loopbreak(struct event_base *event_base) 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (event_base == NULL) 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (-1); 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_base->event_break = 1; 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (0); 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* not thread safe */ 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)event_loop(int flags) 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return event_base_loop(current_base, flags); 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)event_base_loop(struct event_base *base, int flags) 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const struct eventop *evsel = base->evsel; 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void *evbase = base->evbase; 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct timeval tv; 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct timeval *tv_p; 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int res, done; 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* clear time cache */ 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base->tv_cache.tv_sec = 0; 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (base->sig.ev_signal_added) 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) evsignal_base = base; 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) done = 0; 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (!done) { 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Terminate the loop if we have been asked to */ 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (base->event_gotterm) { 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base->event_gotterm = 0; 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (base->event_break) { 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base->event_break = 0; 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) timeout_correct(base, &tv); 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tv_p = &tv; 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!base->event_count_active && !(flags & EVLOOP_NONBLOCK)) { 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) timeout_next(base, &tv_p); 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * if we have active events, we just poll new events 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * without waiting. 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) evutil_timerclear(&tv); 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* If we have no events, we just exit */ 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!event_haveevents(base)) { 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_debug(("%s: no events registered.", __func__)); 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (1); 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* update last old time */ 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gettime(base, &base->event_tv); 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* clear time cache */ 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base->tv_cache.tv_sec = 0; 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) res = evsel->dispatch(base, evbase, tv_p); 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (res == -1) 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (-1); 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gettime(base, &base->tv_cache); 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) timeout_process(base); 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (base->event_count_active) { 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_process_active(base); 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!base->event_count_active && (flags & EVLOOP_ONCE)) 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) done = 1; 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (flags & EVLOOP_NONBLOCK) 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) done = 1; 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* clear time cache */ 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base->tv_cache.tv_sec = 0; 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_debug(("%s: asked to terminate loop.", __func__)); 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (0); 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Sets up an event for processing once */ 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct event_once { 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct event ev; 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void (*cb)(int, short, void *); 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void *arg; 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* One-time callback, it deletes itself */ 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)event_once_cb(int fd, short events, void *arg) 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct event_once *eonce = arg; 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (*eonce->cb)(fd, events, eonce->arg); 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) free(eonce); 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* not threadsafe, event scheduled once. */ 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)event_once(int fd, short events, 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void (*callback)(int, short, void *), void *arg, const struct timeval *tv) 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return event_base_once(current_base, fd, events, callback, arg, tv); 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Schedules an event once */ 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)event_base_once(struct event_base *base, int fd, short events, 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void (*callback)(int, short, void *), void *arg, const struct timeval *tv) 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct event_once *eonce; 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct timeval etv; 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int res; 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* We cannot support signals that just fire once */ 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (events & EV_SIGNAL) 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (-1); 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((eonce = calloc(1, sizeof(struct event_once))) == NULL) 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (-1); 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) eonce->cb = callback; 5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) eonce->arg = arg; 5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (events == EV_TIMEOUT) { 5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tv == NULL) { 5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) evutil_timerclear(&etv); 5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tv = &etv; 5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) evtimer_set(&eonce->ev, event_once_cb, eonce); 5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (events & (EV_READ|EV_WRITE)) { 5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) events &= EV_READ|EV_WRITE; 5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_set(&eonce->ev, fd, events, event_once_cb, eonce); 5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Bad event combination */ 5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) free(eonce); 5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (-1); 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) res = event_base_set(base, &eonce->ev); 5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (res == 0) 5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) res = event_add(&eonce->ev, tv); 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (res != 0) { 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) free(eonce); 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (res); 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (0); 6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void 6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)event_set(struct event *ev, int fd, short events, 6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void (*callback)(int, short, void *), void *arg) 6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Take the current base - caller needs to set the real base later */ 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ev->ev_base = current_base; 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ev->ev_callback = callback; 6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ev->ev_arg = arg; 6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ev->ev_fd = fd; 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ev->ev_events = events; 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ev->ev_res = 0; 6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ev->ev_flags = EVLIST_INIT; 6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ev->ev_ncalls = 0; 6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ev->ev_pncalls = NULL; 6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) min_heap_elem_init(ev); 6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* by default, we put new events into the middle priority */ 6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if(current_base) 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ev->ev_pri = current_base->nactivequeues/2; 6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int 6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)event_base_set(struct event_base *base, struct event *ev) 6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Only innocent events may be assigned to a different base */ 6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ev->ev_flags != EVLIST_INIT) 6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (-1); 6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ev->ev_base = base; 6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ev->ev_pri = base->nactivequeues/2; 6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (0); 6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Set's the priority of an event - if an event is already scheduled 6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * changing the priority is going to fail. 6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int 6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)event_priority_set(struct event *ev, int pri) 6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ev->ev_flags & EVLIST_ACTIVE) 6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (-1); 6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pri < 0 || pri >= ev->ev_base->nactivequeues) 6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (-1); 6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ev->ev_pri = pri; 6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (0); 6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Checks if a specific event is pending or scheduled. 6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int 6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)event_pending(struct event *ev, short event, struct timeval *tv) 6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct timeval now, res; 6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int flags = 0; 6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ev->ev_flags & EVLIST_INSERTED) 6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) flags |= (ev->ev_events & (EV_READ|EV_WRITE|EV_SIGNAL)); 6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ev->ev_flags & EVLIST_ACTIVE) 6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) flags |= ev->ev_res; 6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ev->ev_flags & EVLIST_TIMEOUT) 6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) flags |= EV_TIMEOUT; 6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event &= (EV_TIMEOUT|EV_READ|EV_WRITE|EV_SIGNAL); 6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* See if there is a timeout that we should report */ 6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tv != NULL && (flags & event & EV_TIMEOUT)) { 6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gettime(ev->ev_base, &now); 6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) evutil_timersub(&ev->ev_timeout, &now, &res); 6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* correctly remap to real time */ 6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) evutil_gettimeofday(&now, NULL); 6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) evutil_timeradd(&now, &res, tv); 6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (flags & event); 6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int 6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)event_add(struct event *ev, const struct timeval *tv) 6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct event_base *base = ev->ev_base; 6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const struct eventop *evsel = base->evsel; 6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void *evbase = base->evbase; 6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int res = 0; 6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_debug(( 6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "event_add: event: %p, %s%s%scall %p", 6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ev, 6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ev->ev_events & EV_READ ? "EV_READ " : " ", 6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ev->ev_events & EV_WRITE ? "EV_WRITE " : " ", 7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tv ? "EV_TIMEOUT " : " ", 7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ev->ev_callback)); 7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(!(ev->ev_flags & ~EVLIST_ALL)); 7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * prepare for timeout insertion further below, if we get a 7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * failure on any step, we should not change any state. 7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tv != NULL && !(ev->ev_flags & EVLIST_TIMEOUT)) { 7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (min_heap_reserve(&base->timeheap, 7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1 + min_heap_size(&base->timeheap)) == -1) 7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (-1); /* ENOMEM == errno */ 7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((ev->ev_events & (EV_READ|EV_WRITE|EV_SIGNAL)) && 7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !(ev->ev_flags & (EVLIST_INSERTED|EVLIST_ACTIVE))) { 7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) res = evsel->add(evbase, ev); 7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (res != -1) 7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_queue_insert(base, ev, EVLIST_INSERTED); 7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * we should change the timout state only if the previous event 7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * addition succeeded. 7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (res != -1 && tv != NULL) { 7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct timeval now; 7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * we already reserved memory above for the case where we 7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * are not replacing an exisiting timeout. 7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ev->ev_flags & EVLIST_TIMEOUT) 7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_queue_remove(base, ev, EVLIST_TIMEOUT); 7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Check if it is active due to a timeout. Rescheduling 7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * this timeout before the callback can be executed 7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * removes it from the active list. */ 7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((ev->ev_flags & EVLIST_ACTIVE) && 7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (ev->ev_res & EV_TIMEOUT)) { 7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* See if we are just active executing this 7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * event in a loop 7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ev->ev_ncalls && ev->ev_pncalls) { 7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Abort loop */ 7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *ev->ev_pncalls = 0; 7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_queue_remove(base, ev, EVLIST_ACTIVE); 7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gettime(base, &now); 7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) evutil_timeradd(&now, tv, &ev->ev_timeout); 7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_debug(( 7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "event_add: timeout in %ld seconds, call %p", 7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tv->tv_sec, ev->ev_callback)); 7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_queue_insert(base, ev, EVLIST_TIMEOUT); 7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (res); 7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int 7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)event_del(struct event *ev) 7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct event_base *base; 7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_debug(("event_del: %p, callback %p", 7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ev, ev->ev_callback)); 7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* An event without a base has not been added */ 7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ev->ev_base == NULL) 7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (-1); 7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base = ev->ev_base; 7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(!(ev->ev_flags & ~EVLIST_ALL)); 7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* See if we are just active executing this event in a loop */ 7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ev->ev_ncalls && ev->ev_pncalls) { 7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Abort loop */ 7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *ev->ev_pncalls = 0; 7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ev->ev_flags & EVLIST_TIMEOUT) 7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_queue_remove(base, ev, EVLIST_TIMEOUT); 7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ev->ev_flags & EVLIST_ACTIVE) 7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_queue_remove(base, ev, EVLIST_ACTIVE); 7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ev->ev_flags & EVLIST_INSERTED) { 7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_queue_remove(base, ev, EVLIST_INSERTED); 7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (base->evsel->del(base->evbase, ev)); 7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (0); 7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void 8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)event_active(struct event *ev, int res, short ncalls) 8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* We get different kinds of events, add them together */ 8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ev->ev_flags & EVLIST_ACTIVE) { 8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ev->ev_res |= res; 8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ev->ev_res = res; 8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ev->ev_ncalls = ncalls; 8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ev->ev_pncalls = NULL; 8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_queue_insert(ev->ev_base, ev, EVLIST_ACTIVE); 8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int 8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)timeout_next(struct event_base *base, struct timeval **tv_p) 8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct timeval now; 8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct event *ev; 8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct timeval *tv = *tv_p; 8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((ev = min_heap_top(&base->timeheap)) == NULL) { 8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* if no time-based events are active wait for I/O */ 8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *tv_p = NULL; 8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (0); 8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (gettime(base, &now) == -1) 8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (-1); 8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (evutil_timercmp(&ev->ev_timeout, &now, <=)) { 8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) evutil_timerclear(tv); 8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (0); 8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) evutil_timersub(&ev->ev_timeout, &now, tv); 8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(tv->tv_sec >= 0); 8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(tv->tv_usec >= 0); 8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_debug(("timeout_next: in %ld seconds", tv->tv_sec)); 8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (0); 8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Determines if the time is running backwards by comparing the current 8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * time against the last time we checked. Not needed when using clock 8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * monotonic. 8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void 8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)timeout_correct(struct event_base *base, struct timeval *tv) 8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct event **pev; 8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int size; 8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct timeval off; 8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (use_monotonic) 8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Check if time is running backwards */ 8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gettime(base, tv); 8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (evutil_timercmp(tv, &base->event_tv, >=)) { 8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base->event_tv = *tv; 8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_debug(("%s: time is running backwards, corrected", 8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __func__)); 8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) evutil_timersub(&base->event_tv, tv, &off); 8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * We can modify the key element of the node without destroying 8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the key, beause we apply it to all in the right order. 8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pev = base->timeheap.p; 8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size = base->timeheap.n; 8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (; size-- > 0; ++pev) { 8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct timeval *ev_tv = &(**pev).ev_timeout; 8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) evutil_timersub(ev_tv, &off, ev_tv); 8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Now remember what the new time turned out to be. */ 8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base->event_tv = *tv; 8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void 8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)timeout_process(struct event_base *base) 8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct timeval now; 8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct event *ev; 8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (min_heap_empty(&base->timeheap)) 8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gettime(base, &now); 8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while ((ev = min_heap_top(&base->timeheap))) { 8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (evutil_timercmp(&ev->ev_timeout, &now, >)) 9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* delete this event from the I/O queues */ 9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_del(ev); 9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_debug(("timeout_process: call %p", 9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ev->ev_callback)); 9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_active(ev, EV_TIMEOUT, 1); 9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void 9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)event_queue_remove(struct event_base *base, struct event *ev, int queue) 9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!(ev->ev_flags & queue)) 9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_errx(1, "%s: %p(fd %d) not on queue %x", __func__, 9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ev, ev->ev_fd, queue); 9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (~ev->ev_flags & EVLIST_INTERNAL) 9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base->event_count--; 9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ev->ev_flags &= ~queue; 9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (queue) { 9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case EVLIST_INSERTED: 9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TAILQ_REMOVE(&base->eventqueue, ev, ev_next); 9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case EVLIST_ACTIVE: 9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base->event_count_active--; 9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TAILQ_REMOVE(base->activequeues[ev->ev_pri], 9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ev, ev_active_next); 9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case EVLIST_TIMEOUT: 9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) min_heap_erase(&base->timeheap, ev); 9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_errx(1, "%s: unknown queue %x", __func__, queue); 9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void 9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)event_queue_insert(struct event_base *base, struct event *ev, int queue) 9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ev->ev_flags & queue) { 9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Double insertion is possible for active events */ 9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (queue & EVLIST_ACTIVE) 9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_errx(1, "%s: %p(fd %d) already on queue %x", __func__, 9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ev, ev->ev_fd, queue); 9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (~ev->ev_flags & EVLIST_INTERNAL) 9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base->event_count++; 9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ev->ev_flags |= queue; 9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (queue) { 9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case EVLIST_INSERTED: 9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TAILQ_INSERT_TAIL(&base->eventqueue, ev, ev_next); 9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case EVLIST_ACTIVE: 9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base->event_count_active++; 9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TAILQ_INSERT_TAIL(base->activequeues[ev->ev_pri], 9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ev,ev_active_next); 9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case EVLIST_TIMEOUT: { 9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) min_heap_push(&base->timeheap, ev); 9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_errx(1, "%s: unknown queue %x", __func__, queue); 9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Functions for debugging */ 9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char * 9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)event_get_version(void) 9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (VERSION); 9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * No thread-safe interface needed - the information should be the same 9835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * for all threads. 9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char * 9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)event_get_method(void) 9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (current_base->evsel->name); 9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 991