xref: /freebsd/contrib/libevent/event-internal.h (revision b50261e21f39a6c7249a49e7b60aa878c98512a8)
1c43e99fdSEd Maste /*
2c43e99fdSEd Maste  * Copyright (c) 2000-2007 Niels Provos <provos@citi.umich.edu>
3c43e99fdSEd Maste  * Copyright (c) 2007-2012 Niels Provos and Nick Mathewson
4c43e99fdSEd Maste  *
5c43e99fdSEd Maste  * Redistribution and use in source and binary forms, with or without
6c43e99fdSEd Maste  * modification, are permitted provided that the following conditions
7c43e99fdSEd Maste  * are met:
8c43e99fdSEd Maste  * 1. Redistributions of source code must retain the above copyright
9c43e99fdSEd Maste  *    notice, this list of conditions and the following disclaimer.
10c43e99fdSEd Maste  * 2. Redistributions in binary form must reproduce the above copyright
11c43e99fdSEd Maste  *    notice, this list of conditions and the following disclaimer in the
12c43e99fdSEd Maste  *    documentation and/or other materials provided with the distribution.
13c43e99fdSEd Maste  * 3. The name of the author may not be used to endorse or promote products
14c43e99fdSEd Maste  *    derived from this software without specific prior written permission.
15c43e99fdSEd Maste  *
16c43e99fdSEd Maste  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17c43e99fdSEd Maste  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18c43e99fdSEd Maste  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19c43e99fdSEd Maste  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20c43e99fdSEd Maste  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21c43e99fdSEd Maste  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22c43e99fdSEd Maste  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23c43e99fdSEd Maste  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24c43e99fdSEd Maste  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25c43e99fdSEd Maste  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26c43e99fdSEd Maste  */
27c43e99fdSEd Maste #ifndef EVENT_INTERNAL_H_INCLUDED_
28c43e99fdSEd Maste #define EVENT_INTERNAL_H_INCLUDED_
29c43e99fdSEd Maste 
30c43e99fdSEd Maste #ifdef __cplusplus
31c43e99fdSEd Maste extern "C" {
32c43e99fdSEd Maste #endif
33c43e99fdSEd Maste 
34c43e99fdSEd Maste #include "event2/event-config.h"
35c43e99fdSEd Maste #include "evconfig-private.h"
36c43e99fdSEd Maste 
37c43e99fdSEd Maste #include <time.h>
38c43e99fdSEd Maste #include <sys/queue.h>
39c43e99fdSEd Maste #include "event2/event_struct.h"
40c43e99fdSEd Maste #include "minheap-internal.h"
41c43e99fdSEd Maste #include "evsignal-internal.h"
42c43e99fdSEd Maste #include "mm-internal.h"
43c43e99fdSEd Maste #include "defer-internal.h"
44c43e99fdSEd Maste 
45c43e99fdSEd Maste /* map union members back */
46c43e99fdSEd Maste 
47c43e99fdSEd Maste /* mutually exclusive */
48c43e99fdSEd Maste #define ev_signal_next	ev_.ev_signal.ev_signal_next
49c43e99fdSEd Maste #define ev_io_next	ev_.ev_io.ev_io_next
50c43e99fdSEd Maste #define ev_io_timeout	ev_.ev_io.ev_timeout
51c43e99fdSEd Maste 
52c43e99fdSEd Maste /* used only by signals */
53c43e99fdSEd Maste #define ev_ncalls	ev_.ev_signal.ev_ncalls
54c43e99fdSEd Maste #define ev_pncalls	ev_.ev_signal.ev_pncalls
55c43e99fdSEd Maste 
56c43e99fdSEd Maste #define ev_pri ev_evcallback.evcb_pri
57c43e99fdSEd Maste #define ev_flags ev_evcallback.evcb_flags
58c43e99fdSEd Maste #define ev_closure ev_evcallback.evcb_closure
59c43e99fdSEd Maste #define ev_callback ev_evcallback.evcb_cb_union.evcb_callback
60c43e99fdSEd Maste #define ev_arg ev_evcallback.evcb_arg
61c43e99fdSEd Maste 
62c43e99fdSEd Maste /** @name Event closure codes
63c43e99fdSEd Maste 
64c43e99fdSEd Maste     Possible values for evcb_closure in struct event_callback
65c43e99fdSEd Maste 
66c43e99fdSEd Maste     @{
67c43e99fdSEd Maste  */
68c43e99fdSEd Maste /** A regular event. Uses the evcb_callback callback */
69c43e99fdSEd Maste #define EV_CLOSURE_EVENT 0
70c43e99fdSEd Maste /** A signal event. Uses the evcb_callback callback */
71c43e99fdSEd Maste #define EV_CLOSURE_EVENT_SIGNAL 1
72c43e99fdSEd Maste /** A persistent non-signal event. Uses the evcb_callback callback */
73c43e99fdSEd Maste #define EV_CLOSURE_EVENT_PERSIST 2
74c43e99fdSEd Maste /** A simple callback. Uses the evcb_selfcb callback. */
75c43e99fdSEd Maste #define EV_CLOSURE_CB_SELF 3
76c43e99fdSEd Maste /** A finalizing callback. Uses the evcb_cbfinalize callback. */
77c43e99fdSEd Maste #define EV_CLOSURE_CB_FINALIZE 4
78c43e99fdSEd Maste /** A finalizing event. Uses the evcb_evfinalize callback. */
79c43e99fdSEd Maste #define EV_CLOSURE_EVENT_FINALIZE 5
80c43e99fdSEd Maste /** A finalizing event that should get freed after. Uses the evcb_evfinalize
81c43e99fdSEd Maste  * callback. */
82c43e99fdSEd Maste #define EV_CLOSURE_EVENT_FINALIZE_FREE 6
83c43e99fdSEd Maste /** @} */
84c43e99fdSEd Maste 
85c43e99fdSEd Maste /** Structure to define the backend of a given event_base. */
86c43e99fdSEd Maste struct eventop {
87c43e99fdSEd Maste 	/** The name of this backend. */
88c43e99fdSEd Maste 	const char *name;
89c43e99fdSEd Maste 	/** Function to set up an event_base to use this backend.  It should
90c43e99fdSEd Maste 	 * create a new structure holding whatever information is needed to
91c43e99fdSEd Maste 	 * run the backend, and return it.  The returned pointer will get
92c43e99fdSEd Maste 	 * stored by event_init into the event_base.evbase field.  On failure,
93c43e99fdSEd Maste 	 * this function should return NULL. */
94c43e99fdSEd Maste 	void *(*init)(struct event_base *);
95c43e99fdSEd Maste 	/** Enable reading/writing on a given fd or signal.  'events' will be
96c43e99fdSEd Maste 	 * the events that we're trying to enable: one or more of EV_READ,
97c43e99fdSEd Maste 	 * EV_WRITE, EV_SIGNAL, and EV_ET.  'old' will be those events that
98c43e99fdSEd Maste 	 * were enabled on this fd previously.  'fdinfo' will be a structure
99c43e99fdSEd Maste 	 * associated with the fd by the evmap; its size is defined by the
100c43e99fdSEd Maste 	 * fdinfo field below.  It will be set to 0 the first time the fd is
101c43e99fdSEd Maste 	 * added.  The function should return 0 on success and -1 on error.
102c43e99fdSEd Maste 	 */
103c43e99fdSEd Maste 	int (*add)(struct event_base *, evutil_socket_t fd, short old, short events, void *fdinfo);
104c43e99fdSEd Maste 	/** As "add", except 'events' contains the events we mean to disable. */
105c43e99fdSEd Maste 	int (*del)(struct event_base *, evutil_socket_t fd, short old, short events, void *fdinfo);
106c43e99fdSEd Maste 	/** Function to implement the core of an event loop.  It must see which
107c43e99fdSEd Maste 	    added events are ready, and cause event_active to be called for each
108c43e99fdSEd Maste 	    active event (usually via event_io_active or such).  It should
109c43e99fdSEd Maste 	    return 0 on success and -1 on error.
110c43e99fdSEd Maste 	 */
111c43e99fdSEd Maste 	int (*dispatch)(struct event_base *, struct timeval *);
112c43e99fdSEd Maste 	/** Function to clean up and free our data from the event_base. */
113c43e99fdSEd Maste 	void (*dealloc)(struct event_base *);
114c43e99fdSEd Maste 	/** Flag: set if we need to reinitialize the event base after we fork.
115c43e99fdSEd Maste 	 */
116c43e99fdSEd Maste 	int need_reinit;
117c43e99fdSEd Maste 	/** Bit-array of supported event_method_features that this backend can
118c43e99fdSEd Maste 	 * provide. */
119c43e99fdSEd Maste 	enum event_method_feature features;
120c43e99fdSEd Maste 	/** Length of the extra information we should record for each fd that
121c43e99fdSEd Maste 	    has one or more active events.  This information is recorded
122c43e99fdSEd Maste 	    as part of the evmap entry for each fd, and passed as an argument
123c43e99fdSEd Maste 	    to the add and del functions above.
124c43e99fdSEd Maste 	 */
125c43e99fdSEd Maste 	size_t fdinfo_len;
126c43e99fdSEd Maste };
127c43e99fdSEd Maste 
128c43e99fdSEd Maste #ifdef _WIN32
129c43e99fdSEd Maste /* If we're on win32, then file descriptors are not nice low densely packed
130c43e99fdSEd Maste    integers.  Instead, they are pointer-like windows handles, and we want to
131c43e99fdSEd Maste    use a hashtable instead of an array to map fds to events.
132c43e99fdSEd Maste */
133c43e99fdSEd Maste #define EVMAP_USE_HT
134c43e99fdSEd Maste #endif
135c43e99fdSEd Maste 
136c43e99fdSEd Maste /* #define HT_CACHE_HASH_VALS */
137c43e99fdSEd Maste 
138c43e99fdSEd Maste #ifdef EVMAP_USE_HT
139c43e99fdSEd Maste #define HT_NO_CACHE_HASH_VALUES
140c43e99fdSEd Maste #include "ht-internal.h"
141c43e99fdSEd Maste struct event_map_entry;
142c43e99fdSEd Maste HT_HEAD(event_io_map, event_map_entry);
143c43e99fdSEd Maste #else
144c43e99fdSEd Maste #define event_io_map event_signal_map
145c43e99fdSEd Maste #endif
146c43e99fdSEd Maste 
147c43e99fdSEd Maste /* Used to map signal numbers to a list of events.  If EVMAP_USE_HT is not
148c43e99fdSEd Maste    defined, this structure is also used as event_io_map, which maps fds to a
149c43e99fdSEd Maste    list of events.
150c43e99fdSEd Maste */
151c43e99fdSEd Maste struct event_signal_map {
152c43e99fdSEd Maste 	/* An array of evmap_io * or of evmap_signal *; empty entries are
153c43e99fdSEd Maste 	 * set to NULL. */
154c43e99fdSEd Maste 	void **entries;
155c43e99fdSEd Maste 	/* The number of entries available in entries */
156c43e99fdSEd Maste 	int nentries;
157c43e99fdSEd Maste };
158c43e99fdSEd Maste 
159c43e99fdSEd Maste /* A list of events waiting on a given 'common' timeout value.  Ordinarily,
160c43e99fdSEd Maste  * events waiting for a timeout wait on a minheap.  Sometimes, however, a
161c43e99fdSEd Maste  * queue can be faster.
162c43e99fdSEd Maste  **/
163c43e99fdSEd Maste struct common_timeout_list {
164c43e99fdSEd Maste 	/* List of events currently waiting in the queue. */
165c43e99fdSEd Maste 	struct event_list events;
166c43e99fdSEd Maste 	/* 'magic' timeval used to indicate the duration of events in this
167c43e99fdSEd Maste 	 * queue. */
168c43e99fdSEd Maste 	struct timeval duration;
169c43e99fdSEd Maste 	/* Event that triggers whenever one of the events in the queue is
170c43e99fdSEd Maste 	 * ready to activate */
171c43e99fdSEd Maste 	struct event timeout_event;
172c43e99fdSEd Maste 	/* The event_base that this timeout list is part of */
173c43e99fdSEd Maste 	struct event_base *base;
174c43e99fdSEd Maste };
175c43e99fdSEd Maste 
176c43e99fdSEd Maste /** Mask used to get the real tv_usec value from a common timeout. */
177c43e99fdSEd Maste #define COMMON_TIMEOUT_MICROSECONDS_MASK       0x000fffff
178c43e99fdSEd Maste 
179c43e99fdSEd Maste struct event_change;
180c43e99fdSEd Maste 
181c43e99fdSEd Maste /* List of 'changes' since the last call to eventop.dispatch.  Only maintained
182c43e99fdSEd Maste  * if the backend is using changesets. */
183c43e99fdSEd Maste struct event_changelist {
184c43e99fdSEd Maste 	struct event_change *changes;
185c43e99fdSEd Maste 	int n_changes;
186c43e99fdSEd Maste 	int changes_size;
187c43e99fdSEd Maste };
188c43e99fdSEd Maste 
189c43e99fdSEd Maste #ifndef EVENT__DISABLE_DEBUG_MODE
190c43e99fdSEd Maste /* Global internal flag: set to one if debug mode is on. */
191c43e99fdSEd Maste extern int event_debug_mode_on_;
192c43e99fdSEd Maste #define EVENT_DEBUG_MODE_IS_ON() (event_debug_mode_on_)
193c43e99fdSEd Maste #else
194c43e99fdSEd Maste #define EVENT_DEBUG_MODE_IS_ON() (0)
195c43e99fdSEd Maste #endif
196c43e99fdSEd Maste 
197c43e99fdSEd Maste TAILQ_HEAD(evcallback_list, event_callback);
198c43e99fdSEd Maste 
199c43e99fdSEd Maste /* Sets up an event for processing once */
200c43e99fdSEd Maste struct event_once {
201c43e99fdSEd Maste 	LIST_ENTRY(event_once) next_once;
202c43e99fdSEd Maste 	struct event ev;
203c43e99fdSEd Maste 
204c43e99fdSEd Maste 	void (*cb)(evutil_socket_t, short, void *);
205c43e99fdSEd Maste 	void *arg;
206c43e99fdSEd Maste };
207c43e99fdSEd Maste 
208c43e99fdSEd Maste struct event_base {
209c43e99fdSEd Maste 	/** Function pointers and other data to describe this event_base's
210c43e99fdSEd Maste 	 * backend. */
211c43e99fdSEd Maste 	const struct eventop *evsel;
212c43e99fdSEd Maste 	/** Pointer to backend-specific data. */
213c43e99fdSEd Maste 	void *evbase;
214c43e99fdSEd Maste 
215c43e99fdSEd Maste 	/** List of changes to tell backend about at next dispatch.  Only used
216c43e99fdSEd Maste 	 * by the O(1) backends. */
217c43e99fdSEd Maste 	struct event_changelist changelist;
218c43e99fdSEd Maste 
219c43e99fdSEd Maste 	/** Function pointers used to describe the backend that this event_base
220c43e99fdSEd Maste 	 * uses for signals */
221c43e99fdSEd Maste 	const struct eventop *evsigsel;
222*b50261e2SCy Schubert 	/** Data to implement the common signal handler code. */
223c43e99fdSEd Maste 	struct evsig_info sig;
224c43e99fdSEd Maste 
225c43e99fdSEd Maste 	/** Number of virtual events */
226c43e99fdSEd Maste 	int virtual_event_count;
227c43e99fdSEd Maste 	/** Maximum number of virtual events active */
228c43e99fdSEd Maste 	int virtual_event_count_max;
229c43e99fdSEd Maste 	/** Number of total events added to this event_base */
230c43e99fdSEd Maste 	int event_count;
231c43e99fdSEd Maste 	/** Maximum number of total events added to this event_base */
232c43e99fdSEd Maste 	int event_count_max;
233c43e99fdSEd Maste 	/** Number of total events active in this event_base */
234c43e99fdSEd Maste 	int event_count_active;
235c43e99fdSEd Maste 	/** Maximum number of total events active in this event_base */
236c43e99fdSEd Maste 	int event_count_active_max;
237c43e99fdSEd Maste 
238c43e99fdSEd Maste 	/** Set if we should terminate the loop once we're done processing
239c43e99fdSEd Maste 	 * events. */
240c43e99fdSEd Maste 	int event_gotterm;
241c43e99fdSEd Maste 	/** Set if we should terminate the loop immediately */
242c43e99fdSEd Maste 	int event_break;
243c43e99fdSEd Maste 	/** Set if we should start a new instance of the loop immediately. */
244c43e99fdSEd Maste 	int event_continue;
245c43e99fdSEd Maste 
246c43e99fdSEd Maste 	/** The currently running priority of events */
247c43e99fdSEd Maste 	int event_running_priority;
248c43e99fdSEd Maste 
249c43e99fdSEd Maste 	/** Set if we're running the event_base_loop function, to prevent
250c43e99fdSEd Maste 	 * reentrant invocation. */
251c43e99fdSEd Maste 	int running_loop;
252c43e99fdSEd Maste 
253c43e99fdSEd Maste 	/** Set to the number of deferred_cbs we've made 'active' in the
254c43e99fdSEd Maste 	 * loop.  This is a hack to prevent starvation; it would be smarter
255c43e99fdSEd Maste 	 * to just use event_config_set_max_dispatch_interval's max_callbacks
256c43e99fdSEd Maste 	 * feature */
257c43e99fdSEd Maste 	int n_deferreds_queued;
258c43e99fdSEd Maste 
259c43e99fdSEd Maste 	/* Active event management. */
260c43e99fdSEd Maste 	/** An array of nactivequeues queues for active event_callbacks (ones
261c43e99fdSEd Maste 	 * that have triggered, and whose callbacks need to be called).  Low
262c43e99fdSEd Maste 	 * priority numbers are more important, and stall higher ones.
263c43e99fdSEd Maste 	 */
264c43e99fdSEd Maste 	struct evcallback_list *activequeues;
265c43e99fdSEd Maste 	/** The length of the activequeues array */
266c43e99fdSEd Maste 	int nactivequeues;
267c43e99fdSEd Maste 	/** A list of event_callbacks that should become active the next time
268c43e99fdSEd Maste 	 * we process events, but not this time. */
269c43e99fdSEd Maste 	struct evcallback_list active_later_queue;
270c43e99fdSEd Maste 
271c43e99fdSEd Maste 	/* common timeout logic */
272c43e99fdSEd Maste 
273c43e99fdSEd Maste 	/** An array of common_timeout_list* for all of the common timeout
274c43e99fdSEd Maste 	 * values we know. */
275c43e99fdSEd Maste 	struct common_timeout_list **common_timeout_queues;
276c43e99fdSEd Maste 	/** The number of entries used in common_timeout_queues */
277c43e99fdSEd Maste 	int n_common_timeouts;
278c43e99fdSEd Maste 	/** The total size of common_timeout_queues. */
279c43e99fdSEd Maste 	int n_common_timeouts_allocated;
280c43e99fdSEd Maste 
281c43e99fdSEd Maste 	/** Mapping from file descriptors to enabled (added) events */
282c43e99fdSEd Maste 	struct event_io_map io;
283c43e99fdSEd Maste 
284c43e99fdSEd Maste 	/** Mapping from signal numbers to enabled (added) events. */
285c43e99fdSEd Maste 	struct event_signal_map sigmap;
286c43e99fdSEd Maste 
287c43e99fdSEd Maste 	/** Priority queue of events with timeouts. */
288c43e99fdSEd Maste 	struct min_heap timeheap;
289c43e99fdSEd Maste 
290c43e99fdSEd Maste 	/** Stored timeval: used to avoid calling gettimeofday/clock_gettime
291c43e99fdSEd Maste 	 * too often. */
292c43e99fdSEd Maste 	struct timeval tv_cache;
293c43e99fdSEd Maste 
294c43e99fdSEd Maste 	struct evutil_monotonic_timer monotonic_timer;
295c43e99fdSEd Maste 
296c43e99fdSEd Maste 	/** Difference between internal time (maybe from clock_gettime) and
297c43e99fdSEd Maste 	 * gettimeofday. */
298c43e99fdSEd Maste 	struct timeval tv_clock_diff;
299c43e99fdSEd Maste 	/** Second in which we last updated tv_clock_diff, in monotonic time. */
300c43e99fdSEd Maste 	time_t last_updated_clock_diff;
301c43e99fdSEd Maste 
302c43e99fdSEd Maste #ifndef EVENT__DISABLE_THREAD_SUPPORT
303c43e99fdSEd Maste 	/* threading support */
304c43e99fdSEd Maste 	/** The thread currently running the event_loop for this base */
305c43e99fdSEd Maste 	unsigned long th_owner_id;
306c43e99fdSEd Maste 	/** A lock to prevent conflicting accesses to this event_base */
307c43e99fdSEd Maste 	void *th_base_lock;
308c43e99fdSEd Maste 	/** A condition that gets signalled when we're done processing an
309c43e99fdSEd Maste 	 * event with waiters on it. */
310c43e99fdSEd Maste 	void *current_event_cond;
311c43e99fdSEd Maste 	/** Number of threads blocking on current_event_cond. */
312c43e99fdSEd Maste 	int current_event_waiters;
313c43e99fdSEd Maste #endif
314c43e99fdSEd Maste 	/** The event whose callback is executing right now */
315c43e99fdSEd Maste 	struct event_callback *current_event;
316c43e99fdSEd Maste 
317c43e99fdSEd Maste #ifdef _WIN32
318c43e99fdSEd Maste 	/** IOCP support structure, if IOCP is enabled. */
319c43e99fdSEd Maste 	struct event_iocp_port *iocp;
320c43e99fdSEd Maste #endif
321c43e99fdSEd Maste 
322c43e99fdSEd Maste 	/** Flags that this base was configured with */
323c43e99fdSEd Maste 	enum event_base_config_flag flags;
324c43e99fdSEd Maste 
325c43e99fdSEd Maste 	struct timeval max_dispatch_time;
326c43e99fdSEd Maste 	int max_dispatch_callbacks;
327c43e99fdSEd Maste 	int limit_callbacks_after_prio;
328c43e99fdSEd Maste 
329c43e99fdSEd Maste 	/* Notify main thread to wake up break, etc. */
330c43e99fdSEd Maste 	/** True if the base already has a pending notify, and we don't need
331c43e99fdSEd Maste 	 * to add any more. */
332c43e99fdSEd Maste 	int is_notify_pending;
333c43e99fdSEd Maste 	/** A socketpair used by some th_notify functions to wake up the main
334c43e99fdSEd Maste 	 * thread. */
335c43e99fdSEd Maste 	evutil_socket_t th_notify_fd[2];
336c43e99fdSEd Maste 	/** An event used by some th_notify functions to wake up the main
337c43e99fdSEd Maste 	 * thread. */
338c43e99fdSEd Maste 	struct event th_notify;
339c43e99fdSEd Maste 	/** A function used to wake up the main thread from another thread. */
340c43e99fdSEd Maste 	int (*th_notify_fn)(struct event_base *base);
341c43e99fdSEd Maste 
342c43e99fdSEd Maste 	/** Saved seed for weak random number generator. Some backends use
343c43e99fdSEd Maste 	 * this to produce fairness among sockets. Protected by th_base_lock. */
344c43e99fdSEd Maste 	struct evutil_weakrand_state weakrand_seed;
345c43e99fdSEd Maste 
346c43e99fdSEd Maste 	/** List of event_onces that have not yet fired. */
347c43e99fdSEd Maste 	LIST_HEAD(once_event_list, event_once) once_events;
348c43e99fdSEd Maste 
349c43e99fdSEd Maste };
350c43e99fdSEd Maste 
351c43e99fdSEd Maste struct event_config_entry {
352c43e99fdSEd Maste 	TAILQ_ENTRY(event_config_entry) next;
353c43e99fdSEd Maste 
354c43e99fdSEd Maste 	const char *avoid_method;
355c43e99fdSEd Maste };
356c43e99fdSEd Maste 
357c43e99fdSEd Maste /** Internal structure: describes the configuration we want for an event_base
358c43e99fdSEd Maste  * that we're about to allocate. */
359c43e99fdSEd Maste struct event_config {
360c43e99fdSEd Maste 	TAILQ_HEAD(event_configq, event_config_entry) entries;
361c43e99fdSEd Maste 
362c43e99fdSEd Maste 	int n_cpus_hint;
363c43e99fdSEd Maste 	struct timeval max_dispatch_interval;
364c43e99fdSEd Maste 	int max_dispatch_callbacks;
365c43e99fdSEd Maste 	int limit_callbacks_after_prio;
366c43e99fdSEd Maste 	enum event_method_feature require_features;
367c43e99fdSEd Maste 	enum event_base_config_flag flags;
368c43e99fdSEd Maste };
369c43e99fdSEd Maste 
370c43e99fdSEd Maste /* Internal use only: Functions that might be missing from <sys/queue.h> */
371*b50261e2SCy Schubert #ifndef LIST_END
372*b50261e2SCy Schubert #define LIST_END(head)			NULL
373*b50261e2SCy Schubert #endif
374*b50261e2SCy Schubert 
375c43e99fdSEd Maste #ifndef TAILQ_FIRST
376c43e99fdSEd Maste #define	TAILQ_FIRST(head)		((head)->tqh_first)
377c43e99fdSEd Maste #endif
378c43e99fdSEd Maste #ifndef TAILQ_END
379c43e99fdSEd Maste #define	TAILQ_END(head)			NULL
380c43e99fdSEd Maste #endif
381c43e99fdSEd Maste #ifndef TAILQ_NEXT
382c43e99fdSEd Maste #define	TAILQ_NEXT(elm, field)		((elm)->field.tqe_next)
383c43e99fdSEd Maste #endif
384c43e99fdSEd Maste 
385c43e99fdSEd Maste #ifndef TAILQ_FOREACH
386c43e99fdSEd Maste #define TAILQ_FOREACH(var, head, field)					\
387c43e99fdSEd Maste 	for ((var) = TAILQ_FIRST(head);					\
388c43e99fdSEd Maste 	     (var) != TAILQ_END(head);					\
389c43e99fdSEd Maste 	     (var) = TAILQ_NEXT(var, field))
390c43e99fdSEd Maste #endif
391c43e99fdSEd Maste 
392c43e99fdSEd Maste #ifndef TAILQ_INSERT_BEFORE
393c43e99fdSEd Maste #define	TAILQ_INSERT_BEFORE(listelm, elm, field) do {			\
394c43e99fdSEd Maste 	(elm)->field.tqe_prev = (listelm)->field.tqe_prev;		\
395c43e99fdSEd Maste 	(elm)->field.tqe_next = (listelm);				\
396c43e99fdSEd Maste 	*(listelm)->field.tqe_prev = (elm);				\
397c43e99fdSEd Maste 	(listelm)->field.tqe_prev = &(elm)->field.tqe_next;		\
398c43e99fdSEd Maste } while (0)
399c43e99fdSEd Maste #endif
400c43e99fdSEd Maste 
401c43e99fdSEd Maste #define N_ACTIVE_CALLBACKS(base)					\
402c43e99fdSEd Maste 	((base)->event_count_active)
403c43e99fdSEd Maste 
404c43e99fdSEd Maste int evsig_set_handler_(struct event_base *base, int evsignal,
405c43e99fdSEd Maste 			  void (*fn)(int));
406c43e99fdSEd Maste int evsig_restore_handler_(struct event_base *base, int evsignal);
407c43e99fdSEd Maste 
408c43e99fdSEd Maste int event_add_nolock_(struct event *ev,
409c43e99fdSEd Maste     const struct timeval *tv, int tv_is_absolute);
410c43e99fdSEd Maste /** Argument for event_del_nolock_. Tells event_del not to block on the event
411c43e99fdSEd Maste  * if it's running in another thread. */
412c43e99fdSEd Maste #define EVENT_DEL_NOBLOCK 0
413c43e99fdSEd Maste /** Argument for event_del_nolock_. Tells event_del to block on the event
414c43e99fdSEd Maste  * if it's running in another thread, regardless of its value for EV_FINALIZE
415c43e99fdSEd Maste  */
416c43e99fdSEd Maste #define EVENT_DEL_BLOCK 1
417c43e99fdSEd Maste /** Argument for event_del_nolock_. Tells event_del to block on the event
418c43e99fdSEd Maste  * if it is running in another thread and it doesn't have EV_FINALIZE set.
419c43e99fdSEd Maste  */
420c43e99fdSEd Maste #define EVENT_DEL_AUTOBLOCK 2
421*b50261e2SCy Schubert /** Argument for event_del_nolock_. Tells event_del to proceed even if the
422c43e99fdSEd Maste  * event is set up for finalization rather for regular use.*/
423c43e99fdSEd Maste #define EVENT_DEL_EVEN_IF_FINALIZING 3
424c43e99fdSEd Maste int event_del_nolock_(struct event *ev, int blocking);
425c43e99fdSEd Maste int event_remove_timer_nolock_(struct event *ev);
426c43e99fdSEd Maste 
427c43e99fdSEd Maste void event_active_nolock_(struct event *ev, int res, short count);
428*b50261e2SCy Schubert EVENT2_EXPORT_SYMBOL
429c43e99fdSEd Maste int event_callback_activate_(struct event_base *, struct event_callback *);
430c43e99fdSEd Maste int event_callback_activate_nolock_(struct event_base *, struct event_callback *);
431c43e99fdSEd Maste int event_callback_cancel_(struct event_base *base,
432c43e99fdSEd Maste     struct event_callback *evcb);
433c43e99fdSEd Maste 
434c43e99fdSEd Maste void event_callback_finalize_nolock_(struct event_base *base, unsigned flags, struct event_callback *evcb, void (*cb)(struct event_callback *, void *));
435*b50261e2SCy Schubert EVENT2_EXPORT_SYMBOL
436c43e99fdSEd Maste void event_callback_finalize_(struct event_base *base, unsigned flags, struct event_callback *evcb, void (*cb)(struct event_callback *, void *));
437c43e99fdSEd Maste int event_callback_finalize_many_(struct event_base *base, int n_cbs, struct event_callback **evcb, void (*cb)(struct event_callback *, void *));
438c43e99fdSEd Maste 
439c43e99fdSEd Maste 
440*b50261e2SCy Schubert EVENT2_EXPORT_SYMBOL
441c43e99fdSEd Maste void event_active_later_(struct event *ev, int res);
442c43e99fdSEd Maste void event_active_later_nolock_(struct event *ev, int res);
443c43e99fdSEd Maste int event_callback_activate_later_nolock_(struct event_base *base,
444c43e99fdSEd Maste     struct event_callback *evcb);
445c43e99fdSEd Maste int event_callback_cancel_nolock_(struct event_base *base,
446c43e99fdSEd Maste     struct event_callback *evcb, int even_if_finalizing);
447c43e99fdSEd Maste void event_callback_init_(struct event_base *base,
448c43e99fdSEd Maste     struct event_callback *cb);
449c43e99fdSEd Maste 
450c43e99fdSEd Maste /* FIXME document. */
451*b50261e2SCy Schubert EVENT2_EXPORT_SYMBOL
452c43e99fdSEd Maste void event_base_add_virtual_(struct event_base *base);
453c43e99fdSEd Maste void event_base_del_virtual_(struct event_base *base);
454c43e99fdSEd Maste 
455c43e99fdSEd Maste /** For debugging: unless assertions are disabled, verify the referential
456c43e99fdSEd Maste     integrity of the internal data structures of 'base'.  This operation can
457c43e99fdSEd Maste     be expensive.
458c43e99fdSEd Maste 
459c43e99fdSEd Maste     Returns on success; aborts on failure.
460c43e99fdSEd Maste */
461*b50261e2SCy Schubert EVENT2_EXPORT_SYMBOL
462c43e99fdSEd Maste void event_base_assert_ok_(struct event_base *base);
463c43e99fdSEd Maste void event_base_assert_ok_nolock_(struct event_base *base);
464c43e99fdSEd Maste 
465c43e99fdSEd Maste 
466c43e99fdSEd Maste /* Helper function: Call 'fn' exactly once every inserted or active event in
467c43e99fdSEd Maste  * the event_base 'base'.
468c43e99fdSEd Maste  *
469c43e99fdSEd Maste  * If fn returns 0, continue on to the next event. Otherwise, return the same
470c43e99fdSEd Maste  * value that fn returned.
471c43e99fdSEd Maste  *
472c43e99fdSEd Maste  * Requires that 'base' be locked.
473c43e99fdSEd Maste  */
474c43e99fdSEd Maste int event_base_foreach_event_nolock_(struct event_base *base,
475c43e99fdSEd Maste     event_base_foreach_event_cb cb, void *arg);
476c43e99fdSEd Maste 
477c43e99fdSEd Maste /* Cleanup function to reset debug mode during shutdown.
478c43e99fdSEd Maste  *
479c43e99fdSEd Maste  * Calling this function doesn't mean it'll be possible to re-enable
480c43e99fdSEd Maste  * debug mode if any events were added.
481c43e99fdSEd Maste  */
482c43e99fdSEd Maste void event_disable_debug_mode(void);
483c43e99fdSEd Maste 
484c43e99fdSEd Maste #ifdef __cplusplus
485c43e99fdSEd Maste }
486c43e99fdSEd Maste #endif
487c43e99fdSEd Maste 
488c43e99fdSEd Maste #endif /* EVENT_INTERNAL_H_INCLUDED_ */
489