12b15cb3dSCy Schubert /* 22b15cb3dSCy Schubert * Copyright (c) 2000-2007 Niels Provos <provos@citi.umich.edu> 32b15cb3dSCy Schubert * Copyright (c) 2007-2012 Niels Provos and Nick Mathewson 42b15cb3dSCy Schubert * 52b15cb3dSCy Schubert * Redistribution and use in source and binary forms, with or without 62b15cb3dSCy Schubert * modification, are permitted provided that the following conditions 72b15cb3dSCy Schubert * are met: 82b15cb3dSCy Schubert * 1. Redistributions of source code must retain the above copyright 92b15cb3dSCy Schubert * notice, this list of conditions and the following disclaimer. 102b15cb3dSCy Schubert * 2. Redistributions in binary form must reproduce the above copyright 112b15cb3dSCy Schubert * notice, this list of conditions and the following disclaimer in the 122b15cb3dSCy Schubert * documentation and/or other materials provided with the distribution. 132b15cb3dSCy Schubert * 3. The name of the author may not be used to endorse or promote products 142b15cb3dSCy Schubert * derived from this software without specific prior written permission. 152b15cb3dSCy Schubert * 162b15cb3dSCy Schubert * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 172b15cb3dSCy Schubert * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 182b15cb3dSCy Schubert * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 192b15cb3dSCy Schubert * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 202b15cb3dSCy Schubert * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 212b15cb3dSCy Schubert * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 222b15cb3dSCy Schubert * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 232b15cb3dSCy Schubert * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 242b15cb3dSCy Schubert * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 252b15cb3dSCy Schubert * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 262b15cb3dSCy Schubert */ 272b15cb3dSCy Schubert #ifndef EVENT_INTERNAL_H_INCLUDED_ 282b15cb3dSCy Schubert #define EVENT_INTERNAL_H_INCLUDED_ 292b15cb3dSCy Schubert 302b15cb3dSCy Schubert #ifdef __cplusplus 312b15cb3dSCy Schubert extern "C" { 322b15cb3dSCy Schubert #endif 332b15cb3dSCy Schubert 342b15cb3dSCy Schubert #include "event2/event-config.h" 352b15cb3dSCy Schubert #include "evconfig-private.h" 362b15cb3dSCy Schubert 372b15cb3dSCy Schubert #include <time.h> 382b15cb3dSCy Schubert #include <sys/queue.h> 392b15cb3dSCy Schubert #include "event2/event_struct.h" 402b15cb3dSCy Schubert #include "minheap-internal.h" 412b15cb3dSCy Schubert #include "evsignal-internal.h" 422b15cb3dSCy Schubert #include "mm-internal.h" 432b15cb3dSCy Schubert #include "defer-internal.h" 442b15cb3dSCy Schubert 452b15cb3dSCy Schubert /* map union members back */ 462b15cb3dSCy Schubert 472b15cb3dSCy Schubert /* mutually exclusive */ 482b15cb3dSCy Schubert #define ev_signal_next ev_.ev_signal.ev_signal_next 492b15cb3dSCy Schubert #define ev_io_next ev_.ev_io.ev_io_next 502b15cb3dSCy Schubert #define ev_io_timeout ev_.ev_io.ev_timeout 512b15cb3dSCy Schubert 522b15cb3dSCy Schubert /* used only by signals */ 532b15cb3dSCy Schubert #define ev_ncalls ev_.ev_signal.ev_ncalls 542b15cb3dSCy Schubert #define ev_pncalls ev_.ev_signal.ev_pncalls 552b15cb3dSCy Schubert 562b15cb3dSCy Schubert #define ev_pri ev_evcallback.evcb_pri 572b15cb3dSCy Schubert #define ev_flags ev_evcallback.evcb_flags 582b15cb3dSCy Schubert #define ev_closure ev_evcallback.evcb_closure 592b15cb3dSCy Schubert #define ev_callback ev_evcallback.evcb_cb_union.evcb_callback 602b15cb3dSCy Schubert #define ev_arg ev_evcallback.evcb_arg 612b15cb3dSCy Schubert 622b15cb3dSCy Schubert /** @name Event closure codes 632b15cb3dSCy Schubert 642b15cb3dSCy Schubert Possible values for evcb_closure in struct event_callback 652b15cb3dSCy Schubert 662b15cb3dSCy Schubert @{ 672b15cb3dSCy Schubert */ 682b15cb3dSCy Schubert /** A regular event. Uses the evcb_callback callback */ 692b15cb3dSCy Schubert #define EV_CLOSURE_EVENT 0 702b15cb3dSCy Schubert /** A signal event. Uses the evcb_callback callback */ 712b15cb3dSCy Schubert #define EV_CLOSURE_EVENT_SIGNAL 1 722b15cb3dSCy Schubert /** A persistent non-signal event. Uses the evcb_callback callback */ 732b15cb3dSCy Schubert #define EV_CLOSURE_EVENT_PERSIST 2 742b15cb3dSCy Schubert /** A simple callback. Uses the evcb_selfcb callback. */ 752b15cb3dSCy Schubert #define EV_CLOSURE_CB_SELF 3 762b15cb3dSCy Schubert /** A finalizing callback. Uses the evcb_cbfinalize callback. */ 772b15cb3dSCy Schubert #define EV_CLOSURE_CB_FINALIZE 4 782b15cb3dSCy Schubert /** A finalizing event. Uses the evcb_evfinalize callback. */ 792b15cb3dSCy Schubert #define EV_CLOSURE_EVENT_FINALIZE 5 802b15cb3dSCy Schubert /** A finalizing event that should get freed after. Uses the evcb_evfinalize 812b15cb3dSCy Schubert * callback. */ 822b15cb3dSCy Schubert #define EV_CLOSURE_EVENT_FINALIZE_FREE 6 832b15cb3dSCy Schubert /** @} */ 842b15cb3dSCy Schubert 852b15cb3dSCy Schubert /** Structure to define the backend of a given event_base. */ 862b15cb3dSCy Schubert struct eventop { 872b15cb3dSCy Schubert /** The name of this backend. */ 882b15cb3dSCy Schubert const char *name; 892b15cb3dSCy Schubert /** Function to set up an event_base to use this backend. It should 902b15cb3dSCy Schubert * create a new structure holding whatever information is needed to 912b15cb3dSCy Schubert * run the backend, and return it. The returned pointer will get 922b15cb3dSCy Schubert * stored by event_init into the event_base.evbase field. On failure, 932b15cb3dSCy Schubert * this function should return NULL. */ 942b15cb3dSCy Schubert void *(*init)(struct event_base *); 952b15cb3dSCy Schubert /** Enable reading/writing on a given fd or signal. 'events' will be 962b15cb3dSCy Schubert * the events that we're trying to enable: one or more of EV_READ, 972b15cb3dSCy Schubert * EV_WRITE, EV_SIGNAL, and EV_ET. 'old' will be those events that 982b15cb3dSCy Schubert * were enabled on this fd previously. 'fdinfo' will be a structure 992b15cb3dSCy Schubert * associated with the fd by the evmap; its size is defined by the 1002b15cb3dSCy Schubert * fdinfo field below. It will be set to 0 the first time the fd is 1012b15cb3dSCy Schubert * added. The function should return 0 on success and -1 on error. 1022b15cb3dSCy Schubert */ 1032b15cb3dSCy Schubert int (*add)(struct event_base *, evutil_socket_t fd, short old, short events, void *fdinfo); 1042b15cb3dSCy Schubert /** As "add", except 'events' contains the events we mean to disable. */ 1052b15cb3dSCy Schubert int (*del)(struct event_base *, evutil_socket_t fd, short old, short events, void *fdinfo); 1062b15cb3dSCy Schubert /** Function to implement the core of an event loop. It must see which 1072b15cb3dSCy Schubert added events are ready, and cause event_active to be called for each 1082b15cb3dSCy Schubert active event (usually via event_io_active or such). It should 1092b15cb3dSCy Schubert return 0 on success and -1 on error. 1102b15cb3dSCy Schubert */ 1112b15cb3dSCy Schubert int (*dispatch)(struct event_base *, struct timeval *); 1122b15cb3dSCy Schubert /** Function to clean up and free our data from the event_base. */ 1132b15cb3dSCy Schubert void (*dealloc)(struct event_base *); 1142b15cb3dSCy Schubert /** Flag: set if we need to reinitialize the event base after we fork. 1152b15cb3dSCy Schubert */ 1162b15cb3dSCy Schubert int need_reinit; 1172b15cb3dSCy Schubert /** Bit-array of supported event_method_features that this backend can 1182b15cb3dSCy Schubert * provide. */ 1192b15cb3dSCy Schubert enum event_method_feature features; 1202b15cb3dSCy Schubert /** Length of the extra information we should record for each fd that 1212b15cb3dSCy Schubert has one or more active events. This information is recorded 1222b15cb3dSCy Schubert as part of the evmap entry for each fd, and passed as an argument 1232b15cb3dSCy Schubert to the add and del functions above. 1242b15cb3dSCy Schubert */ 1252b15cb3dSCy Schubert size_t fdinfo_len; 1262b15cb3dSCy Schubert }; 1272b15cb3dSCy Schubert 1282b15cb3dSCy Schubert #ifdef _WIN32 1292b15cb3dSCy Schubert /* If we're on win32, then file descriptors are not nice low densely packed 1302b15cb3dSCy Schubert integers. Instead, they are pointer-like windows handles, and we want to 1312b15cb3dSCy Schubert use a hashtable instead of an array to map fds to events. 1322b15cb3dSCy Schubert */ 1332b15cb3dSCy Schubert #define EVMAP_USE_HT 1342b15cb3dSCy Schubert #endif 1352b15cb3dSCy Schubert 1362b15cb3dSCy Schubert /* #define HT_CACHE_HASH_VALS */ 1372b15cb3dSCy Schubert 1382b15cb3dSCy Schubert #ifdef EVMAP_USE_HT 1392b15cb3dSCy Schubert #define HT_NO_CACHE_HASH_VALUES 1402b15cb3dSCy Schubert #include "ht-internal.h" 1412b15cb3dSCy Schubert struct event_map_entry; 1422b15cb3dSCy Schubert HT_HEAD(event_io_map, event_map_entry); 1432b15cb3dSCy Schubert #else 1442b15cb3dSCy Schubert #define event_io_map event_signal_map 1452b15cb3dSCy Schubert #endif 1462b15cb3dSCy Schubert 1472b15cb3dSCy Schubert /* Used to map signal numbers to a list of events. If EVMAP_USE_HT is not 1482b15cb3dSCy Schubert defined, this structure is also used as event_io_map, which maps fds to a 1492b15cb3dSCy Schubert list of events. 1502b15cb3dSCy Schubert */ 1512b15cb3dSCy Schubert struct event_signal_map { 1522b15cb3dSCy Schubert /* An array of evmap_io * or of evmap_signal *; empty entries are 1532b15cb3dSCy Schubert * set to NULL. */ 1542b15cb3dSCy Schubert void **entries; 1552b15cb3dSCy Schubert /* The number of entries available in entries */ 1562b15cb3dSCy Schubert int nentries; 1572b15cb3dSCy Schubert }; 1582b15cb3dSCy Schubert 1592b15cb3dSCy Schubert /* A list of events waiting on a given 'common' timeout value. Ordinarily, 1602b15cb3dSCy Schubert * events waiting for a timeout wait on a minheap. Sometimes, however, a 1612b15cb3dSCy Schubert * queue can be faster. 1622b15cb3dSCy Schubert **/ 1632b15cb3dSCy Schubert struct common_timeout_list { 1642b15cb3dSCy Schubert /* List of events currently waiting in the queue. */ 1652b15cb3dSCy Schubert struct event_list events; 1662b15cb3dSCy Schubert /* 'magic' timeval used to indicate the duration of events in this 1672b15cb3dSCy Schubert * queue. */ 1682b15cb3dSCy Schubert struct timeval duration; 1692b15cb3dSCy Schubert /* Event that triggers whenever one of the events in the queue is 1702b15cb3dSCy Schubert * ready to activate */ 1712b15cb3dSCy Schubert struct event timeout_event; 1722b15cb3dSCy Schubert /* The event_base that this timeout list is part of */ 1732b15cb3dSCy Schubert struct event_base *base; 1742b15cb3dSCy Schubert }; 1752b15cb3dSCy Schubert 1762b15cb3dSCy Schubert /** Mask used to get the real tv_usec value from a common timeout. */ 1772b15cb3dSCy Schubert #define COMMON_TIMEOUT_MICROSECONDS_MASK 0x000fffff 1782b15cb3dSCy Schubert 1792b15cb3dSCy Schubert struct event_change; 1802b15cb3dSCy Schubert 1812b15cb3dSCy Schubert /* List of 'changes' since the last call to eventop.dispatch. Only maintained 1822b15cb3dSCy Schubert * if the backend is using changesets. */ 1832b15cb3dSCy Schubert struct event_changelist { 1842b15cb3dSCy Schubert struct event_change *changes; 1852b15cb3dSCy Schubert int n_changes; 1862b15cb3dSCy Schubert int changes_size; 1872b15cb3dSCy Schubert }; 1882b15cb3dSCy Schubert 1892b15cb3dSCy Schubert #ifndef EVENT__DISABLE_DEBUG_MODE 1902b15cb3dSCy Schubert /* Global internal flag: set to one if debug mode is on. */ 1912b15cb3dSCy Schubert extern int event_debug_mode_on_; 1922b15cb3dSCy Schubert #define EVENT_DEBUG_MODE_IS_ON() (event_debug_mode_on_) 1932b15cb3dSCy Schubert #else 1942b15cb3dSCy Schubert #define EVENT_DEBUG_MODE_IS_ON() (0) 1952b15cb3dSCy Schubert #endif 1962b15cb3dSCy Schubert 1972b15cb3dSCy Schubert TAILQ_HEAD(evcallback_list, event_callback); 1982b15cb3dSCy Schubert 1992b15cb3dSCy Schubert /* Sets up an event for processing once */ 2002b15cb3dSCy Schubert struct event_once { 2012b15cb3dSCy Schubert LIST_ENTRY(event_once) next_once; 2022b15cb3dSCy Schubert struct event ev; 2032b15cb3dSCy Schubert 2042b15cb3dSCy Schubert void (*cb)(evutil_socket_t, short, void *); 2052b15cb3dSCy Schubert void *arg; 2062b15cb3dSCy Schubert }; 2072b15cb3dSCy Schubert 2082b15cb3dSCy Schubert struct event_base { 2092b15cb3dSCy Schubert /** Function pointers and other data to describe this event_base's 2102b15cb3dSCy Schubert * backend. */ 2112b15cb3dSCy Schubert const struct eventop *evsel; 2122b15cb3dSCy Schubert /** Pointer to backend-specific data. */ 2132b15cb3dSCy Schubert void *evbase; 2142b15cb3dSCy Schubert 2152b15cb3dSCy Schubert /** List of changes to tell backend about at next dispatch. Only used 2162b15cb3dSCy Schubert * by the O(1) backends. */ 2172b15cb3dSCy Schubert struct event_changelist changelist; 2182b15cb3dSCy Schubert 2192b15cb3dSCy Schubert /** Function pointers used to describe the backend that this event_base 2202b15cb3dSCy Schubert * uses for signals */ 2212b15cb3dSCy Schubert const struct eventop *evsigsel; 222*a466cc55SCy Schubert /** Data to implement the common signal handler code. */ 2232b15cb3dSCy Schubert struct evsig_info sig; 2242b15cb3dSCy Schubert 2252b15cb3dSCy Schubert /** Number of virtual events */ 2262b15cb3dSCy Schubert int virtual_event_count; 2272b15cb3dSCy Schubert /** Maximum number of virtual events active */ 2282b15cb3dSCy Schubert int virtual_event_count_max; 2292b15cb3dSCy Schubert /** Number of total events added to this event_base */ 2302b15cb3dSCy Schubert int event_count; 2312b15cb3dSCy Schubert /** Maximum number of total events added to this event_base */ 2322b15cb3dSCy Schubert int event_count_max; 2332b15cb3dSCy Schubert /** Number of total events active in this event_base */ 2342b15cb3dSCy Schubert int event_count_active; 2352b15cb3dSCy Schubert /** Maximum number of total events active in this event_base */ 2362b15cb3dSCy Schubert int event_count_active_max; 2372b15cb3dSCy Schubert 2382b15cb3dSCy Schubert /** Set if we should terminate the loop once we're done processing 2392b15cb3dSCy Schubert * events. */ 2402b15cb3dSCy Schubert int event_gotterm; 2412b15cb3dSCy Schubert /** Set if we should terminate the loop immediately */ 2422b15cb3dSCy Schubert int event_break; 2432b15cb3dSCy Schubert /** Set if we should start a new instance of the loop immediately. */ 2442b15cb3dSCy Schubert int event_continue; 2452b15cb3dSCy Schubert 2462b15cb3dSCy Schubert /** The currently running priority of events */ 2472b15cb3dSCy Schubert int event_running_priority; 2482b15cb3dSCy Schubert 2492b15cb3dSCy Schubert /** Set if we're running the event_base_loop function, to prevent 2502b15cb3dSCy Schubert * reentrant invocation. */ 2512b15cb3dSCy Schubert int running_loop; 2522b15cb3dSCy Schubert 2532b15cb3dSCy Schubert /** Set to the number of deferred_cbs we've made 'active' in the 2542b15cb3dSCy Schubert * loop. This is a hack to prevent starvation; it would be smarter 2552b15cb3dSCy Schubert * to just use event_config_set_max_dispatch_interval's max_callbacks 2562b15cb3dSCy Schubert * feature */ 2572b15cb3dSCy Schubert int n_deferreds_queued; 2582b15cb3dSCy Schubert 2592b15cb3dSCy Schubert /* Active event management. */ 2602b15cb3dSCy Schubert /** An array of nactivequeues queues for active event_callbacks (ones 2612b15cb3dSCy Schubert * that have triggered, and whose callbacks need to be called). Low 2622b15cb3dSCy Schubert * priority numbers are more important, and stall higher ones. 2632b15cb3dSCy Schubert */ 2642b15cb3dSCy Schubert struct evcallback_list *activequeues; 2652b15cb3dSCy Schubert /** The length of the activequeues array */ 2662b15cb3dSCy Schubert int nactivequeues; 2672b15cb3dSCy Schubert /** A list of event_callbacks that should become active the next time 2682b15cb3dSCy Schubert * we process events, but not this time. */ 2692b15cb3dSCy Schubert struct evcallback_list active_later_queue; 2702b15cb3dSCy Schubert 2712b15cb3dSCy Schubert /* common timeout logic */ 2722b15cb3dSCy Schubert 2732b15cb3dSCy Schubert /** An array of common_timeout_list* for all of the common timeout 2742b15cb3dSCy Schubert * values we know. */ 2752b15cb3dSCy Schubert struct common_timeout_list **common_timeout_queues; 2762b15cb3dSCy Schubert /** The number of entries used in common_timeout_queues */ 2772b15cb3dSCy Schubert int n_common_timeouts; 2782b15cb3dSCy Schubert /** The total size of common_timeout_queues. */ 2792b15cb3dSCy Schubert int n_common_timeouts_allocated; 2802b15cb3dSCy Schubert 2812b15cb3dSCy Schubert /** Mapping from file descriptors to enabled (added) events */ 2822b15cb3dSCy Schubert struct event_io_map io; 2832b15cb3dSCy Schubert 2842b15cb3dSCy Schubert /** Mapping from signal numbers to enabled (added) events. */ 2852b15cb3dSCy Schubert struct event_signal_map sigmap; 2862b15cb3dSCy Schubert 2872b15cb3dSCy Schubert /** Priority queue of events with timeouts. */ 2882b15cb3dSCy Schubert struct min_heap timeheap; 2892b15cb3dSCy Schubert 2902b15cb3dSCy Schubert /** Stored timeval: used to avoid calling gettimeofday/clock_gettime 2912b15cb3dSCy Schubert * too often. */ 2922b15cb3dSCy Schubert struct timeval tv_cache; 2932b15cb3dSCy Schubert 2942b15cb3dSCy Schubert struct evutil_monotonic_timer monotonic_timer; 2952b15cb3dSCy Schubert 2962b15cb3dSCy Schubert /** Difference between internal time (maybe from clock_gettime) and 2972b15cb3dSCy Schubert * gettimeofday. */ 2982b15cb3dSCy Schubert struct timeval tv_clock_diff; 2992b15cb3dSCy Schubert /** Second in which we last updated tv_clock_diff, in monotonic time. */ 3002b15cb3dSCy Schubert time_t last_updated_clock_diff; 3012b15cb3dSCy Schubert 3022b15cb3dSCy Schubert #ifndef EVENT__DISABLE_THREAD_SUPPORT 3032b15cb3dSCy Schubert /* threading support */ 3042b15cb3dSCy Schubert /** The thread currently running the event_loop for this base */ 3052b15cb3dSCy Schubert unsigned long th_owner_id; 3062b15cb3dSCy Schubert /** A lock to prevent conflicting accesses to this event_base */ 3072b15cb3dSCy Schubert void *th_base_lock; 3082b15cb3dSCy Schubert /** A condition that gets signalled when we're done processing an 3092b15cb3dSCy Schubert * event with waiters on it. */ 3102b15cb3dSCy Schubert void *current_event_cond; 3112b15cb3dSCy Schubert /** Number of threads blocking on current_event_cond. */ 3122b15cb3dSCy Schubert int current_event_waiters; 3132b15cb3dSCy Schubert #endif 3142b15cb3dSCy Schubert /** The event whose callback is executing right now */ 3152b15cb3dSCy Schubert struct event_callback *current_event; 3162b15cb3dSCy Schubert 3172b15cb3dSCy Schubert #ifdef _WIN32 3182b15cb3dSCy Schubert /** IOCP support structure, if IOCP is enabled. */ 3192b15cb3dSCy Schubert struct event_iocp_port *iocp; 3202b15cb3dSCy Schubert #endif 3212b15cb3dSCy Schubert 3222b15cb3dSCy Schubert /** Flags that this base was configured with */ 3232b15cb3dSCy Schubert enum event_base_config_flag flags; 3242b15cb3dSCy Schubert 3252b15cb3dSCy Schubert struct timeval max_dispatch_time; 3262b15cb3dSCy Schubert int max_dispatch_callbacks; 3272b15cb3dSCy Schubert int limit_callbacks_after_prio; 3282b15cb3dSCy Schubert 3292b15cb3dSCy Schubert /* Notify main thread to wake up break, etc. */ 3302b15cb3dSCy Schubert /** True if the base already has a pending notify, and we don't need 3312b15cb3dSCy Schubert * to add any more. */ 3322b15cb3dSCy Schubert int is_notify_pending; 3332b15cb3dSCy Schubert /** A socketpair used by some th_notify functions to wake up the main 3342b15cb3dSCy Schubert * thread. */ 3352b15cb3dSCy Schubert evutil_socket_t th_notify_fd[2]; 3362b15cb3dSCy Schubert /** An event used by some th_notify functions to wake up the main 3372b15cb3dSCy Schubert * thread. */ 3382b15cb3dSCy Schubert struct event th_notify; 3392b15cb3dSCy Schubert /** A function used to wake up the main thread from another thread. */ 3402b15cb3dSCy Schubert int (*th_notify_fn)(struct event_base *base); 3412b15cb3dSCy Schubert 3422b15cb3dSCy Schubert /** Saved seed for weak random number generator. Some backends use 3432b15cb3dSCy Schubert * this to produce fairness among sockets. Protected by th_base_lock. */ 3442b15cb3dSCy Schubert struct evutil_weakrand_state weakrand_seed; 3452b15cb3dSCy Schubert 3462b15cb3dSCy Schubert /** List of event_onces that have not yet fired. */ 3472b15cb3dSCy Schubert LIST_HEAD(once_event_list, event_once) once_events; 3482b15cb3dSCy Schubert 3492b15cb3dSCy Schubert }; 3502b15cb3dSCy Schubert 3512b15cb3dSCy Schubert struct event_config_entry { 3522b15cb3dSCy Schubert TAILQ_ENTRY(event_config_entry) next; 3532b15cb3dSCy Schubert 3542b15cb3dSCy Schubert const char *avoid_method; 3552b15cb3dSCy Schubert }; 3562b15cb3dSCy Schubert 3572b15cb3dSCy Schubert /** Internal structure: describes the configuration we want for an event_base 3582b15cb3dSCy Schubert * that we're about to allocate. */ 3592b15cb3dSCy Schubert struct event_config { 3602b15cb3dSCy Schubert TAILQ_HEAD(event_configq, event_config_entry) entries; 3612b15cb3dSCy Schubert 3622b15cb3dSCy Schubert int n_cpus_hint; 3632b15cb3dSCy Schubert struct timeval max_dispatch_interval; 3642b15cb3dSCy Schubert int max_dispatch_callbacks; 3652b15cb3dSCy Schubert int limit_callbacks_after_prio; 3662b15cb3dSCy Schubert enum event_method_feature require_features; 3672b15cb3dSCy Schubert enum event_base_config_flag flags; 3682b15cb3dSCy Schubert }; 3692b15cb3dSCy Schubert 3702b15cb3dSCy Schubert /* Internal use only: Functions that might be missing from <sys/queue.h> */ 371*a466cc55SCy Schubert #ifndef LIST_END 372*a466cc55SCy Schubert #define LIST_END(head) NULL 373*a466cc55SCy Schubert #endif 374*a466cc55SCy Schubert 3752b15cb3dSCy Schubert #ifndef TAILQ_FIRST 3762b15cb3dSCy Schubert #define TAILQ_FIRST(head) ((head)->tqh_first) 3772b15cb3dSCy Schubert #endif 3782b15cb3dSCy Schubert #ifndef TAILQ_END 3792b15cb3dSCy Schubert #define TAILQ_END(head) NULL 3802b15cb3dSCy Schubert #endif 3812b15cb3dSCy Schubert #ifndef TAILQ_NEXT 3822b15cb3dSCy Schubert #define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next) 3832b15cb3dSCy Schubert #endif 3842b15cb3dSCy Schubert 3852b15cb3dSCy Schubert #ifndef TAILQ_FOREACH 3862b15cb3dSCy Schubert #define TAILQ_FOREACH(var, head, field) \ 3872b15cb3dSCy Schubert for ((var) = TAILQ_FIRST(head); \ 3882b15cb3dSCy Schubert (var) != TAILQ_END(head); \ 3892b15cb3dSCy Schubert (var) = TAILQ_NEXT(var, field)) 3902b15cb3dSCy Schubert #endif 3912b15cb3dSCy Schubert 3922b15cb3dSCy Schubert #ifndef TAILQ_INSERT_BEFORE 3932b15cb3dSCy Schubert #define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \ 3942b15cb3dSCy Schubert (elm)->field.tqe_prev = (listelm)->field.tqe_prev; \ 3952b15cb3dSCy Schubert (elm)->field.tqe_next = (listelm); \ 3962b15cb3dSCy Schubert *(listelm)->field.tqe_prev = (elm); \ 3972b15cb3dSCy Schubert (listelm)->field.tqe_prev = &(elm)->field.tqe_next; \ 3982b15cb3dSCy Schubert } while (0) 3992b15cb3dSCy Schubert #endif 4002b15cb3dSCy Schubert 4012b15cb3dSCy Schubert #define N_ACTIVE_CALLBACKS(base) \ 4022b15cb3dSCy Schubert ((base)->event_count_active) 4032b15cb3dSCy Schubert 4042b15cb3dSCy Schubert int evsig_set_handler_(struct event_base *base, int evsignal, 4052b15cb3dSCy Schubert void (*fn)(int)); 4062b15cb3dSCy Schubert int evsig_restore_handler_(struct event_base *base, int evsignal); 4072b15cb3dSCy Schubert 4082b15cb3dSCy Schubert int event_add_nolock_(struct event *ev, 4092b15cb3dSCy Schubert const struct timeval *tv, int tv_is_absolute); 4102b15cb3dSCy Schubert /** Argument for event_del_nolock_. Tells event_del not to block on the event 4112b15cb3dSCy Schubert * if it's running in another thread. */ 4122b15cb3dSCy Schubert #define EVENT_DEL_NOBLOCK 0 4132b15cb3dSCy Schubert /** Argument for event_del_nolock_. Tells event_del to block on the event 4142b15cb3dSCy Schubert * if it's running in another thread, regardless of its value for EV_FINALIZE 4152b15cb3dSCy Schubert */ 4162b15cb3dSCy Schubert #define EVENT_DEL_BLOCK 1 4172b15cb3dSCy Schubert /** Argument for event_del_nolock_. Tells event_del to block on the event 4182b15cb3dSCy Schubert * if it is running in another thread and it doesn't have EV_FINALIZE set. 4192b15cb3dSCy Schubert */ 4202b15cb3dSCy Schubert #define EVENT_DEL_AUTOBLOCK 2 421*a466cc55SCy Schubert /** Argument for event_del_nolock_. Tells event_del to proceed even if the 4222b15cb3dSCy Schubert * event is set up for finalization rather for regular use.*/ 4232b15cb3dSCy Schubert #define EVENT_DEL_EVEN_IF_FINALIZING 3 4242b15cb3dSCy Schubert int event_del_nolock_(struct event *ev, int blocking); 4252b15cb3dSCy Schubert int event_remove_timer_nolock_(struct event *ev); 4262b15cb3dSCy Schubert 4272b15cb3dSCy Schubert void event_active_nolock_(struct event *ev, int res, short count); 428*a466cc55SCy Schubert EVENT2_EXPORT_SYMBOL 4292b15cb3dSCy Schubert int event_callback_activate_(struct event_base *, struct event_callback *); 4302b15cb3dSCy Schubert int event_callback_activate_nolock_(struct event_base *, struct event_callback *); 4312b15cb3dSCy Schubert int event_callback_cancel_(struct event_base *base, 4322b15cb3dSCy Schubert struct event_callback *evcb); 4332b15cb3dSCy Schubert 4342b15cb3dSCy Schubert void event_callback_finalize_nolock_(struct event_base *base, unsigned flags, struct event_callback *evcb, void (*cb)(struct event_callback *, void *)); 435*a466cc55SCy Schubert EVENT2_EXPORT_SYMBOL 4362b15cb3dSCy Schubert void event_callback_finalize_(struct event_base *base, unsigned flags, struct event_callback *evcb, void (*cb)(struct event_callback *, void *)); 4372b15cb3dSCy Schubert int event_callback_finalize_many_(struct event_base *base, int n_cbs, struct event_callback **evcb, void (*cb)(struct event_callback *, void *)); 4382b15cb3dSCy Schubert 4392b15cb3dSCy Schubert 440*a466cc55SCy Schubert EVENT2_EXPORT_SYMBOL 4412b15cb3dSCy Schubert void event_active_later_(struct event *ev, int res); 4422b15cb3dSCy Schubert void event_active_later_nolock_(struct event *ev, int res); 443*a466cc55SCy Schubert int event_callback_activate_later_nolock_(struct event_base *base, 4442b15cb3dSCy Schubert struct event_callback *evcb); 4452b15cb3dSCy Schubert int event_callback_cancel_nolock_(struct event_base *base, 4462b15cb3dSCy Schubert struct event_callback *evcb, int even_if_finalizing); 4472b15cb3dSCy Schubert void event_callback_init_(struct event_base *base, 4482b15cb3dSCy Schubert struct event_callback *cb); 4492b15cb3dSCy Schubert 4502b15cb3dSCy Schubert /* FIXME document. */ 451*a466cc55SCy Schubert EVENT2_EXPORT_SYMBOL 4522b15cb3dSCy Schubert void event_base_add_virtual_(struct event_base *base); 4532b15cb3dSCy Schubert void event_base_del_virtual_(struct event_base *base); 4542b15cb3dSCy Schubert 4552b15cb3dSCy Schubert /** For debugging: unless assertions are disabled, verify the referential 4562b15cb3dSCy Schubert integrity of the internal data structures of 'base'. This operation can 4572b15cb3dSCy Schubert be expensive. 4582b15cb3dSCy Schubert 4592b15cb3dSCy Schubert Returns on success; aborts on failure. 4602b15cb3dSCy Schubert */ 461*a466cc55SCy Schubert EVENT2_EXPORT_SYMBOL 4622b15cb3dSCy Schubert void event_base_assert_ok_(struct event_base *base); 4632b15cb3dSCy Schubert void event_base_assert_ok_nolock_(struct event_base *base); 4642b15cb3dSCy Schubert 4652b15cb3dSCy Schubert 4662b15cb3dSCy Schubert /* Helper function: Call 'fn' exactly once every inserted or active event in 4672b15cb3dSCy Schubert * the event_base 'base'. 4682b15cb3dSCy Schubert * 4692b15cb3dSCy Schubert * If fn returns 0, continue on to the next event. Otherwise, return the same 4702b15cb3dSCy Schubert * value that fn returned. 4712b15cb3dSCy Schubert * 4722b15cb3dSCy Schubert * Requires that 'base' be locked. 4732b15cb3dSCy Schubert */ 4742b15cb3dSCy Schubert int event_base_foreach_event_nolock_(struct event_base *base, 4752b15cb3dSCy Schubert event_base_foreach_event_cb cb, void *arg); 4762b15cb3dSCy Schubert 477*a466cc55SCy Schubert /* Cleanup function to reset debug mode during shutdown. 478*a466cc55SCy Schubert * 479*a466cc55SCy Schubert * Calling this function doesn't mean it'll be possible to re-enable 480*a466cc55SCy Schubert * debug mode if any events were added. 481*a466cc55SCy Schubert */ 482*a466cc55SCy Schubert void event_disable_debug_mode(void); 483*a466cc55SCy Schubert 4842b15cb3dSCy Schubert #ifdef __cplusplus 4852b15cb3dSCy Schubert } 4862b15cb3dSCy Schubert #endif 4872b15cb3dSCy Schubert 4882b15cb3dSCy Schubert #endif /* EVENT_INTERNAL_H_INCLUDED_ */ 489