File Coverage

libev/ev.h
Criterion Covered Total %
statement 4 4 100.0
branch n/a
condition n/a
subroutine n/a
pod n/a
total 4 4 100.0


line stmt bran cond sub pod time code
1             /*
2             * libev native API header
3             *
4             * Copyright (c) 2007-2020 Marc Alexander Lehmann
5             * All rights reserved.
6             *
7             * Redistribution and use in source and binary forms, with or without modifica-
8             * tion, are permitted provided that the following conditions are met:
9             *
10             * 1. Redistributions of source code must retain the above copyright notice,
11             * this list of conditions and the following disclaimer.
12             *
13             * 2. Redistributions in binary form must reproduce the above copyright
14             * notice, this list of conditions and the following disclaimer in the
15             * documentation and/or other materials provided with the distribution.
16             *
17             * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
18             * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER-
19             * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
20             * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE-
21             * CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22             * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
23             * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24             * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH-
25             * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
26             * OF THE POSSIBILITY OF SUCH DAMAGE.
27             *
28             * Alternatively, the contents of this file may be used under the terms of
29             * the GNU General Public License ("GPL") version 2 or any later version,
30             * in which case the provisions of the GPL are applicable instead of
31             * the above. If you wish to allow the use of your version of this file
32             * only under the terms of the GPL and not to allow others to use your
33             * version of this file under the BSD license, indicate your decision
34             * by deleting the provisions above and replace them with the notice
35             * and other provisions required by the GPL. If you do not delete the
36             * provisions above, a recipient may use your version of this file under
37             * either the BSD or the GPL.
38             */
39              
40             #ifndef EV_H_
41             #define EV_H_
42              
43             #ifdef __cplusplus
44             # define EV_CPP(x) x
45             # if __cplusplus >= 201103L
46             # define EV_NOEXCEPT noexcept
47             # else
48             # define EV_NOEXCEPT
49             # endif
50             #else
51             # define EV_CPP(x)
52             # define EV_NOEXCEPT
53             #endif
54             #define EV_THROW EV_NOEXCEPT /* pre-4.25, do not use in new code */
55              
56             EV_CPP(extern "C" {)
57              
58             /*****************************************************************************/
59              
60             /* pre-4.0 compatibility */
61             #ifndef EV_COMPAT3
62             # define EV_COMPAT3 1
63             #endif
64              
65             #ifndef EV_FEATURES
66             # if defined __OPTIMIZE_SIZE__
67             # define EV_FEATURES 0x7c
68             # else
69             # define EV_FEATURES 0x7f
70             # endif
71             #endif
72              
73             #define EV_FEATURE_CODE ((EV_FEATURES) & 1)
74             #define EV_FEATURE_DATA ((EV_FEATURES) & 2)
75             #define EV_FEATURE_CONFIG ((EV_FEATURES) & 4)
76             #define EV_FEATURE_API ((EV_FEATURES) & 8)
77             #define EV_FEATURE_WATCHERS ((EV_FEATURES) & 16)
78             #define EV_FEATURE_BACKENDS ((EV_FEATURES) & 32)
79             #define EV_FEATURE_OS ((EV_FEATURES) & 64)
80              
81             /* these priorities are inclusive, higher priorities will be invoked earlier */
82             #ifndef EV_MINPRI
83             # define EV_MINPRI (EV_FEATURE_CONFIG ? -2 : 0)
84             #endif
85             #ifndef EV_MAXPRI
86             # define EV_MAXPRI (EV_FEATURE_CONFIG ? +2 : 0)
87             #endif
88              
89             #ifndef EV_MULTIPLICITY
90             # define EV_MULTIPLICITY EV_FEATURE_CONFIG
91             #endif
92              
93             #ifndef EV_PERIODIC_ENABLE
94             # define EV_PERIODIC_ENABLE EV_FEATURE_WATCHERS
95             #endif
96              
97             #ifndef EV_STAT_ENABLE
98             # define EV_STAT_ENABLE EV_FEATURE_WATCHERS
99             #endif
100              
101             #ifndef EV_PREPARE_ENABLE
102             # define EV_PREPARE_ENABLE EV_FEATURE_WATCHERS
103             #endif
104              
105             #ifndef EV_CHECK_ENABLE
106             # define EV_CHECK_ENABLE EV_FEATURE_WATCHERS
107             #endif
108              
109             #ifndef EV_IDLE_ENABLE
110             # define EV_IDLE_ENABLE EV_FEATURE_WATCHERS
111             #endif
112              
113             #ifndef EV_FORK_ENABLE
114             # define EV_FORK_ENABLE EV_FEATURE_WATCHERS
115             #endif
116              
117             #ifndef EV_CLEANUP_ENABLE
118             # define EV_CLEANUP_ENABLE EV_FEATURE_WATCHERS
119             #endif
120              
121             #ifndef EV_SIGNAL_ENABLE
122             # define EV_SIGNAL_ENABLE EV_FEATURE_WATCHERS
123             #endif
124              
125             #ifndef EV_CHILD_ENABLE
126             # ifdef _WIN32
127             # define EV_CHILD_ENABLE 0
128             # else
129             # define EV_CHILD_ENABLE EV_FEATURE_WATCHERS
130             #endif
131             #endif
132              
133             #ifndef EV_ASYNC_ENABLE
134             # define EV_ASYNC_ENABLE EV_FEATURE_WATCHERS
135             #endif
136              
137             #ifndef EV_EMBED_ENABLE
138             # define EV_EMBED_ENABLE EV_FEATURE_WATCHERS
139             #endif
140              
141             #ifndef EV_WALK_ENABLE
142             # define EV_WALK_ENABLE 0 /* not yet */
143             #endif
144              
145             /*****************************************************************************/
146              
147             #if EV_CHILD_ENABLE && !EV_SIGNAL_ENABLE
148             # undef EV_SIGNAL_ENABLE
149             # define EV_SIGNAL_ENABLE 1
150             #endif
151              
152             /*****************************************************************************/
153              
154             #ifndef EV_TSTAMP_T
155             # define EV_TSTAMP_T double
156             #endif
157             typedef EV_TSTAMP_T ev_tstamp;
158              
159             #include /* for memmove */
160              
161             #ifndef EV_ATOMIC_T
162             # include
163             # define EV_ATOMIC_T sig_atomic_t volatile
164             #endif
165              
166             #if EV_STAT_ENABLE
167             # ifdef _WIN32
168             # include
169             # include
170             # endif
171             # include
172             #endif
173              
174             /* support multiple event loops? */
175             #if EV_MULTIPLICITY
176             struct ev_loop;
177             # define EV_P struct ev_loop *loop /* a loop as sole parameter in a declaration */
178             # define EV_P_ EV_P, /* a loop as first of multiple parameters */
179             # define EV_A loop /* a loop as sole argument to a function call */
180             # define EV_A_ EV_A, /* a loop as first of multiple arguments */
181             # define EV_DEFAULT_UC ev_default_loop_uc_ () /* the default loop, if initialised, as sole arg */
182             # define EV_DEFAULT_UC_ EV_DEFAULT_UC, /* the default loop as first of multiple arguments */
183             # define EV_DEFAULT ev_default_loop (0) /* the default loop as sole arg */
184             # define EV_DEFAULT_ EV_DEFAULT, /* the default loop as first of multiple arguments */
185             #else
186             # define EV_P void
187             # define EV_P_
188             # define EV_A
189             # define EV_A_
190             # define EV_DEFAULT
191             # define EV_DEFAULT_
192             # define EV_DEFAULT_UC
193             # define EV_DEFAULT_UC_
194             # undef EV_EMBED_ENABLE
195             #endif
196              
197             /* EV_INLINE is used for functions in header files */
198             #if __STDC_VERSION__ >= 199901L || __GNUC__ >= 3
199             # define EV_INLINE static inline
200             #else
201             # define EV_INLINE static
202             #endif
203              
204             #ifdef EV_API_STATIC
205             # define EV_API_DECL static
206             #else
207             # define EV_API_DECL extern
208             #endif
209              
210             /* EV_PROTOTYPES can be used to switch of prototype declarations */
211             #ifndef EV_PROTOTYPES
212             # define EV_PROTOTYPES 1
213             #endif
214              
215             /*****************************************************************************/
216              
217             #define EV_VERSION_MAJOR 4
218             #define EV_VERSION_MINOR 32
219              
220             /* eventmask, revents, events... */
221             enum {
222             EV_UNDEF = (int)0xFFFFFFFF, /* guaranteed to be invalid */
223             EV_NONE = 0x00, /* no events */
224             EV_READ = 0x01, /* ev_io detected read will not block */
225             EV_WRITE = 0x02, /* ev_io detected write will not block */
226             EV__IOFDSET = 0x80, /* internal use only */
227             EV_IO = EV_READ, /* alias for type-detection */
228             EV_TIMER = 0x00000100, /* timer timed out */
229             #if EV_COMPAT3
230             EV_TIMEOUT = EV_TIMER, /* pre 4.0 API compatibility */
231             #endif
232             EV_PERIODIC = 0x00000200, /* periodic timer timed out */
233             EV_SIGNAL = 0x00000400, /* signal was received */
234             EV_CHILD = 0x00000800, /* child/pid had status change */
235             EV_STAT = 0x00001000, /* stat data changed */
236             EV_IDLE = 0x00002000, /* event loop is idling */
237             EV_PREPARE = 0x00004000, /* event loop about to poll */
238             EV_CHECK = 0x00008000, /* event loop finished poll */
239             EV_EMBED = 0x00010000, /* embedded event loop needs sweep */
240             EV_FORK = 0x00020000, /* event loop resumed in child */
241             EV_CLEANUP = 0x00040000, /* event loop resumed in child */
242             EV_ASYNC = 0x00080000, /* async intra-loop signal */
243             EV_CUSTOM = 0x01000000, /* for use by user code */
244             EV_ERROR = (int)0x80000000 /* sent when an error occurs */
245             };
246              
247             /* can be used to add custom fields to all watchers, while losing binary compatibility */
248             #ifndef EV_COMMON
249             # define EV_COMMON void *data;
250             #endif
251              
252             #ifndef EV_CB_DECLARE
253             # define EV_CB_DECLARE(type) void (*cb)(EV_P_ struct type *w, int revents);
254             #endif
255             #ifndef EV_CB_INVOKE
256             # define EV_CB_INVOKE(watcher,revents) (watcher)->cb (EV_A_ (watcher), (revents))
257             #endif
258              
259             /* not official, do not use */
260             #define EV_CB(type,name) void name (EV_P_ struct ev_ ## type *w, int revents)
261              
262             /*
263             * struct member types:
264             * private: you may look at them, but not change them,
265             * and they might not mean anything to you.
266             * ro: can be read anytime, but only changed when the watcher isn't active.
267             * rw: can be read and modified anytime, even when the watcher is active.
268             *
269             * some internal details that might be helpful for debugging:
270             *
271             * active is either 0, which means the watcher is not active,
272             * or the array index of the watcher (periodics, timers)
273             * or the array index + 1 (most other watchers)
274             * or simply 1 for watchers that aren't in some array.
275             * pending is either 0, in which case the watcher isn't,
276             * or the array index + 1 in the pendings array.
277             */
278              
279             #if EV_MINPRI == EV_MAXPRI
280             # define EV_DECL_PRIORITY
281             #elif !defined (EV_DECL_PRIORITY)
282             # define EV_DECL_PRIORITY int priority;
283             #endif
284              
285             /* shared by all watchers */
286             #define EV_WATCHER(type) \
287             int active; /* private */ \
288             int pending; /* private */ \
289             EV_DECL_PRIORITY /* private */ \
290             EV_COMMON /* rw */ \
291             EV_CB_DECLARE (type) /* private */
292              
293             #define EV_WATCHER_LIST(type) \
294             EV_WATCHER (type) \
295             struct ev_watcher_list *next; /* private */
296              
297             #define EV_WATCHER_TIME(type) \
298             EV_WATCHER (type) \
299             ev_tstamp at; /* private */
300              
301             /* base class, nothing to see here unless you subclass */
302             typedef struct ev_watcher
303             {
304             EV_WATCHER (ev_watcher)
305             } ev_watcher;
306              
307             /* base class, nothing to see here unless you subclass */
308             typedef struct ev_watcher_list
309             {
310             EV_WATCHER_LIST (ev_watcher_list)
311             } ev_watcher_list;
312              
313             /* base class, nothing to see here unless you subclass */
314             typedef struct ev_watcher_time
315             {
316             EV_WATCHER_TIME (ev_watcher_time)
317             } ev_watcher_time;
318              
319             /* invoked when fd is either EV_READable or EV_WRITEable */
320             /* revent EV_READ, EV_WRITE */
321             typedef struct ev_io
322             {
323             EV_WATCHER_LIST (ev_io)
324              
325             int fd; /* ro */
326             int events; /* ro */
327             } ev_io;
328              
329             /* invoked after a specific time, repeatable (based on monotonic clock) */
330             /* revent EV_TIMEOUT */
331             typedef struct ev_timer
332             {
333             EV_WATCHER_TIME (ev_timer)
334              
335             ev_tstamp repeat; /* rw */
336             } ev_timer;
337              
338             /* invoked at some specific time, possibly repeating at regular intervals (based on UTC) */
339             /* revent EV_PERIODIC */
340             typedef struct ev_periodic
341             {
342             EV_WATCHER_TIME (ev_periodic)
343              
344             ev_tstamp offset; /* rw */
345             ev_tstamp interval; /* rw */
346             ev_tstamp (*reschedule_cb)(struct ev_periodic *w, ev_tstamp now) EV_NOEXCEPT; /* rw */
347             } ev_periodic;
348              
349             /* invoked when the given signal has been received */
350             /* revent EV_SIGNAL */
351             typedef struct ev_signal
352             {
353             EV_WATCHER_LIST (ev_signal)
354              
355             int signum; /* ro */
356             } ev_signal;
357              
358             /* invoked when sigchld is received and waitpid indicates the given pid */
359             /* revent EV_CHILD */
360             /* does not support priorities */
361             typedef struct ev_child
362             {
363             EV_WATCHER_LIST (ev_child)
364              
365             int flags; /* private */
366             int pid; /* ro */
367             int rpid; /* rw, holds the received pid */
368             int rstatus; /* rw, holds the exit status, use the macros from sys/wait.h */
369             } ev_child;
370              
371             #if EV_STAT_ENABLE
372             /* st_nlink = 0 means missing file or other error */
373             # ifdef _WIN32
374             typedef struct _stati64 ev_statdata;
375             # else
376             typedef struct stat ev_statdata;
377             # endif
378              
379             /* invoked each time the stat data changes for a given path */
380             /* revent EV_STAT */
381             typedef struct ev_stat
382             {
383             EV_WATCHER_LIST (ev_stat)
384              
385             ev_timer timer; /* private */
386             ev_tstamp interval; /* ro */
387             const char *path; /* ro */
388             ev_statdata prev; /* ro */
389             ev_statdata attr; /* ro */
390              
391             int wd; /* wd for inotify, fd for kqueue */
392             } ev_stat;
393             #endif
394              
395             /* invoked when the nothing else needs to be done, keeps the process from blocking */
396             /* revent EV_IDLE */
397             typedef struct ev_idle
398             {
399             EV_WATCHER (ev_idle)
400             } ev_idle;
401              
402             /* invoked for each run of the mainloop, just before the blocking call */
403             /* you can still change events in any way you like */
404             /* revent EV_PREPARE */
405             typedef struct ev_prepare
406             {
407             EV_WATCHER (ev_prepare)
408             } ev_prepare;
409              
410             /* invoked for each run of the mainloop, just after the blocking call */
411             /* revent EV_CHECK */
412             typedef struct ev_check
413             {
414             EV_WATCHER (ev_check)
415             } ev_check;
416              
417             /* the callback gets invoked before check in the child process when a fork was detected */
418             /* revent EV_FORK */
419             typedef struct ev_fork
420             {
421             EV_WATCHER (ev_fork)
422             } ev_fork;
423              
424             /* is invoked just before the loop gets destroyed */
425             /* revent EV_CLEANUP */
426             typedef struct ev_cleanup
427             {
428             EV_WATCHER (ev_cleanup)
429             } ev_cleanup;
430              
431             #if EV_EMBED_ENABLE
432             /* used to embed an event loop inside another */
433             /* the callback gets invoked when the event loop has handled events, and can be 0 */
434             typedef struct ev_embed
435             {
436             EV_WATCHER (ev_embed)
437              
438             struct ev_loop *other; /* ro */
439             #undef EV_IO_ENABLE
440             #define EV_IO_ENABLE 1
441             ev_io io; /* private */
442             #undef EV_PREPARE_ENABLE
443             #define EV_PREPARE_ENABLE 1
444             ev_prepare prepare; /* private */
445             ev_check check; /* unused */
446             ev_timer timer; /* unused */
447             ev_periodic periodic; /* unused */
448             ev_idle idle; /* unused */
449             ev_fork fork; /* private */
450             ev_cleanup cleanup; /* unused */
451             } ev_embed;
452             #endif
453              
454             #if EV_ASYNC_ENABLE
455             /* invoked when somebody calls ev_async_send on the watcher */
456             /* revent EV_ASYNC */
457             typedef struct ev_async
458             {
459             EV_WATCHER (ev_async)
460              
461             EV_ATOMIC_T sent; /* private */
462             } ev_async;
463              
464             # define ev_async_pending(w) (+(w)->sent)
465             #endif
466              
467             /* the presence of this union forces similar struct layout */
468             union ev_any_watcher
469             {
470             struct ev_watcher w;
471             struct ev_watcher_list wl;
472              
473             struct ev_io io;
474             struct ev_timer timer;
475             struct ev_periodic periodic;
476             struct ev_signal signal;
477             struct ev_child child;
478             #if EV_STAT_ENABLE
479             struct ev_stat stat;
480             #endif
481             #if EV_IDLE_ENABLE
482             struct ev_idle idle;
483             #endif
484             struct ev_prepare prepare;
485             struct ev_check check;
486             #if EV_FORK_ENABLE
487             struct ev_fork fork;
488             #endif
489             #if EV_CLEANUP_ENABLE
490             struct ev_cleanup cleanup;
491             #endif
492             #if EV_EMBED_ENABLE
493             struct ev_embed embed;
494             #endif
495             #if EV_ASYNC_ENABLE
496             struct ev_async async;
497             #endif
498             };
499              
500             /* flag bits for ev_default_loop and ev_loop_new */
501             enum {
502             /* the default */
503             EVFLAG_AUTO = 0x00000000U, /* not quite a mask */
504             /* flag bits */
505             EVFLAG_NOENV = 0x01000000U, /* do NOT consult environment */
506             EVFLAG_FORKCHECK = 0x02000000U, /* check for a fork in each iteration */
507             /* debugging/feature disable */
508             EVFLAG_NOINOTIFY = 0x00100000U, /* do not attempt to use inotify */
509             #if EV_COMPAT3
510             EVFLAG_NOSIGFD = 0, /* compatibility to pre-3.9 */
511             #endif
512             EVFLAG_SIGNALFD = 0x00200000U, /* attempt to use signalfd */
513             EVFLAG_NOSIGMASK = 0x00400000U, /* avoid modifying the signal mask */
514             EVFLAG_NOTIMERFD = 0x00800000U /* avoid creating a timerfd */
515             };
516              
517             /* method bits to be ored together */
518             enum {
519             EVBACKEND_SELECT = 0x00000001U, /* available just about anywhere */
520             EVBACKEND_POLL = 0x00000002U, /* !win, !aix, broken on osx */
521             EVBACKEND_EPOLL = 0x00000004U, /* linux */
522             EVBACKEND_KQUEUE = 0x00000008U, /* bsd, broken on osx */
523             EVBACKEND_DEVPOLL = 0x00000010U, /* solaris 8 */ /* NYI */
524             EVBACKEND_PORT = 0x00000020U, /* solaris 10 */
525             EVBACKEND_LINUXAIO = 0x00000040U, /* linux AIO, 4.19+ */
526             EVBACKEND_IOURING = 0x00000080U, /* linux io_uring, 5.1+ */
527             EVBACKEND_ALL = 0x000000FFU, /* all known backends */
528             EVBACKEND_MASK = 0x0000FFFFU /* all future backends */
529             };
530              
531             #if EV_PROTOTYPES
532             EV_API_DECL int ev_version_major (void) EV_NOEXCEPT;
533             EV_API_DECL int ev_version_minor (void) EV_NOEXCEPT;
534              
535             EV_API_DECL unsigned int ev_supported_backends (void) EV_NOEXCEPT;
536             EV_API_DECL unsigned int ev_recommended_backends (void) EV_NOEXCEPT;
537             EV_API_DECL unsigned int ev_embeddable_backends (void) EV_NOEXCEPT;
538              
539             EV_API_DECL ev_tstamp ev_time (void) EV_NOEXCEPT;
540             EV_API_DECL void ev_sleep (ev_tstamp delay) EV_NOEXCEPT; /* sleep for a while */
541              
542             /* Sets the allocation function to use, works like realloc.
543             * It is used to allocate and free memory.
544             * If it returns zero when memory needs to be allocated, the library might abort
545             * or take some potentially destructive action.
546             * The default is your system realloc function.
547             */
548             EV_API_DECL void ev_set_allocator (void *(*cb)(void *ptr, long size) EV_NOEXCEPT) EV_NOEXCEPT;
549              
550             /* set the callback function to call on a
551             * retryable syscall error
552             * (such as failed select, poll, epoll_wait)
553             */
554             EV_API_DECL void ev_set_syserr_cb (void (*cb)(const char *msg) EV_NOEXCEPT) EV_NOEXCEPT;
555              
556             #if EV_MULTIPLICITY
557              
558             /* the default loop is the only one that handles signals and child watchers */
559             /* you can call this as often as you like */
560             EV_API_DECL struct ev_loop *ev_default_loop (unsigned int flags EV_CPP (= 0)) EV_NOEXCEPT;
561              
562             #ifdef EV_API_STATIC
563             EV_API_DECL struct ev_loop *ev_default_loop_ptr;
564             #endif
565              
566             EV_INLINE struct ev_loop *
567 4           ev_default_loop_uc_ (void) EV_NOEXCEPT
568             {
569             extern struct ev_loop *ev_default_loop_ptr;
570              
571 4           return ev_default_loop_ptr;
572             }
573              
574             EV_INLINE int
575 4           ev_is_default_loop (EV_P) EV_NOEXCEPT
576             {
577 4           return EV_A == EV_DEFAULT_UC;
578             }
579              
580             /* create and destroy alternative loops that don't handle signals */
581             EV_API_DECL struct ev_loop *ev_loop_new (unsigned int flags EV_CPP (= 0)) EV_NOEXCEPT;
582              
583             EV_API_DECL ev_tstamp ev_now (EV_P) EV_NOEXCEPT; /* time w.r.t. timers and the eventloop, updated after each poll */
584              
585             #else
586              
587             EV_API_DECL int ev_default_loop (unsigned int flags EV_CPP (= 0)) EV_NOEXCEPT; /* returns true when successful */
588              
589             EV_API_DECL ev_tstamp ev_rt_now;
590              
591             EV_INLINE ev_tstamp
592             ev_now (void) EV_NOEXCEPT
593             {
594             return ev_rt_now;
595             }
596              
597             /* looks weird, but ev_is_default_loop (EV_A) still works if this exists */
598             EV_INLINE int
599             ev_is_default_loop (void) EV_NOEXCEPT
600             {
601             return 1;
602             }
603              
604             #endif /* multiplicity */
605              
606             /* destroy event loops, also works for the default loop */
607             EV_API_DECL void ev_loop_destroy (EV_P);
608              
609             /* this needs to be called after fork, to duplicate the loop */
610             /* when you want to re-use it in the child */
611             /* you can call it in either the parent or the child */
612             /* you can actually call it at any time, anywhere :) */
613             EV_API_DECL void ev_loop_fork (EV_P) EV_NOEXCEPT;
614              
615             EV_API_DECL unsigned int ev_backend (EV_P) EV_NOEXCEPT; /* backend in use by loop */
616              
617             EV_API_DECL void ev_now_update (EV_P) EV_NOEXCEPT; /* update event loop time */
618              
619             #if EV_WALK_ENABLE
620             /* walk (almost) all watchers in the loop of a given type, invoking the */
621             /* callback on every such watcher. The callback might stop the watcher, */
622             /* but do nothing else with the loop */
623             EV_API_DECL void ev_walk (EV_P_ int types, void (*cb)(EV_P_ int type, void *w)) EV_NOEXCEPT;
624             #endif
625              
626             #endif /* prototypes */
627              
628             /* ev_run flags values */
629             enum {
630             EVRUN_NOWAIT = 1, /* do not block/wait */
631             EVRUN_ONCE = 2 /* block *once* only */
632             };
633              
634             /* ev_break how values */
635             enum {
636             EVBREAK_CANCEL = 0, /* undo unloop */
637             EVBREAK_ONE = 1, /* unloop once */
638             EVBREAK_ALL = 2 /* unloop all loops */
639             };
640              
641             #if EV_PROTOTYPES
642             EV_API_DECL int ev_run (EV_P_ int flags EV_CPP (= 0));
643             EV_API_DECL void ev_break (EV_P_ int how EV_CPP (= EVBREAK_ONE)) EV_NOEXCEPT; /* break out of the loop */
644              
645             /*
646             * ref/unref can be used to add or remove a refcount on the mainloop. every watcher
647             * keeps one reference. if you have a long-running watcher you never unregister that
648             * should not keep ev_loop from running, unref() after starting, and ref() before stopping.
649             */
650             EV_API_DECL void ev_ref (EV_P) EV_NOEXCEPT;
651             EV_API_DECL void ev_unref (EV_P) EV_NOEXCEPT;
652              
653             /*
654             * convenience function, wait for a single event, without registering an event watcher
655             * if timeout is < 0, do wait indefinitely
656             */
657             EV_API_DECL void ev_once (EV_P_ int fd, int events, ev_tstamp timeout, void (*cb)(int revents, void *arg), void *arg) EV_NOEXCEPT;
658              
659             EV_API_DECL void ev_invoke_pending (EV_P); /* invoke all pending watchers */
660              
661             # if EV_FEATURE_API
662             EV_API_DECL unsigned int ev_iteration (EV_P) EV_NOEXCEPT; /* number of loop iterations */
663             EV_API_DECL unsigned int ev_depth (EV_P) EV_NOEXCEPT; /* #ev_loop enters - #ev_loop leaves */
664             EV_API_DECL void ev_verify (EV_P) EV_NOEXCEPT; /* abort if loop data corrupted */
665              
666             EV_API_DECL void ev_set_io_collect_interval (EV_P_ ev_tstamp interval) EV_NOEXCEPT; /* sleep at least this time, default 0 */
667             EV_API_DECL void ev_set_timeout_collect_interval (EV_P_ ev_tstamp interval) EV_NOEXCEPT; /* sleep at least this time, default 0 */
668              
669             /* advanced stuff for threading etc. support, see docs */
670             EV_API_DECL void ev_set_userdata (EV_P_ void *data) EV_NOEXCEPT;
671             EV_API_DECL void *ev_userdata (EV_P) EV_NOEXCEPT;
672             typedef void (*ev_loop_callback)(EV_P);
673             EV_API_DECL void ev_set_invoke_pending_cb (EV_P_ ev_loop_callback invoke_pending_cb) EV_NOEXCEPT;
674             /* C++ doesn't allow the use of the ev_loop_callback typedef here, so we need to spell it out */
675             EV_API_DECL void ev_set_loop_release_cb (EV_P_ void (*release)(EV_P) EV_NOEXCEPT, void (*acquire)(EV_P) EV_NOEXCEPT) EV_NOEXCEPT;
676              
677             EV_API_DECL unsigned int ev_pending_count (EV_P) EV_NOEXCEPT; /* number of pending events, if any */
678              
679             /*
680             * stop/start the timer handling.
681             */
682             EV_API_DECL void ev_suspend (EV_P) EV_NOEXCEPT;
683             EV_API_DECL void ev_resume (EV_P) EV_NOEXCEPT;
684             #endif
685              
686             #endif
687              
688             /* these may evaluate ev multiple times, and the other arguments at most once */
689             /* either use ev_init + ev_TYPE_set, or the ev_TYPE_init macro, below, to first initialise a watcher */
690             #define ev_init(ev,cb_) do { \
691             ((ev_watcher *)(void *)(ev))->active = \
692             ((ev_watcher *)(void *)(ev))->pending = 0; \
693             ev_set_priority ((ev), 0); \
694             ev_set_cb ((ev), cb_); \
695             } while (0)
696              
697             #define ev_io_modify(ev,events_) do { (ev)->events = (ev)->events & EV__IOFDSET | (events_); } while (0)
698             #define ev_io_set(ev,fd_,events_) do { (ev)->fd = (fd_); (ev)->events = (events_) | EV__IOFDSET; } while (0)
699             #define ev_timer_set(ev,after_,repeat_) do { ((ev_watcher_time *)(ev))->at = (after_); (ev)->repeat = (repeat_); } while (0)
700             #define ev_periodic_set(ev,ofs_,ival_,rcb_) do { (ev)->offset = (ofs_); (ev)->interval = (ival_); (ev)->reschedule_cb = (rcb_); } while (0)
701             #define ev_signal_set(ev,signum_) do { (ev)->signum = (signum_); } while (0)
702             #define ev_child_set(ev,pid_,trace_) do { (ev)->pid = (pid_); (ev)->flags = !!(trace_); } while (0)
703             #define ev_stat_set(ev,path_,interval_) do { (ev)->path = (path_); (ev)->interval = (interval_); (ev)->wd = -2; } while (0)
704             #define ev_idle_set(ev) /* nop, yes, this is a serious in-joke */
705             #define ev_prepare_set(ev) /* nop, yes, this is a serious in-joke */
706             #define ev_check_set(ev) /* nop, yes, this is a serious in-joke */
707             #define ev_embed_set(ev,other_) do { (ev)->other = (other_); } while (0)
708             #define ev_fork_set(ev) /* nop, yes, this is a serious in-joke */
709             #define ev_cleanup_set(ev) /* nop, yes, this is a serious in-joke */
710             #define ev_async_set(ev) /* nop, yes, this is a serious in-joke */
711              
712             #define ev_io_init(ev,cb,fd,events) do { ev_init ((ev), (cb)); ev_io_set ((ev),(fd),(events)); } while (0)
713             #define ev_timer_init(ev,cb,after,repeat) do { ev_init ((ev), (cb)); ev_timer_set ((ev),(after),(repeat)); } while (0)
714             #define ev_periodic_init(ev,cb,ofs,ival,rcb) do { ev_init ((ev), (cb)); ev_periodic_set ((ev),(ofs),(ival),(rcb)); } while (0)
715             #define ev_signal_init(ev,cb,signum) do { ev_init ((ev), (cb)); ev_signal_set ((ev), (signum)); } while (0)
716             #define ev_child_init(ev,cb,pid,trace) do { ev_init ((ev), (cb)); ev_child_set ((ev),(pid),(trace)); } while (0)
717             #define ev_stat_init(ev,cb,path,interval) do { ev_init ((ev), (cb)); ev_stat_set ((ev),(path),(interval)); } while (0)
718             #define ev_idle_init(ev,cb) do { ev_init ((ev), (cb)); ev_idle_set ((ev)); } while (0)
719             #define ev_prepare_init(ev,cb) do { ev_init ((ev), (cb)); ev_prepare_set ((ev)); } while (0)
720             #define ev_check_init(ev,cb) do { ev_init ((ev), (cb)); ev_check_set ((ev)); } while (0)
721             #define ev_embed_init(ev,cb,other) do { ev_init ((ev), (cb)); ev_embed_set ((ev),(other)); } while (0)
722             #define ev_fork_init(ev,cb) do { ev_init ((ev), (cb)); ev_fork_set ((ev)); } while (0)
723             #define ev_cleanup_init(ev,cb) do { ev_init ((ev), (cb)); ev_cleanup_set ((ev)); } while (0)
724             #define ev_async_init(ev,cb) do { ev_init ((ev), (cb)); ev_async_set ((ev)); } while (0)
725              
726             #define ev_is_pending(ev) (0 + ((ev_watcher *)(void *)(ev))->pending) /* ro, true when watcher is waiting for callback invocation */
727             #define ev_is_active(ev) (0 + ((ev_watcher *)(void *)(ev))->active) /* ro, true when the watcher has been started */
728              
729             #define ev_cb_(ev) (ev)->cb /* rw */
730             #define ev_cb(ev) (memmove (&ev_cb_ (ev), &((ev_watcher *)(ev))->cb, sizeof (ev_cb_ (ev))), (ev)->cb)
731              
732             #if EV_MINPRI == EV_MAXPRI
733             # define ev_priority(ev) ((ev), EV_MINPRI)
734             # define ev_set_priority(ev,pri) ((ev), (pri))
735             #else
736             # define ev_priority(ev) (+(((ev_watcher *)(void *)(ev))->priority))
737             # define ev_set_priority(ev,pri) ( (ev_watcher *)(void *)(ev))->priority = (pri)
738             #endif
739              
740             #define ev_periodic_at(ev) (+((ev_watcher_time *)(ev))->at)
741              
742             #ifndef ev_set_cb
743             /* memmove is used here to avoid strict aliasing violations, and hopefully is optimized out by any reasonable compiler */
744             # define ev_set_cb(ev,cb_) (ev_cb_ (ev) = (cb_), memmove (&((ev_watcher *)(ev))->cb, &ev_cb_ (ev), sizeof (ev_cb_ (ev))))
745             #endif
746              
747             /* stopping (enabling, adding) a watcher does nothing if it is already running */
748             /* stopping (disabling, deleting) a watcher does nothing unless it's already running */
749             #if EV_PROTOTYPES
750              
751             /* feeds an event into a watcher as if the event actually occurred */
752             /* accepts any ev_watcher type */
753             EV_API_DECL void ev_feed_event (EV_P_ void *w, int revents) EV_NOEXCEPT;
754             EV_API_DECL void ev_feed_fd_event (EV_P_ int fd, int revents) EV_NOEXCEPT;
755             #if EV_SIGNAL_ENABLE
756             EV_API_DECL void ev_feed_signal (int signum) EV_NOEXCEPT;
757             EV_API_DECL void ev_feed_signal_event (EV_P_ int signum) EV_NOEXCEPT;
758             #endif
759             EV_API_DECL void ev_invoke (EV_P_ void *w, int revents);
760             EV_API_DECL int ev_clear_pending (EV_P_ void *w) EV_NOEXCEPT;
761              
762             EV_API_DECL void ev_io_start (EV_P_ ev_io *w) EV_NOEXCEPT;
763             EV_API_DECL void ev_io_stop (EV_P_ ev_io *w) EV_NOEXCEPT;
764              
765             EV_API_DECL void ev_timer_start (EV_P_ ev_timer *w) EV_NOEXCEPT;
766             EV_API_DECL void ev_timer_stop (EV_P_ ev_timer *w) EV_NOEXCEPT;
767             /* stops if active and no repeat, restarts if active and repeating, starts if inactive and repeating */
768             EV_API_DECL void ev_timer_again (EV_P_ ev_timer *w) EV_NOEXCEPT;
769             /* return remaining time */
770             EV_API_DECL ev_tstamp ev_timer_remaining (EV_P_ ev_timer *w) EV_NOEXCEPT;
771              
772             #if EV_PERIODIC_ENABLE
773             EV_API_DECL void ev_periodic_start (EV_P_ ev_periodic *w) EV_NOEXCEPT;
774             EV_API_DECL void ev_periodic_stop (EV_P_ ev_periodic *w) EV_NOEXCEPT;
775             EV_API_DECL void ev_periodic_again (EV_P_ ev_periodic *w) EV_NOEXCEPT;
776             #endif
777              
778             /* only supported in the default loop */
779             #if EV_SIGNAL_ENABLE
780             EV_API_DECL void ev_signal_start (EV_P_ ev_signal *w) EV_NOEXCEPT;
781             EV_API_DECL void ev_signal_stop (EV_P_ ev_signal *w) EV_NOEXCEPT;
782             #endif
783              
784             /* only supported in the default loop */
785             # if EV_CHILD_ENABLE
786             EV_API_DECL void ev_child_start (EV_P_ ev_child *w) EV_NOEXCEPT;
787             EV_API_DECL void ev_child_stop (EV_P_ ev_child *w) EV_NOEXCEPT;
788             # endif
789              
790             # if EV_STAT_ENABLE
791             EV_API_DECL void ev_stat_start (EV_P_ ev_stat *w) EV_NOEXCEPT;
792             EV_API_DECL void ev_stat_stop (EV_P_ ev_stat *w) EV_NOEXCEPT;
793             EV_API_DECL void ev_stat_stat (EV_P_ ev_stat *w) EV_NOEXCEPT;
794             # endif
795              
796             # if EV_IDLE_ENABLE
797             EV_API_DECL void ev_idle_start (EV_P_ ev_idle *w) EV_NOEXCEPT;
798             EV_API_DECL void ev_idle_stop (EV_P_ ev_idle *w) EV_NOEXCEPT;
799             # endif
800              
801             #if EV_PREPARE_ENABLE
802             EV_API_DECL void ev_prepare_start (EV_P_ ev_prepare *w) EV_NOEXCEPT;
803             EV_API_DECL void ev_prepare_stop (EV_P_ ev_prepare *w) EV_NOEXCEPT;
804             #endif
805              
806             #if EV_CHECK_ENABLE
807             EV_API_DECL void ev_check_start (EV_P_ ev_check *w) EV_NOEXCEPT;
808             EV_API_DECL void ev_check_stop (EV_P_ ev_check *w) EV_NOEXCEPT;
809             #endif
810              
811             # if EV_FORK_ENABLE
812             EV_API_DECL void ev_fork_start (EV_P_ ev_fork *w) EV_NOEXCEPT;
813             EV_API_DECL void ev_fork_stop (EV_P_ ev_fork *w) EV_NOEXCEPT;
814             # endif
815              
816             # if EV_CLEANUP_ENABLE
817             EV_API_DECL void ev_cleanup_start (EV_P_ ev_cleanup *w) EV_NOEXCEPT;
818             EV_API_DECL void ev_cleanup_stop (EV_P_ ev_cleanup *w) EV_NOEXCEPT;
819             # endif
820              
821             # if EV_EMBED_ENABLE
822             /* only supported when loop to be embedded is in fact embeddable */
823             EV_API_DECL void ev_embed_start (EV_P_ ev_embed *w) EV_NOEXCEPT;
824             EV_API_DECL void ev_embed_stop (EV_P_ ev_embed *w) EV_NOEXCEPT;
825             EV_API_DECL void ev_embed_sweep (EV_P_ ev_embed *w) EV_NOEXCEPT;
826             # endif
827              
828             # if EV_ASYNC_ENABLE
829             EV_API_DECL void ev_async_start (EV_P_ ev_async *w) EV_NOEXCEPT;
830             EV_API_DECL void ev_async_stop (EV_P_ ev_async *w) EV_NOEXCEPT;
831             EV_API_DECL void ev_async_send (EV_P_ ev_async *w) EV_NOEXCEPT;
832             # endif
833              
834             #if EV_COMPAT3
835             #define EVLOOP_NONBLOCK EVRUN_NOWAIT
836             #define EVLOOP_ONESHOT EVRUN_ONCE
837             #define EVUNLOOP_CANCEL EVBREAK_CANCEL
838             #define EVUNLOOP_ONE EVBREAK_ONE
839             #define EVUNLOOP_ALL EVBREAK_ALL
840             #if EV_PROTOTYPES
841             EV_INLINE void ev_loop (EV_P_ int flags) { ev_run (EV_A_ flags); }
842             EV_INLINE void ev_unloop (EV_P_ int how ) { ev_break (EV_A_ how ); }
843             EV_INLINE void ev_default_destroy (void) { ev_loop_destroy (EV_DEFAULT); }
844             EV_INLINE void ev_default_fork (void) { ev_loop_fork (EV_DEFAULT); }
845             #if EV_FEATURE_API
846             EV_INLINE unsigned int ev_loop_count (EV_P) { return ev_iteration (EV_A); }
847             EV_INLINE unsigned int ev_loop_depth (EV_P) { return ev_depth (EV_A); }
848             EV_INLINE void ev_loop_verify (EV_P) { ev_verify (EV_A); }
849             #endif
850             #endif
851             #else
852             typedef struct ev_loop ev_loop;
853             #endif
854              
855             #endif
856              
857             EV_CPP(})
858              
859             #endif
860