1 /*
2  * libev native API header
3  *
4  * Copyright (c) 2007-2019 Marc Alexander Lehmann <libev@schmorp.de>
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 <string.h> /* for memmove */
160 
161 #ifndef EV_ATOMIC_T
162 # include <signal.h>
163 # define EV_ATOMIC_T sig_atomic_t volatile
164 #endif
165 
166 #if EV_STAT_ENABLE
167 # ifdef _WIN32
168 #  include <time.h>
169 #  include <sys/types.h>
170 # endif
171 # include <sys/stat.h>
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 27
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 #if EV_IDLE_ENABLE
396 /* invoked when the nothing else needs to be done, keeps the process from blocking */
397 /* revent EV_IDLE */
398 typedef struct ev_idle
399 {
400   EV_WATCHER (ev_idle)
401 } ev_idle;
402 #endif
403 
404 /* invoked for each run of the mainloop, just before the blocking call */
405 /* you can still change events in any way you like */
406 /* revent EV_PREPARE */
407 typedef struct ev_prepare
408 {
409   EV_WATCHER (ev_prepare)
410 } ev_prepare;
411 
412 /* invoked for each run of the mainloop, just after the blocking call */
413 /* revent EV_CHECK */
414 typedef struct ev_check
415 {
416   EV_WATCHER (ev_check)
417 } ev_check;
418 
419 #if EV_FORK_ENABLE
420 /* the callback gets invoked before check in the child process when a fork was detected */
421 /* revent EV_FORK */
422 typedef struct ev_fork
423 {
424   EV_WATCHER (ev_fork)
425 } ev_fork;
426 #endif
427 
428 #if EV_CLEANUP_ENABLE
429 /* is invoked just before the loop gets destroyed */
430 /* revent EV_CLEANUP */
431 typedef struct ev_cleanup
432 {
433   EV_WATCHER (ev_cleanup)
434 } ev_cleanup;
435 #endif
436 
437 #if EV_EMBED_ENABLE
438 /* used to embed an event loop inside another */
439 /* the callback gets invoked when the event loop has handled events, and can be 0 */
440 typedef struct ev_embed
441 {
442   EV_WATCHER (ev_embed)
443 
444   struct ev_loop *other; /* ro */
445   ev_io io;              /* private */
446   ev_prepare prepare;    /* private */
447   ev_check check;        /* unused */
448   ev_timer timer;        /* unused */
449   ev_periodic periodic;  /* unused */
450   ev_idle idle;          /* unused */
451   ev_fork fork;          /* private */
452 #if EV_CLEANUP_ENABLE
453   ev_cleanup cleanup;    /* unused */
454 #endif
455 } ev_embed;
456 #endif
457 
458 #if EV_ASYNC_ENABLE
459 /* invoked when somebody calls ev_async_send on the watcher */
460 /* revent EV_ASYNC */
461 typedef struct ev_async
462 {
463   EV_WATCHER (ev_async)
464 
465   EV_ATOMIC_T sent; /* private */
466 } ev_async;
467 
468 # define ev_async_pending(w) (+(w)->sent)
469 #endif
470 
471 /* the presence of this union forces similar struct layout */
472 union ev_any_watcher
473 {
474   struct ev_watcher w;
475   struct ev_watcher_list wl;
476 
477   struct ev_io io;
478   struct ev_timer timer;
479   struct ev_periodic periodic;
480   struct ev_signal signal;
481   struct ev_child child;
482 #if EV_STAT_ENABLE
483   struct ev_stat stat;
484 #endif
485 #if EV_IDLE_ENABLE
486   struct ev_idle idle;
487 #endif
488   struct ev_prepare prepare;
489   struct ev_check check;
490 #if EV_FORK_ENABLE
491   struct ev_fork fork;
492 #endif
493 #if EV_CLEANUP_ENABLE
494   struct ev_cleanup cleanup;
495 #endif
496 #if EV_EMBED_ENABLE
497   struct ev_embed embed;
498 #endif
499 #if EV_ASYNC_ENABLE
500   struct ev_async async;
501 #endif
502 };
503 
504 /* flag bits for ev_default_loop and ev_loop_new */
505 enum {
506   /* the default */
507   EVFLAG_AUTO      = 0x00000000U, /* not quite a mask */
508   /* flag bits */
509   EVFLAG_NOENV     = 0x01000000U, /* do NOT consult environment */
510   EVFLAG_FORKCHECK = 0x02000000U, /* check for a fork in each iteration */
511   /* debugging/feature disable */
512   EVFLAG_NOINOTIFY = 0x00100000U, /* do not attempt to use inotify */
513 #if EV_COMPAT3
514   EVFLAG_NOSIGFD   = 0, /* compatibility to pre-3.9 */
515 #endif
516   EVFLAG_SIGNALFD  = 0x00200000U, /* attempt to use signalfd */
517   EVFLAG_NOSIGMASK = 0x00400000U  /* avoid modifying the signal mask */
518 };
519 
520 /* method bits to be ored together */
521 enum {
522   EVBACKEND_SELECT   = 0x00000001U, /* available just about anywhere */
523   EVBACKEND_POLL     = 0x00000002U, /* !win, !aix, broken on osx */
524   EVBACKEND_EPOLL    = 0x00000004U, /* linux */
525   EVBACKEND_KQUEUE   = 0x00000008U, /* bsd, broken on osx */
526   EVBACKEND_DEVPOLL  = 0x00000010U, /* solaris 8 */ /* NYI */
527   EVBACKEND_PORT     = 0x00000020U, /* solaris 10 */
528   EVBACKEND_LINUXAIO = 0x00000040U, /* linuix AIO, 4.19+ */
529   EVBACKEND_IOURING  = 0x00000080U, /* linux io_uring, 5.1+ */
530   EVBACKEND_ALL      = 0x000000FFU, /* all known backends */
531   EVBACKEND_MASK     = 0x0000FFFFU  /* all future backends */
532 };
533 
534 #if EV_PROTOTYPES
535 EV_API_DECL int ev_version_major (void) EV_NOEXCEPT;
536 EV_API_DECL int ev_version_minor (void) EV_NOEXCEPT;
537 
538 EV_API_DECL unsigned int ev_supported_backends (void) EV_NOEXCEPT;
539 EV_API_DECL unsigned int ev_recommended_backends (void) EV_NOEXCEPT;
540 EV_API_DECL unsigned int ev_embeddable_backends (void) EV_NOEXCEPT;
541 
542 EV_API_DECL ev_tstamp ev_time (void) EV_NOEXCEPT;
543 EV_API_DECL void ev_sleep (ev_tstamp delay) EV_NOEXCEPT; /* sleep for a while */
544 
545 /* Sets the allocation function to use, works like realloc.
546  * It is used to allocate and free memory.
547  * If it returns zero when memory needs to be allocated, the library might abort
548  * or take some potentially destructive action.
549  * The default is your system realloc function.
550  */
551 EV_API_DECL void ev_set_allocator (void *(*cb)(void *ptr, long size) EV_NOEXCEPT) EV_NOEXCEPT;
552 
553 /* set the callback function to call on a
554  * retryable syscall error
555  * (such as failed select, poll, epoll_wait)
556  */
557 EV_API_DECL void ev_set_syserr_cb (void (*cb)(const char *msg) EV_NOEXCEPT) EV_NOEXCEPT;
558 
559 #if EV_MULTIPLICITY
560 
561 /* the default loop is the only one that handles signals and child watchers */
562 /* you can call this as often as you like */
563 EV_API_DECL struct ev_loop *ev_default_loop (unsigned int flags EV_CPP (= 0)) EV_NOEXCEPT;
564 
565 #ifdef EV_API_STATIC
566 EV_API_DECL struct ev_loop *ev_default_loop_ptr;
567 #endif
568 
569 EV_INLINE struct ev_loop *
570 ev_default_loop_uc_ (void) EV_NOEXCEPT
571 {
572   extern struct ev_loop *ev_default_loop_ptr;
573 
574   return ev_default_loop_ptr;
575 }
576 
577 EV_INLINE int
578 ev_is_default_loop (EV_P) EV_NOEXCEPT
579 {
580   return EV_A == EV_DEFAULT_UC;
581 }
582 
583 /* create and destroy alternative loops that don't handle signals */
584 EV_API_DECL struct ev_loop *ev_loop_new (unsigned int flags EV_CPP (= 0)) EV_NOEXCEPT;
585 
586 EV_API_DECL ev_tstamp ev_now (EV_P) EV_NOEXCEPT; /* time w.r.t. timers and the eventloop, updated after each poll */
587 
588 #else
589 
590 EV_API_DECL int ev_default_loop (unsigned int flags EV_CPP (= 0)) EV_NOEXCEPT; /* returns true when successful */
591 
592 EV_API_DECL ev_tstamp ev_rt_now;
593 
594 EV_INLINE ev_tstamp
595 ev_now (void) EV_NOEXCEPT
596 {
597   return ev_rt_now;
598 }
599 
600 /* looks weird, but ev_is_default_loop (EV_A) still works if this exists */
601 EV_INLINE int
602 ev_is_default_loop (void) EV_NOEXCEPT
603 {
604   return 1;
605 }
606 
607 #endif /* multiplicity */
608 
609 /* destroy event loops, also works for the default loop */
610 EV_API_DECL void ev_loop_destroy (EV_P);
611 
612 /* this needs to be called after fork, to duplicate the loop */
613 /* when you want to re-use it in the child */
614 /* you can call it in either the parent or the child */
615 /* you can actually call it at any time, anywhere :) */
616 EV_API_DECL void ev_loop_fork (EV_P) EV_NOEXCEPT;
617 
618 EV_API_DECL unsigned int ev_backend (EV_P) EV_NOEXCEPT; /* backend in use by loop */
619 
620 EV_API_DECL void ev_now_update (EV_P) EV_NOEXCEPT; /* update event loop time */
621 
622 #if EV_WALK_ENABLE
623 /* walk (almost) all watchers in the loop of a given type, invoking the */
624 /* callback on every such watcher. The callback might stop the watcher, */
625 /* but do nothing else with the loop */
626 EV_API_DECL void ev_walk (EV_P_ int types, void (*cb)(EV_P_ int type, void *w)) EV_NOEXCEPT;
627 #endif
628 
629 #endif /* prototypes */
630 
631 /* ev_run flags values */
632 enum {
633   EVRUN_NOWAIT = 1, /* do not block/wait */
634   EVRUN_ONCE   = 2  /* block *once* only */
635 };
636 
637 /* ev_break how values */
638 enum {
639   EVBREAK_CANCEL = 0, /* undo unloop */
640   EVBREAK_ONE    = 1, /* unloop once */
641   EVBREAK_ALL    = 2  /* unloop all loops */
642 };
643 
644 #if EV_PROTOTYPES
645 EV_API_DECL int  ev_run (EV_P_ int flags EV_CPP (= 0));
646 EV_API_DECL void ev_break (EV_P_ int how EV_CPP (= EVBREAK_ONE)) EV_NOEXCEPT; /* break out of the loop */
647 
648 /*
649  * ref/unref can be used to add or remove a refcount on the mainloop. every watcher
650  * keeps one reference. if you have a long-running watcher you never unregister that
651  * should not keep ev_loop from running, unref() after starting, and ref() before stopping.
652  */
653 EV_API_DECL void ev_ref   (EV_P) EV_NOEXCEPT;
654 EV_API_DECL void ev_unref (EV_P) EV_NOEXCEPT;
655 
656 /*
657  * convenience function, wait for a single event, without registering an event watcher
658  * if timeout is < 0, do wait indefinitely
659  */
660 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;
661 
662 # if EV_FEATURE_API
663 EV_API_DECL unsigned int ev_iteration (EV_P) EV_NOEXCEPT; /* number of loop iterations */
664 EV_API_DECL unsigned int ev_depth     (EV_P) EV_NOEXCEPT; /* #ev_loop enters - #ev_loop leaves */
665 EV_API_DECL void         ev_verify    (EV_P) EV_NOEXCEPT; /* abort if loop data corrupted */
666 
667 EV_API_DECL void ev_set_io_collect_interval (EV_P_ ev_tstamp interval) EV_NOEXCEPT; /* sleep at least this time, default 0 */
668 EV_API_DECL void ev_set_timeout_collect_interval (EV_P_ ev_tstamp interval) EV_NOEXCEPT; /* sleep at least this time, default 0 */
669 
670 /* advanced stuff for threading etc. support, see docs */
671 EV_API_DECL void ev_set_userdata (EV_P_ void *data) EV_NOEXCEPT;
672 EV_API_DECL void *ev_userdata (EV_P) EV_NOEXCEPT;
673 typedef void (*ev_loop_callback)(EV_P);
674 EV_API_DECL void ev_set_invoke_pending_cb (EV_P_ ev_loop_callback invoke_pending_cb) EV_NOEXCEPT;
675 /* C++ doesn't allow the use of the ev_loop_callback typedef here, so we need to spell it out */
676 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;
677 
678 EV_API_DECL unsigned int ev_pending_count (EV_P) EV_NOEXCEPT; /* number of pending events, if any */
679 EV_API_DECL void ev_invoke_pending (EV_P); /* invoke all pending watchers */
680 
681 /*
682  * stop/start the timer handling.
683  */
684 EV_API_DECL void ev_suspend (EV_P) EV_NOEXCEPT;
685 EV_API_DECL void ev_resume  (EV_P) EV_NOEXCEPT;
686 #endif
687 
688 #endif
689 
690 /* these may evaluate ev multiple times, and the other arguments at most once */
691 /* either use ev_init + ev_TYPE_set, or the ev_TYPE_init macro, below, to first initialise a watcher */
692 #define ev_init(ev,cb_) do {			\
693   ((ev_watcher *)(void *)(ev))->active  =	\
694   ((ev_watcher *)(void *)(ev))->pending = 0;	\
695   ev_set_priority ((ev), 0);			\
696   ev_set_cb ((ev), cb_);			\
697 } while (0)
698 
699 #define ev_io_set(ev,fd_,events_)            do { (ev)->fd = (fd_); (ev)->events = (events_) | EV__IOFDSET; } while (0)
700 #define ev_timer_set(ev,after_,repeat_)      do { ((ev_watcher_time *)(ev))->at = (after_); (ev)->repeat = (repeat_); } while (0)
701 #define ev_periodic_set(ev,ofs_,ival_,rcb_)  do { (ev)->offset = (ofs_); (ev)->interval = (ival_); (ev)->reschedule_cb = (rcb_); } while (0)
702 #define ev_signal_set(ev,signum_)            do { (ev)->signum = (signum_); } while (0)
703 #define ev_child_set(ev,pid_,trace_)         do { (ev)->pid = (pid_); (ev)->flags = !!(trace_); } while (0)
704 #define ev_stat_set(ev,path_,interval_)      do { (ev)->path = (path_); (ev)->interval = (interval_); (ev)->wd = -2; } while (0)
705 #define ev_idle_set(ev)                      /* nop, yes, this is a serious in-joke */
706 #define ev_prepare_set(ev)                   /* nop, yes, this is a serious in-joke */
707 #define ev_check_set(ev)                     /* nop, yes, this is a serious in-joke */
708 #define ev_embed_set(ev,other_)              do { (ev)->other = (other_); } while (0)
709 #define ev_fork_set(ev)                      /* nop, yes, this is a serious in-joke */
710 #define ev_cleanup_set(ev)                   /* nop, yes, this is a serious in-joke */
711 #define ev_async_set(ev)                     /* nop, yes, this is a serious in-joke */
712 
713 #define ev_io_init(ev,cb,fd,events)          do { ev_init ((ev), (cb)); ev_io_set ((ev),(fd),(events)); } while (0)
714 #define ev_timer_init(ev,cb,after,repeat)    do { ev_init ((ev), (cb)); ev_timer_set ((ev),(after),(repeat)); } while (0)
715 #define ev_periodic_init(ev,cb,ofs,ival,rcb) do { ev_init ((ev), (cb)); ev_periodic_set ((ev),(ofs),(ival),(rcb)); } while (0)
716 #define ev_signal_init(ev,cb,signum)         do { ev_init ((ev), (cb)); ev_signal_set ((ev), (signum)); } while (0)
717 #define ev_child_init(ev,cb,pid,trace)       do { ev_init ((ev), (cb)); ev_child_set ((ev),(pid),(trace)); } while (0)
718 #define ev_stat_init(ev,cb,path,interval)    do { ev_init ((ev), (cb)); ev_stat_set ((ev),(path),(interval)); } while (0)
719 #define ev_idle_init(ev,cb)                  do { ev_init ((ev), (cb)); ev_idle_set ((ev)); } while (0)
720 #define ev_prepare_init(ev,cb)               do { ev_init ((ev), (cb)); ev_prepare_set ((ev)); } while (0)
721 #define ev_check_init(ev,cb)                 do { ev_init ((ev), (cb)); ev_check_set ((ev)); } while (0)
722 #define ev_embed_init(ev,cb,other)           do { ev_init ((ev), (cb)); ev_embed_set ((ev),(other)); } while (0)
723 #define ev_fork_init(ev,cb)                  do { ev_init ((ev), (cb)); ev_fork_set ((ev)); } while (0)
724 #define ev_cleanup_init(ev,cb)               do { ev_init ((ev), (cb)); ev_cleanup_set ((ev)); } while (0)
725 #define ev_async_init(ev,cb)                 do { ev_init ((ev), (cb)); ev_async_set ((ev)); } while (0)
726 
727 #define ev_is_pending(ev)                    (0 + ((ev_watcher *)(void *)(ev))->pending) /* ro, true when watcher is waiting for callback invocation */
728 #define ev_is_active(ev)                     (0 + ((ev_watcher *)(void *)(ev))->active) /* ro, true when the watcher has been started */
729 
730 #define ev_cb_(ev)                           (ev)->cb /* rw */
731 #define ev_cb(ev)                            (memmove (&ev_cb_ (ev), &((ev_watcher *)(ev))->cb, sizeof (ev_cb_ (ev))), (ev)->cb)
732 
733 #if EV_MINPRI == EV_MAXPRI
734 # define ev_priority(ev)                     ((ev), EV_MINPRI)
735 # define ev_set_priority(ev,pri)             ((ev), (pri))
736 #else
737 # define ev_priority(ev)                     (+(((ev_watcher *)(void *)(ev))->priority))
738 # define ev_set_priority(ev,pri)             (   (ev_watcher *)(void *)(ev))->priority = (pri)
739 #endif
740 
741 #define ev_periodic_at(ev)                   (+((ev_watcher_time *)(ev))->at)
742 
743 #ifndef ev_set_cb
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 
861