18773c4c9SNiels Provos /* 2b85b710cSNick Mathewson * Copyright (c) 2000-2007 Niels Provos <[email protected]> 3e49e2891SNick Mathewson * Copyright (c) 2007-2012 Niels Provos and Nick Mathewson 48773c4c9SNiels Provos * 58773c4c9SNiels Provos * Redistribution and use in source and binary forms, with or without 68773c4c9SNiels Provos * modification, are permitted provided that the following conditions 78773c4c9SNiels Provos * are met: 88773c4c9SNiels Provos * 1. Redistributions of source code must retain the above copyright 98773c4c9SNiels Provos * notice, this list of conditions and the following disclaimer. 108773c4c9SNiels Provos * 2. Redistributions in binary form must reproduce the above copyright 118773c4c9SNiels Provos * notice, this list of conditions and the following disclaimer in the 128773c4c9SNiels Provos * documentation and/or other materials provided with the distribution. 138773c4c9SNiels Provos * 3. The name of the author may not be used to endorse or promote products 148773c4c9SNiels Provos * derived from this software without specific prior written permission. 158773c4c9SNiels Provos * 168773c4c9SNiels Provos * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 178773c4c9SNiels Provos * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 188773c4c9SNiels Provos * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 198773c4c9SNiels Provos * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 208773c4c9SNiels Provos * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 218773c4c9SNiels Provos * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 228773c4c9SNiels Provos * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 238773c4c9SNiels Provos * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 248773c4c9SNiels Provos * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 258773c4c9SNiels Provos * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 268773c4c9SNiels Provos */ 273f8c7cd0SNick Mathewson #ifndef EVENT_INTERNAL_H_INCLUDED_ 283f8c7cd0SNick Mathewson #define EVENT_INTERNAL_H_INCLUDED_ 298773c4c9SNiels Provos 308773c4c9SNiels Provos #ifdef __cplusplus 318773c4c9SNiels Provos extern "C" { 328773c4c9SNiels Provos #endif 338773c4c9SNiels Provos 34ec347b92SNick Mathewson #include "event2/event-config.h" 350915ca0aSKevin Bowling #include "evconfig-private.h" 360915ca0aSKevin Bowling 37a459ef70SNick Mathewson #include <time.h> 38fe47003dSNick Mathewson #include <sys/queue.h> 39fe47003dSNick Mathewson #include "event2/event_struct.h" 40169321c9SNick Mathewson #include "minheap-internal.h" 41169321c9SNick Mathewson #include "evsignal-internal.h" 427eb250e9SNick Mathewson #include "mm-internal.h" 43b06b2649SNick Mathewson #include "defer-internal.h" 4441b7cbc3SNiels Provos 458c750eafSNiels Provos /* map union members back */ 468c750eafSNiels Provos 478c750eafSNiels Provos /* mutually exclusive */ 48cb9da0bfSNick Mathewson #define ev_signal_next ev_.ev_signal.ev_signal_next 49cb9da0bfSNick Mathewson #define ev_io_next ev_.ev_io.ev_io_next 50cb9da0bfSNick Mathewson #define ev_io_timeout ev_.ev_io.ev_timeout 518c750eafSNiels Provos 528c750eafSNiels Provos /* used only by signals */ 53cb9da0bfSNick Mathewson #define ev_ncalls ev_.ev_signal.ev_ncalls 54cb9da0bfSNick Mathewson #define ev_pncalls ev_.ev_signal.ev_pncalls 558c750eafSNiels Provos 56cba59e53SNick Mathewson #define ev_pri ev_evcallback.evcb_pri 57cba59e53SNick Mathewson #define ev_flags ev_evcallback.evcb_flags 58cba59e53SNick Mathewson #define ev_closure ev_evcallback.evcb_closure 59ae2b84b2SNick Mathewson #define ev_callback ev_evcallback.evcb_cb_union.evcb_callback 60cba59e53SNick Mathewson #define ev_arg ev_evcallback.evcb_arg 61cba59e53SNick Mathewson 62a800b913SNick Mathewson /** @name Event closure codes 63a800b913SNick Mathewson 64a800b913SNick Mathewson Possible values for evcb_closure in struct event_callback 65a800b913SNick Mathewson 66a800b913SNick Mathewson @{ 67a800b913SNick Mathewson */ 68a800b913SNick Mathewson /** A regular event. Uses the evcb_callback callback */ 69cba59e53SNick Mathewson #define EV_CLOSURE_EVENT 0 70a800b913SNick Mathewson /** A signal event. Uses the evcb_callback callback */ 71cba59e53SNick Mathewson #define EV_CLOSURE_EVENT_SIGNAL 1 72a800b913SNick Mathewson /** A persistent non-signal event. Uses the evcb_callback callback */ 73cba59e53SNick Mathewson #define EV_CLOSURE_EVENT_PERSIST 2 74a800b913SNick Mathewson /** A simple callback. Uses the evcb_selfcb callback. */ 75ae2b84b2SNick Mathewson #define EV_CLOSURE_CB_SELF 3 76a800b913SNick Mathewson /** A finalizing callback. Uses the evcb_cbfinalize callback. */ 778eedeabeSNick Mathewson #define EV_CLOSURE_CB_FINALIZE 4 78a800b913SNick Mathewson /** A finalizing event. Uses the evcb_evfinalize callback. */ 798eedeabeSNick Mathewson #define EV_CLOSURE_EVENT_FINALIZE 5 80a800b913SNick Mathewson /** A finalizing event that should get freed after. Uses the evcb_evfinalize 81a800b913SNick Mathewson * callback. */ 828eedeabeSNick Mathewson #define EV_CLOSURE_EVENT_FINALIZE_FREE 6 83a800b913SNick Mathewson /** @} */ 84b4886ec8SNick Mathewson 85838d0a81SNick Mathewson /** Structure to define the backend of a given event_base. */ 8688897852SNiels Provos struct eventop { 87838d0a81SNick Mathewson /** The name of this backend. */ 8888897852SNiels Provos const char *name; 89cdd4c490SNick Mathewson /** Function to set up an event_base to use this backend. It should 90cdd4c490SNick Mathewson * create a new structure holding whatever information is needed to 91cdd4c490SNick Mathewson * run the backend, and return it. The returned pointer will get 92cdd4c490SNick Mathewson * stored by event_init into the event_base.evbase field. On failure, 93cdd4c490SNick Mathewson * this function should return NULL. */ 9488897852SNiels Provos void *(*init)(struct event_base *); 95cdd4c490SNick Mathewson /** Enable reading/writing on a given fd or signal. 'events' will be 96cdd4c490SNick Mathewson * the events that we're trying to enable: one or more of EV_READ, 97cdd4c490SNick Mathewson * EV_WRITE, EV_SIGNAL, and EV_ET. 'old' will be those events that 98cdd4c490SNick Mathewson * were enabled on this fd previously. 'fdinfo' will be a structure 99cdd4c490SNick Mathewson * associated with the fd by the evmap; its size is defined by the 100cdd4c490SNick Mathewson * fdinfo field below. It will be set to 0 the first time the fd is 101cdd4c490SNick Mathewson * added. The function should return 0 on success and -1 on error. 102cdd4c490SNick Mathewson */ 103554e1493SNick Mathewson int (*add)(struct event_base *, evutil_socket_t fd, short old, short events, void *fdinfo); 104cdd4c490SNick Mathewson /** As "add", except 'events' contains the events we mean to disable. */ 105554e1493SNick Mathewson int (*del)(struct event_base *, evutil_socket_t fd, short old, short events, void *fdinfo); 106838d0a81SNick Mathewson /** Function to implement the core of an event loop. It must see which 107838d0a81SNick Mathewson added events are ready, and cause event_active to be called for each 108cdd4c490SNick Mathewson active event (usually via event_io_active or such). It should 109cdd4c490SNick Mathewson return 0 on success and -1 on error. 110838d0a81SNick Mathewson */ 11102b2b4d1SNiels Provos int (*dispatch)(struct event_base *, struct timeval *); 112838d0a81SNick Mathewson /** Function to clean up and free our data from the event_base. */ 11302b2b4d1SNiels Provos void (*dealloc)(struct event_base *); 114cdd4c490SNick Mathewson /** Flag: set if we need to reinitialize the event base after we fork. 115cdd4c490SNick Mathewson */ 11688897852SNiels Provos int need_reinit; 117cdd4c490SNick Mathewson /** Bit-array of supported event_method_features that this backend can 118cdd4c490SNick Mathewson * provide. */ 11905965921SNick Mathewson enum event_method_feature features; 120cdd4c490SNick Mathewson /** Length of the extra information we should record for each fd that 121cdd4c490SNick Mathewson has one or more active events. This information is recorded 122cdd4c490SNick Mathewson as part of the evmap entry for each fd, and passed as an argument 123cdd4c490SNick Mathewson to the add and del functions above. 124838d0a81SNick Mathewson */ 125554e1493SNick Mathewson size_t fdinfo_len; 12688897852SNiels Provos }; 12788897852SNiels Provos 1289f560bfaSNick Mathewson #ifdef _WIN32 129838d0a81SNick Mathewson /* If we're on win32, then file descriptors are not nice low densely packed 130838d0a81SNick Mathewson integers. Instead, they are pointer-like windows handles, and we want to 131838d0a81SNick Mathewson use a hashtable instead of an array to map fds to events. 132838d0a81SNick Mathewson */ 13355bcd7d2SNick Mathewson #define EVMAP_USE_HT 13455bcd7d2SNick Mathewson #endif 13555bcd7d2SNick Mathewson 136a66e947bSNick Mathewson /* #define HT_CACHE_HASH_VALS */ 137a66e947bSNick Mathewson 13855bcd7d2SNick Mathewson #ifdef EVMAP_USE_HT 13946e5bb7bSNick Mathewson #define HT_NO_CACHE_HASH_VALUES 14055bcd7d2SNick Mathewson #include "ht-internal.h" 14155bcd7d2SNick Mathewson struct event_map_entry; 14255bcd7d2SNick Mathewson HT_HEAD(event_io_map, event_map_entry); 14355bcd7d2SNick Mathewson #else 14455bcd7d2SNick Mathewson #define event_io_map event_signal_map 14555bcd7d2SNick Mathewson #endif 14655bcd7d2SNick Mathewson 14755bcd7d2SNick Mathewson /* Used to map signal numbers to a list of events. If EVMAP_USE_HT is not 148cdd4c490SNick Mathewson defined, this structure is also used as event_io_map, which maps fds to a 149cdd4c490SNick Mathewson list of events. 15055bcd7d2SNick Mathewson */ 15155bcd7d2SNick Mathewson struct event_signal_map { 152cdd4c490SNick Mathewson /* An array of evmap_io * or of evmap_signal *; empty entries are 153cdd4c490SNick Mathewson * set to NULL. */ 15430cba6d0SNiels Provos void **entries; 155cdd4c490SNick Mathewson /* The number of entries available in entries */ 15602b2b4d1SNiels Provos int nentries; 15702b2b4d1SNiels Provos }; 15802b2b4d1SNiels Provos 159cdd4c490SNick Mathewson /* A list of events waiting on a given 'common' timeout value. Ordinarily, 160cdd4c490SNick Mathewson * events waiting for a timeout wait on a minheap. Sometimes, however, a 161cdd4c490SNick Mathewson * queue can be faster. 162cdd4c490SNick Mathewson **/ 163693c24efSNick Mathewson struct common_timeout_list { 164cdd4c490SNick Mathewson /* List of events currently waiting in the queue. */ 165693c24efSNick Mathewson struct event_list events; 166cdd4c490SNick Mathewson /* 'magic' timeval used to indicate the duration of events in this 167cdd4c490SNick Mathewson * queue. */ 168693c24efSNick Mathewson struct timeval duration; 169cdd4c490SNick Mathewson /* Event that triggers whenever one of the events in the queue is 170cdd4c490SNick Mathewson * ready to activate */ 171693c24efSNick Mathewson struct event timeout_event; 172cdd4c490SNick Mathewson /* The event_base that this timeout list is part of */ 173693c24efSNick Mathewson struct event_base *base; 174693c24efSNick Mathewson }; 175693c24efSNick Mathewson 1765b18f130SNick Mathewson /** Mask used to get the real tv_usec value from a common timeout. */ 1775b18f130SNick Mathewson #define COMMON_TIMEOUT_MICROSECONDS_MASK 0x000fffff 1785b18f130SNick Mathewson 17927308aaeSNick Mathewson struct event_change; 18027308aaeSNick Mathewson 181cdd4c490SNick Mathewson /* List of 'changes' since the last call to eventop.dispatch. Only maintained 182cdd4c490SNick Mathewson * if the backend is using changesets. */ 18327308aaeSNick Mathewson struct event_changelist { 18427308aaeSNick Mathewson struct event_change *changes; 18527308aaeSNick Mathewson int n_changes; 18627308aaeSNick Mathewson int changes_size; 18727308aaeSNick Mathewson }; 18827308aaeSNick Mathewson 18968120d9bSNick Mathewson #ifndef EVENT__DISABLE_DEBUG_MODE 190cdd4c490SNick Mathewson /* Global internal flag: set to one if debug mode is on. */ 191cb9da0bfSNick Mathewson extern int event_debug_mode_on_; 192cb9da0bfSNick Mathewson #define EVENT_DEBUG_MODE_IS_ON() (event_debug_mode_on_) 193cb670740SNick Mathewson #else 194cb670740SNick Mathewson #define EVENT_DEBUG_MODE_IS_ON() (0) 195cd17c3acSNick Mathewson #endif 196cd17c3acSNick Mathewson 197cba59e53SNick Mathewson TAILQ_HEAD(evcallback_list, event_callback); 198cba59e53SNick Mathewson 199c17dd591SNick Mathewson /* Sets up an event for processing once */ 200c17dd591SNick Mathewson struct event_once { 201c17dd591SNick Mathewson LIST_ENTRY(event_once) next_once; 202c17dd591SNick Mathewson struct event ev; 203c17dd591SNick Mathewson 204c17dd591SNick Mathewson void (*cb)(evutil_socket_t, short, void *); 205c17dd591SNick Mathewson void *arg; 206c17dd591SNick Mathewson }; 207c17dd591SNick Mathewson 2088773c4c9SNiels Provos struct event_base { 209838d0a81SNick Mathewson /** Function pointers and other data to describe this event_base's 210838d0a81SNick Mathewson * backend. */ 2118773c4c9SNiels Provos const struct eventop *evsel; 212838d0a81SNick Mathewson /** Pointer to backend-specific data. */ 2138773c4c9SNiels Provos void *evbase; 21402b2b4d1SNiels Provos 21527308aaeSNick Mathewson /** List of changes to tell backend about at next dispatch. Only used 21627308aaeSNick Mathewson * by the O(1) backends. */ 21727308aaeSNick Mathewson struct event_changelist changelist; 21827308aaeSNick Mathewson 219cdd4c490SNick Mathewson /** Function pointers used to describe the backend that this event_base 220cdd4c490SNick Mathewson * uses for signals */ 22102b2b4d1SNiels Provos const struct eventop *evsigsel; 2227f0a7564SXiang Zhang /** Data to implement the common signal handler code. */ 223d776f846SNiels Provos struct evsig_info sig; 22402b2b4d1SNiels Provos 22576f7e7aeSChristopher Davis /** Number of virtual events */ 22676f7e7aeSChristopher Davis int virtual_event_count; 2275173bef5SAndrew Sweeney /** Maximum number of virtual events active */ 2285173bef5SAndrew Sweeney int virtual_event_count_max; 229cdd4c490SNick Mathewson /** Number of total events added to this event_base */ 230cdd4c490SNick Mathewson int event_count; 2315173bef5SAndrew Sweeney /** Maximum number of total events added to this event_base */ 2325173bef5SAndrew Sweeney int event_count_max; 233cdd4c490SNick Mathewson /** Number of total events active in this event_base */ 234cdd4c490SNick Mathewson int event_count_active; 2355173bef5SAndrew Sweeney /** Maximum number of total events active in this event_base */ 2365173bef5SAndrew Sweeney int event_count_active_max; 2378773c4c9SNiels Provos 238cdd4c490SNick Mathewson /** Set if we should terminate the loop once we're done processing 239cdd4c490SNick Mathewson * events. */ 240cdd4c490SNick Mathewson int event_gotterm; 241cdd4c490SNick Mathewson /** Set if we should terminate the loop immediately */ 242cdd4c490SNick Mathewson int event_break; 2432bfda401SNick Mathewson /** Set if we should start a new instance of the loop immediately. */ 2442bfda401SNick Mathewson int event_continue; 2452bfda401SNick Mathewson 2462bfda401SNick Mathewson /** The currently running priority of events */ 2472bfda401SNick Mathewson int event_running_priority; 2488773c4c9SNiels Provos 249b557b175SNick Mathewson /** Set if we're running the event_base_loop function, to prevent 250b557b175SNick Mathewson * reentrant invocation. */ 251b557b175SNick Mathewson int running_loop; 252b557b175SNick Mathewson 253c0e425abSNick Mathewson /** Set to the number of deferred_cbs we've made 'active' in the 254c0e425abSNick Mathewson * loop. This is a hack to prevent starvation; it would be smarter 255c0e425abSNick Mathewson * to just use event_config_set_max_dispatch_interval's max_callbacks 256c0e425abSNick Mathewson * feature */ 257c0e425abSNick Mathewson int n_deferreds_queued; 258c0e425abSNick Mathewson 259838d0a81SNick Mathewson /* Active event management. */ 260cba59e53SNick Mathewson /** An array of nactivequeues queues for active event_callbacks (ones 261cba59e53SNick Mathewson * that have triggered, and whose callbacks need to be called). Low 262838d0a81SNick Mathewson * priority numbers are more important, and stall higher ones. 263838d0a81SNick Mathewson */ 264cba59e53SNick Mathewson struct evcallback_list *activequeues; 265cdd4c490SNick Mathewson /** The length of the activequeues array */ 2668773c4c9SNiels Provos int nactivequeues; 267745a63dbSNick Mathewson /** A list of event_callbacks that should become active the next time 268745a63dbSNick Mathewson * we process events, but not this time. */ 269745a63dbSNick Mathewson struct evcallback_list active_later_queue; 2708773c4c9SNiels Provos 271cdd4c490SNick Mathewson /* common timeout logic */ 272cdd4c490SNick Mathewson 273cdd4c490SNick Mathewson /** An array of common_timeout_list* for all of the common timeout 274cdd4c490SNick Mathewson * values we know. */ 275693c24efSNick Mathewson struct common_timeout_list **common_timeout_queues; 276cdd4c490SNick Mathewson /** The number of entries used in common_timeout_queues */ 277693c24efSNick Mathewson int n_common_timeouts; 278cdd4c490SNick Mathewson /** The total size of common_timeout_queues. */ 279693c24efSNick Mathewson int n_common_timeouts_allocated; 280693c24efSNick Mathewson 281cdd4c490SNick Mathewson /** Mapping from file descriptors to enabled (added) events */ 28255bcd7d2SNick Mathewson struct event_io_map io; 28302b2b4d1SNiels Provos 284cdd4c490SNick Mathewson /** Mapping from signal numbers to enabled (added) events. */ 28555bcd7d2SNick Mathewson struct event_signal_map sigmap; 28641b7cbc3SNiels Provos 287838d0a81SNick Mathewson /** Priority queue of events with timeouts. */ 28830ae40ccSNiels Provos struct min_heap timeheap; 289558de9b3SNiels Provos 290a459ef70SNick Mathewson /** Stored timeval: used to avoid calling gettimeofday/clock_gettime 291a459ef70SNick Mathewson * too often. */ 29245e6fb0dSNiels Provos struct timeval tv_cache; 29345e6fb0dSNiels Provos 294f5e4eb05SNick Mathewson struct evutil_monotonic_timer monotonic_timer; 295f5e4eb05SNick Mathewson 296a459ef70SNick Mathewson /** Difference between internal time (maybe from clock_gettime) and 297a459ef70SNick Mathewson * gettimeofday. */ 298a459ef70SNick Mathewson struct timeval tv_clock_diff; 299a459ef70SNick Mathewson /** Second in which we last updated tv_clock_diff, in monotonic time. */ 300a459ef70SNick Mathewson time_t last_updated_clock_diff; 301a459ef70SNick Mathewson 30268120d9bSNick Mathewson #ifndef EVENT__DISABLE_THREAD_SUPPORT 303558de9b3SNiels Provos /* threading support */ 304838d0a81SNick Mathewson /** The thread currently running the event_loop for this base */ 305558de9b3SNiels Provos unsigned long th_owner_id; 306838d0a81SNick Mathewson /** A lock to prevent conflicting accesses to this event_base */ 307c182bacaSNiels Provos void *th_base_lock; 308e0972c21SNick Mathewson /** A condition that gets signalled when we're done processing an 309e0972c21SNick Mathewson * event with waiters on it. */ 310e0972c21SNick Mathewson void *current_event_cond; 311e0972c21SNick Mathewson /** Number of threads blocking on current_event_cond. */ 312e0972c21SNick Mathewson int current_event_waiters; 313ec35eb55SNick Mathewson #endif 31413dad99cSNick Mathewson /** The event whose callback is executing right now */ 315cba59e53SNick Mathewson struct event_callback *current_event; 316a5901991SNick Mathewson 3179f560bfaSNick Mathewson #ifdef _WIN32 318cdd4c490SNick Mathewson /** IOCP support structure, if IOCP is enabled. */ 319b69d03b5SNick Mathewson struct event_iocp_port *iocp; 320b69d03b5SNick Mathewson #endif 321b69d03b5SNick Mathewson 322cdd4c490SNick Mathewson /** Flags that this base was configured with */ 323ab96b5f3SNick Mathewson enum event_base_config_flag flags; 324ab96b5f3SNick Mathewson 325fd4de1e7SNick Mathewson struct timeval max_dispatch_time; 326fd4de1e7SNick Mathewson int max_dispatch_callbacks; 327a37a0c0eSNick Mathewson int limit_callbacks_after_prio; 328fd4de1e7SNick Mathewson 329a5901991SNick Mathewson /* Notify main thread to wake up break, etc. */ 3304632b78eSNick Mathewson /** True if the base already has a pending notify, and we don't need 3314632b78eSNick Mathewson * to add any more. */ 3324632b78eSNick Mathewson int is_notify_pending; 333cdd4c490SNick Mathewson /** A socketpair used by some th_notify functions to wake up the main 334cdd4c490SNick Mathewson * thread. */ 335f817bfa4SDimitre Piskyulev evutil_socket_t th_notify_fd[2]; 336cdd4c490SNick Mathewson /** An event used by some th_notify functions to wake up the main 337cdd4c490SNick Mathewson * thread. */ 338558de9b3SNiels Provos struct event th_notify; 339cdd4c490SNick Mathewson /** A function used to wake up the main thread from another thread. */ 340a5901991SNick Mathewson int (*th_notify_fn)(struct event_base *base); 341e86af4b7SNicholas Marriott 3423aa44159SNick Mathewson /** Saved seed for weak random number generator. Some backends use 3433aa44159SNick Mathewson * this to produce fairness among sockets. Protected by th_base_lock. */ 3443aa44159SNick Mathewson struct evutil_weakrand_state weakrand_seed; 345c17dd591SNick Mathewson 346c17dd591SNick Mathewson /** List of event_onces that have not yet fired. */ 347c17dd591SNick Mathewson LIST_HEAD(once_event_list, event_once) once_events; 348c17dd591SNick Mathewson 3498773c4c9SNiels Provos }; 3508773c4c9SNiels Provos 3513f56e364SNiels Provos struct event_config_entry { 35260433a0aSGilad Benjamini TAILQ_ENTRY(event_config_entry) next; 3533f56e364SNiels Provos 3543f56e364SNiels Provos const char *avoid_method; 3553f56e364SNiels Provos }; 3563f56e364SNiels Provos 357838d0a81SNick Mathewson /** Internal structure: describes the configuration we want for an event_base 358838d0a81SNick Mathewson * that we're about to allocate. */ 3593f56e364SNiels Provos struct event_config { 3603f56e364SNiels Provos TAILQ_HEAD(event_configq, event_config_entry) entries; 36105965921SNick Mathewson 3622447fe88SChristopher Davis int n_cpus_hint; 363fd4de1e7SNick Mathewson struct timeval max_dispatch_interval; 364fd4de1e7SNick Mathewson int max_dispatch_callbacks; 365a37a0c0eSNick Mathewson int limit_callbacks_after_prio; 36605965921SNick Mathewson enum event_method_feature require_features; 367ec35eb55SNick Mathewson enum event_base_config_flag flags; 3683f56e364SNiels Provos }; 3693f56e364SNiels Provos 370f74e7258SNick Mathewson /* Internal use only: Functions that might be missing from <sys/queue.h> */ 371cdd52e7fSJiri Luznicky #ifndef LIST_END 372cdd52e7fSJiri Luznicky #define LIST_END(head) NULL 373cdd52e7fSJiri Luznicky #endif 374cdd52e7fSJiri Luznicky 375c4dc3353SKevin Bowling #ifndef TAILQ_FIRST 376f74e7258SNick Mathewson #define TAILQ_FIRST(head) ((head)->tqh_first) 377c4dc3353SKevin Bowling #endif 378c4dc3353SKevin Bowling #ifndef TAILQ_END 379f74e7258SNick Mathewson #define TAILQ_END(head) NULL 380c4dc3353SKevin Bowling #endif 381c4dc3353SKevin Bowling #ifndef TAILQ_NEXT 382f74e7258SNick Mathewson #define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next) 383c4dc3353SKevin Bowling #endif 384c4dc3353SKevin Bowling 385e9340964SNick Mathewson #ifndef TAILQ_FOREACH 386f74e7258SNick Mathewson #define TAILQ_FOREACH(var, head, field) \ 387f74e7258SNick Mathewson for ((var) = TAILQ_FIRST(head); \ 388f74e7258SNick Mathewson (var) != TAILQ_END(head); \ 389f74e7258SNick Mathewson (var) = TAILQ_NEXT(var, field)) 390e9340964SNick Mathewson #endif 391c4dc3353SKevin Bowling 392c4dc3353SKevin Bowling #ifndef TAILQ_INSERT_BEFORE 393f74e7258SNick Mathewson #define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \ 394f74e7258SNick Mathewson (elm)->field.tqe_prev = (listelm)->field.tqe_prev; \ 395f74e7258SNick Mathewson (elm)->field.tqe_next = (listelm); \ 396f74e7258SNick Mathewson *(listelm)->field.tqe_prev = (elm); \ 397f74e7258SNick Mathewson (listelm)->field.tqe_prev = &(elm)->field.tqe_next; \ 398f74e7258SNick Mathewson } while (0) 399c4dc3353SKevin Bowling #endif 400f74e7258SNick Mathewson 401b06b2649SNick Mathewson #define N_ACTIVE_CALLBACKS(base) \ 402ae2b84b2SNick Mathewson ((base)->event_count_active) 403b06b2649SNick Mathewson 404cb9da0bfSNick Mathewson int evsig_set_handler_(struct event_base *base, int evsignal, 4052823cb05SNick Mathewson void (*fn)(int)); 406cb9da0bfSNick Mathewson int evsig_restore_handler_(struct event_base *base, int evsignal); 4072823cb05SNick Mathewson 4089cd5acb5SNick Mathewson int event_add_nolock_(struct event *ev, 4099cd5acb5SNick Mathewson const struct timeval *tv, int tv_is_absolute); 410a800b913SNick Mathewson /** Argument for event_del_nolock_. Tells event_del not to block on the event 411a800b913SNick Mathewson * if it's running in another thread. */ 4128eedeabeSNick Mathewson #define EVENT_DEL_NOBLOCK 0 413a800b913SNick Mathewson /** Argument for event_del_nolock_. Tells event_del to block on the event 414a800b913SNick Mathewson * if it's running in another thread, regardless of its value for EV_FINALIZE 415a800b913SNick Mathewson */ 4168eedeabeSNick Mathewson #define EVENT_DEL_BLOCK 1 417a800b913SNick Mathewson /** Argument for event_del_nolock_. Tells event_del to block on the event 418a800b913SNick Mathewson * if it is running in another thread and it doesn't have EV_FINALIZE set. 419a800b913SNick Mathewson */ 4208eedeabeSNick Mathewson #define EVENT_DEL_AUTOBLOCK 2 421*ec52e6afSdota17 /** Argument for event_del_nolock_. Tells event_del to proceed even if the 422a800b913SNick Mathewson * event is set up for finalization rather for regular use.*/ 4238eedeabeSNick Mathewson #define EVENT_DEL_EVEN_IF_FINALIZING 3 4248eedeabeSNick Mathewson int event_del_nolock_(struct event *ev, int blocking); 425e3b2e086SNick Mathewson int event_remove_timer_nolock_(struct event *ev); 426b683cae3SNick Mathewson 4278ac3c4c2SNick Mathewson void event_active_nolock_(struct event *ev, int res, short count); 4289806b126SAzat Khuzhin EVENT2_EXPORT_SYMBOL 429ae2b84b2SNick Mathewson int event_callback_activate_(struct event_base *, struct event_callback *); 430ae2b84b2SNick Mathewson int event_callback_activate_nolock_(struct event_base *, struct event_callback *); 431745a63dbSNick Mathewson int event_callback_cancel_(struct event_base *base, 432745a63dbSNick Mathewson struct event_callback *evcb); 433cba59e53SNick Mathewson 4348eedeabeSNick Mathewson void event_callback_finalize_nolock_(struct event_base *base, unsigned flags, struct event_callback *evcb, void (*cb)(struct event_callback *, void *)); 4359806b126SAzat Khuzhin EVENT2_EXPORT_SYMBOL 4368eedeabeSNick Mathewson void event_callback_finalize_(struct event_base *base, unsigned flags, struct event_callback *evcb, void (*cb)(struct event_callback *, void *)); 4378eedeabeSNick Mathewson int event_callback_finalize_many_(struct event_base *base, int n_cbs, struct event_callback **evcb, void (*cb)(struct event_callback *, void *)); 4388eedeabeSNick Mathewson 4398eedeabeSNick Mathewson 4409806b126SAzat Khuzhin EVENT2_EXPORT_SYMBOL 441745a63dbSNick Mathewson void event_active_later_(struct event *ev, int res); 442745a63dbSNick Mathewson void event_active_later_nolock_(struct event *ev, int res); 44338cef641SGreg Hazel int event_callback_activate_later_nolock_(struct event_base *base, 444745a63dbSNick Mathewson struct event_callback *evcb); 445745a63dbSNick Mathewson int event_callback_cancel_nolock_(struct event_base *base, 4468eedeabeSNick Mathewson struct event_callback *evcb, int even_if_finalizing); 447745a63dbSNick Mathewson void event_callback_init_(struct event_base *base, 448745a63dbSNick Mathewson struct event_callback *cb); 449a2a7d1d1SNick Mathewson 45076f7e7aeSChristopher Davis /* FIXME document. */ 4519806b126SAzat Khuzhin EVENT2_EXPORT_SYMBOL 4528ac3c4c2SNick Mathewson void event_base_add_virtual_(struct event_base *base); 4538ac3c4c2SNick Mathewson void event_base_del_virtual_(struct event_base *base); 45476f7e7aeSChristopher Davis 45527737d55SNick Mathewson /** For debugging: unless assertions are disabled, verify the referential 45627737d55SNick Mathewson integrity of the internal data structures of 'base'. This operation can 45727737d55SNick Mathewson be expensive. 45827737d55SNick Mathewson 45927737d55SNick Mathewson Returns on success; aborts on failure. 46027737d55SNick Mathewson */ 4619806b126SAzat Khuzhin EVENT2_EXPORT_SYMBOL 4628ac3c4c2SNick Mathewson void event_base_assert_ok_(struct event_base *base); 4639cd5acb5SNick Mathewson void event_base_assert_ok_nolock_(struct event_base *base); 4649cd5acb5SNick Mathewson 46527737d55SNick Mathewson 466c89b4e63SNick Mathewson /* Helper function: Call 'fn' exactly once every inserted or active event in 467c89b4e63SNick Mathewson * the event_base 'base'. 468c89b4e63SNick Mathewson * 469c89b4e63SNick Mathewson * If fn returns 0, continue on to the next event. Otherwise, return the same 470c89b4e63SNick Mathewson * value that fn returned. 471c89b4e63SNick Mathewson * 472c89b4e63SNick Mathewson * Requires that 'base' be locked. 473c89b4e63SNick Mathewson */ 474232055efSNick Mathewson int event_base_foreach_event_nolock_(struct event_base *base, 475c89b4e63SNick Mathewson event_base_foreach_event_cb cb, void *arg); 476c89b4e63SNick Mathewson 477bfcedee0SSebastian Hahn /* Cleanup function to reset debug mode during shutdown. 478bfcedee0SSebastian Hahn * 479bfcedee0SSebastian Hahn * Calling this function doesn't mean it'll be possible to re-enable 480bfcedee0SSebastian Hahn * debug mode if any events were added. 481bfcedee0SSebastian Hahn */ 482bfcedee0SSebastian Hahn void event_disable_debug_mode(void); 483bfcedee0SSebastian Hahn 4848773c4c9SNiels Provos #ifdef __cplusplus 4858773c4c9SNiels Provos } 4868773c4c9SNiels Provos #endif 4878773c4c9SNiels Provos 4883f8c7cd0SNick Mathewson #endif /* EVENT_INTERNAL_H_INCLUDED_ */ 489