1 /*
2  * libev simple C++ wrapper classes
3  *
4  * Copyright (c) 2007,2008,2010,2018,2020 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 EVPP_H__
41 #define EVPP_H__
42 
43 #ifdef EV_H
44 # include EV_H
45 #else
46 # include "ev.h"
47 #endif
48 
49 #ifndef EV_USE_STDEXCEPT
50 # define EV_USE_STDEXCEPT 1
51 #endif
52 
53 #if EV_USE_STDEXCEPT
54 # include <stdexcept>
55 #endif
56 
57 namespace ev {
58 
59   typedef ev_tstamp tstamp;
60 
61   enum {
62     UNDEF    = EV_UNDEF,
63     NONE     = EV_NONE,
64     READ     = EV_READ,
65     WRITE    = EV_WRITE,
66 #if EV_COMPAT3
67     TIMEOUT  = EV_TIMEOUT,
68 #endif
69     TIMER    = EV_TIMER,
70     PERIODIC = EV_PERIODIC,
71     SIGNAL   = EV_SIGNAL,
72     CHILD    = EV_CHILD,
73     STAT     = EV_STAT,
74     IDLE     = EV_IDLE,
75     CHECK    = EV_CHECK,
76     PREPARE  = EV_PREPARE,
77     FORK     = EV_FORK,
78     ASYNC    = EV_ASYNC,
79     EMBED    = EV_EMBED,
80 #   undef ERROR // some systems stupidly #define ERROR
81     ERROR    = EV_ERROR
82   };
83 
84   enum
85   {
86     AUTO      = EVFLAG_AUTO,
87     NOENV     = EVFLAG_NOENV,
88     FORKCHECK = EVFLAG_FORKCHECK,
89 
90     SELECT    = EVBACKEND_SELECT,
91     POLL      = EVBACKEND_POLL,
92     EPOLL     = EVBACKEND_EPOLL,
93     KQUEUE    = EVBACKEND_KQUEUE,
94     DEVPOLL   = EVBACKEND_DEVPOLL,
95     PORT      = EVBACKEND_PORT
96   };
97 
98   enum
99   {
100 #if EV_COMPAT3
101     NONBLOCK = EVLOOP_NONBLOCK,
102     ONESHOT  = EVLOOP_ONESHOT,
103 #endif
104     NOWAIT   = EVRUN_NOWAIT,
105     ONCE     = EVRUN_ONCE
106   };
107 
108   enum how_t
109   {
110     ONE = EVBREAK_ONE,
111     ALL = EVBREAK_ALL
112   };
113 
114   struct bad_loop
115 #if EV_USE_STDEXCEPT
116   : std::exception
117 #endif
118   {
119 #if EV_USE_STDEXCEPT
whatbad_loop120     const char *what () const EV_NOEXCEPT
121     {
122       return "libev event loop cannot be initialized, bad value of LIBEV_FLAGS?";
123     }
124 #endif
125   };
126 
127 #ifdef EV_AX
128 #  undef EV_AX
129 #endif
130 
131 #ifdef EV_AX_
132 #  undef EV_AX_
133 #endif
134 
135 #if EV_MULTIPLICITY
136 #  define EV_AX  raw_loop
137 #  define EV_AX_ raw_loop,
138 #else
139 #  define EV_AX
140 #  define EV_AX_
141 #endif
142 
143   struct loop_ref
144   {
loop_refloop_ref145     loop_ref (EV_P) EV_NOEXCEPT
146 #if EV_MULTIPLICITY
147     : EV_AX (EV_A)
148 #endif
149     {
150     }
151 
152     bool operator == (const loop_ref &other) const EV_NOEXCEPT
153     {
154 #if EV_MULTIPLICITY
155       return EV_AX == other.EV_AX;
156 #else
157       return true;
158 #endif
159     }
160 
161     bool operator != (const loop_ref &other) const EV_NOEXCEPT
162     {
163 #if EV_MULTIPLICITY
164       return ! (*this == other);
165 #else
166       return false;
167 #endif
168     }
169 
170 #if EV_MULTIPLICITY
171     bool operator == (const EV_P) const EV_NOEXCEPT
172     {
173       return this->EV_AX == EV_A;
174     }
175 
176     bool operator != (const EV_P) const EV_NOEXCEPT
177     {
178       return ! (*this == EV_A);
179     }
180 
181     operator struct ev_loop * () const EV_NOEXCEPT
182     {
183       return EV_AX;
184     }
185 
186     operator const struct ev_loop * () const EV_NOEXCEPT
187     {
188       return EV_AX;
189     }
190 
is_defaultloop_ref191     bool is_default () const EV_NOEXCEPT
192     {
193       return EV_AX == ev_default_loop (0);
194     }
195 #endif
196 
197 #if EV_COMPAT3
198     void loop (int flags = 0)
199     {
200       ev_run (EV_AX_ flags);
201     }
202 
203     void unloop (how_t how = ONE) EV_NOEXCEPT
204     {
205       ev_break (EV_AX_ how);
206     }
207 #endif
208 
209     void run (int flags = 0)
210     {
211       ev_run (EV_AX_ flags);
212     }
213 
214     void break_loop (how_t how = ONE) EV_NOEXCEPT
215     {
216       ev_break (EV_AX_ how);
217     }
218 
post_forkloop_ref219     void post_fork () EV_NOEXCEPT
220     {
221       ev_loop_fork (EV_AX);
222     }
223 
backendloop_ref224     unsigned int backend () const EV_NOEXCEPT
225     {
226       return ev_backend (EV_AX);
227     }
228 
nowloop_ref229     tstamp now () const EV_NOEXCEPT
230     {
231       return ev_now (EV_AX);
232     }
233 
refloop_ref234     void ref () EV_NOEXCEPT
235     {
236       ev_ref (EV_AX);
237     }
238 
unrefloop_ref239     void unref () EV_NOEXCEPT
240     {
241       ev_unref (EV_AX);
242     }
243 
244 #if EV_FEATURE_API
iterationloop_ref245     unsigned int iteration () const EV_NOEXCEPT
246     {
247       return ev_iteration (EV_AX);
248     }
249 
depthloop_ref250     unsigned int depth () const EV_NOEXCEPT
251     {
252       return ev_depth (EV_AX);
253     }
254 
set_io_collect_intervalloop_ref255     void set_io_collect_interval (tstamp interval) EV_NOEXCEPT
256     {
257       ev_set_io_collect_interval (EV_AX_ interval);
258     }
259 
set_timeout_collect_intervalloop_ref260     void set_timeout_collect_interval (tstamp interval) EV_NOEXCEPT
261     {
262       ev_set_timeout_collect_interval (EV_AX_ interval);
263     }
264 #endif
265 
266     // function callback
267     void once (int fd, int events, tstamp timeout, void (*cb)(int, void *), void *arg = 0) EV_NOEXCEPT
268     {
269       ev_once (EV_AX_ fd, events, timeout, cb, arg);
270     }
271 
272     // method callback
273     template<class K, void (K::*method)(int)>
onceloop_ref274     void once (int fd, int events, tstamp timeout, K *object) EV_NOEXCEPT
275     {
276       once (fd, events, timeout, method_thunk<K, method>, object);
277     }
278 
279     // default method == operator ()
280     template<class K>
onceloop_ref281     void once (int fd, int events, tstamp timeout, K *object) EV_NOEXCEPT
282     {
283       once (fd, events, timeout, method_thunk<K, &K::operator ()>, object);
284     }
285 
286     template<class K, void (K::*method)(int)>
method_thunkloop_ref287     static void method_thunk (int revents, void *arg)
288     {
289       (static_cast<K *>(arg)->*method)
290         (revents);
291     }
292 
293     // no-argument method callback
294     template<class K, void (K::*method)()>
onceloop_ref295     void once (int fd, int events, tstamp timeout, K *object) EV_NOEXCEPT
296     {
297       once (fd, events, timeout, method_noargs_thunk<K, method>, object);
298     }
299 
300     template<class K, void (K::*method)()>
method_noargs_thunkloop_ref301     static void method_noargs_thunk (int revents, void *arg)
302     {
303       (static_cast<K *>(arg)->*method)
304         ();
305     }
306 
307     // simpler function callback
308     template<void (*cb)(int)>
onceloop_ref309     void once (int fd, int events, tstamp timeout) EV_NOEXCEPT
310     {
311       once (fd, events, timeout, simpler_func_thunk<cb>);
312     }
313 
314     template<void (*cb)(int)>
simpler_func_thunkloop_ref315     static void simpler_func_thunk (int revents, void *arg)
316     {
317       (*cb)
318         (revents);
319     }
320 
321     // simplest function callback
322     template<void (*cb)()>
onceloop_ref323     void once (int fd, int events, tstamp timeout) EV_NOEXCEPT
324     {
325       once (fd, events, timeout, simplest_func_thunk<cb>);
326     }
327 
328     template<void (*cb)()>
simplest_func_thunkloop_ref329     static void simplest_func_thunk (int revents, void *arg)
330     {
331       (*cb)
332         ();
333     }
334 
feed_fd_eventloop_ref335     void feed_fd_event (int fd, int revents) EV_NOEXCEPT
336     {
337       ev_feed_fd_event (EV_AX_ fd, revents);
338     }
339 
feed_signal_eventloop_ref340     void feed_signal_event (int signum) EV_NOEXCEPT
341     {
342       ev_feed_signal_event (EV_AX_ signum);
343     }
344 
345 #if EV_MULTIPLICITY
346     struct ev_loop* EV_AX;
347 #endif
348 
349   };
350 
351 #if EV_MULTIPLICITY
352   struct dynamic_loop : loop_ref
353   {
354 
355     dynamic_loop (unsigned int flags = AUTO)
loop_refdynamic_loop356     : loop_ref (ev_loop_new (flags))
357     {
358       if (!EV_AX)
359         throw bad_loop ();
360     }
361 
~dynamic_loopdynamic_loop362     ~dynamic_loop () EV_NOEXCEPT
363     {
364       ev_loop_destroy (EV_AX);
365       EV_AX = 0;
366     }
367 
368   private:
369 
370     dynamic_loop (const dynamic_loop &);
371 
372     dynamic_loop & operator= (const dynamic_loop &);
373 
374   };
375 #endif
376 
377   struct default_loop : loop_ref
378   {
379     default_loop (unsigned int flags = AUTO)
380 #if EV_MULTIPLICITY
loop_refdefault_loop381     : loop_ref (ev_default_loop (flags))
382 #endif
383     {
384       if (
385 #if EV_MULTIPLICITY
386           !EV_AX
387 #else
388           !ev_default_loop (flags)
389 #endif
390       )
391         throw bad_loop ();
392     }
393 
394   private:
395     default_loop (const default_loop &);
396     default_loop &operator = (const default_loop &);
397   };
398 
get_default_loop()399   inline loop_ref get_default_loop () EV_NOEXCEPT
400   {
401 #if EV_MULTIPLICITY
402     return ev_default_loop (0);
403 #else
404     return loop_ref ();
405 #endif
406   }
407 
408 #undef EV_AX
409 #undef EV_AX_
410 
411 #undef EV_PX
412 #undef EV_PX_
413 #if EV_MULTIPLICITY
414 #  define EV_PX  loop_ref EV_A
415 #  define EV_PX_ loop_ref EV_A_
416 #else
417 #  define EV_PX
418 #  define EV_PX_
419 #endif
420 
421   template<class ev_watcher, class watcher>
422   struct base : ev_watcher
423   {
424     // scoped pause/unpause of a watcher
425     struct freeze_guard
426     {
427       watcher &w;
428       bool active;
429 
freeze_guardbase::freeze_guard430       freeze_guard (watcher *self) EV_NOEXCEPT
431       : w (*self), active (w.is_active ())
432       {
433         if (active) w.stop ();
434       }
435 
~freeze_guardbase::freeze_guard436       ~freeze_guard ()
437       {
438         if (active) w.start ();
439       }
440     };
441 
442     #if EV_MULTIPLICITY
443       EV_PX;
444 
445       // loop set
setbase446       void set (EV_P) EV_NOEXCEPT
447       {
448         this->EV_A = EV_A;
449       }
450     #endif
451 
basebase452     base (EV_PX) EV_NOEXCEPT
453     #if EV_MULTIPLICITY
454       : EV_A (EV_A)
455     #endif
456     {
457       ev_init (this, 0);
458     }
459 
set_base460     void set_ (const void *data, void (*cb)(EV_P_ ev_watcher *w, int revents)) EV_NOEXCEPT
461     {
462       this->data = (void *)data;
463       ev_set_cb (static_cast<ev_watcher *>(this), cb);
464     }
465 
466     // function callback
467     template<void (*function)(watcher &w, int)>
468     void set (void *data = 0) EV_NOEXCEPT
469     {
470       set_ (data, function_thunk<function>);
471     }
472 
473     template<void (*function)(watcher &w, int)>
function_thunkbase474     static void function_thunk (EV_P_ ev_watcher *w, int revents)
475     {
476       function
477         (*static_cast<watcher *>(w), revents);
478     }
479 
480     // method callback
481     template<class K, void (K::*method)(watcher &w, int)>
setbase482     void set (K *object) EV_NOEXCEPT
483     {
484       set_ (object, method_thunk<K, method>);
485     }
486 
487     // default method == operator ()
488     template<class K>
setbase489     void set (K *object) EV_NOEXCEPT
490     {
491       set_ (object, method_thunk<K, &K::operator ()>);
492     }
493 
494     template<class K, void (K::*method)(watcher &w, int)>
method_thunkbase495     static void method_thunk (EV_P_ ev_watcher *w, int revents)
496     {
497       (static_cast<K *>(w->data)->*method)
498         (*static_cast<watcher *>(w), revents);
499     }
500 
501     // no-argument callback
502     template<class K, void (K::*method)()>
setbase503     void set (K *object) EV_NOEXCEPT
504     {
505       set_ (object, method_noargs_thunk<K, method>);
506     }
507 
508     template<class K, void (K::*method)()>
method_noargs_thunkbase509     static void method_noargs_thunk (EV_P_ ev_watcher *w, int revents)
510     {
511       (static_cast<K *>(w->data)->*method)
512         ();
513     }
514 
operatorbase515     void operator ()(int events = EV_UNDEF)
516     {
517       return
518         ev_cb (static_cast<ev_watcher *>(this))
519           (static_cast<ev_watcher *>(this), events);
520     }
521 
is_activebase522     bool is_active () const EV_NOEXCEPT
523     {
524       return ev_is_active (static_cast<const ev_watcher *>(this));
525     }
526 
is_pendingbase527     bool is_pending () const EV_NOEXCEPT
528     {
529       return ev_is_pending (static_cast<const ev_watcher *>(this));
530     }
531 
feed_eventbase532     void feed_event (int revents) EV_NOEXCEPT
533     {
534       ev_feed_event (EV_A_ static_cast<ev_watcher *>(this), revents);
535     }
536   };
537 
now(EV_P)538   inline tstamp now (EV_P) EV_NOEXCEPT
539   {
540     return ev_now (EV_A);
541   }
542 
delay(tstamp interval)543   inline void delay (tstamp interval) EV_NOEXCEPT
544   {
545     ev_sleep (interval);
546   }
547 
version_major()548   inline int version_major () EV_NOEXCEPT
549   {
550     return ev_version_major ();
551   }
552 
version_minor()553   inline int version_minor () EV_NOEXCEPT
554   {
555     return ev_version_minor ();
556   }
557 
supported_backends()558   inline unsigned int supported_backends () EV_NOEXCEPT
559   {
560     return ev_supported_backends ();
561   }
562 
recommended_backends()563   inline unsigned int recommended_backends () EV_NOEXCEPT
564   {
565     return ev_recommended_backends ();
566   }
567 
embeddable_backends()568   inline unsigned int embeddable_backends () EV_NOEXCEPT
569   {
570     return ev_embeddable_backends ();
571   }
572 
set_allocator(void * (* cb)(void * ptr,long size)EV_NOEXCEPT)573   inline void set_allocator (void *(*cb)(void *ptr, long size) EV_NOEXCEPT) EV_NOEXCEPT
574   {
575     ev_set_allocator (cb);
576   }
577 
set_syserr_cb(void (* cb)(const char * msg)EV_NOEXCEPT)578   inline void set_syserr_cb (void (*cb)(const char *msg) EV_NOEXCEPT) EV_NOEXCEPT
579   {
580     ev_set_syserr_cb (cb);
581   }
582 
583   #if EV_MULTIPLICITY
584     #define EV_CONSTRUCT(cppstem,cstem)	                                                \
585       (EV_PX = get_default_loop ()) EV_NOEXCEPT                                         \
586         : base<ev_ ## cstem, cppstem> (EV_A)                                            \
587       {                                                                                 \
588       }
589   #else
590     #define EV_CONSTRUCT(cppstem,cstem)                                                 \
591       () EV_NOEXCEPT                                                                    \
592       {                                                                                 \
593       }
594   #endif
595 
596   /* using a template here would require quite a few more lines,
597    * so a macro solution was chosen */
598   #define EV_BEGIN_WATCHER(cppstem,cstem)	                                        \
599                                                                                         \
600   struct cppstem : base<ev_ ## cstem, cppstem>                                          \
601   {                                                                                     \
602     void start () EV_NOEXCEPT                                                           \
603     {                                                                                   \
604       ev_ ## cstem ## _start (EV_A_ static_cast<ev_ ## cstem *>(this));                 \
605     }                                                                                   \
606                                                                                         \
607     void stop () EV_NOEXCEPT                                                            \
608     {                                                                                   \
609       ev_ ## cstem ## _stop (EV_A_ static_cast<ev_ ## cstem *>(this));                  \
610     }                                                                                   \
611                                                                                         \
612     cppstem EV_CONSTRUCT(cppstem,cstem)                                                 \
613                                                                                         \
614     ~cppstem () EV_NOEXCEPT                                                             \
615     {                                                                                   \
616       stop ();                                                                          \
617     }                                                                                   \
618                                                                                         \
619     using base<ev_ ## cstem, cppstem>::set;                                             \
620                                                                                         \
621   private:                                                                              \
622                                                                                         \
623     cppstem (const cppstem &o);                                                         \
624                                                                                         \
625     cppstem &operator =(const cppstem &o);                                              \
626                                                                                         \
627   public:
628 
629   #define EV_END_WATCHER(cppstem,cstem)	                                                \
630   };
631 
EV_BEGIN_WATCHER(io,io)632   EV_BEGIN_WATCHER (io, io)
633     void set (int fd, int events) EV_NOEXCEPT
634     {
635       freeze_guard freeze (this);
636       ev_io_set (static_cast<ev_io *>(this), fd, events);
637     }
638 
set(int events)639     void set (int events) EV_NOEXCEPT
640     {
641       freeze_guard freeze (this);
642       ev_io_modify (static_cast<ev_io *>(this), events);
643     }
644 
start(int fd,int events)645     void start (int fd, int events) EV_NOEXCEPT
646     {
647       set (fd, events);
648       start ();
649     }
EV_END_WATCHER(io,io)650   EV_END_WATCHER (io, io)
651 
652   EV_BEGIN_WATCHER (timer, timer)
653     void set (ev_tstamp after, ev_tstamp repeat = 0.) EV_NOEXCEPT
654     {
655       freeze_guard freeze (this);
656       ev_timer_set (static_cast<ev_timer *>(this), after, repeat);
657     }
658 
659     void start (ev_tstamp after, ev_tstamp repeat = 0.) EV_NOEXCEPT
660     {
661       set (after, repeat);
662       start ();
663     }
664 
again()665     void again () EV_NOEXCEPT
666     {
667       ev_timer_again (EV_A_ static_cast<ev_timer *>(this));
668     }
669 
remaining()670     ev_tstamp remaining ()
671     {
672       return ev_timer_remaining (EV_A_ static_cast<ev_timer *>(this));
673     }
EV_END_WATCHER(timer,timer)674   EV_END_WATCHER (timer, timer)
675 
676   #if EV_PERIODIC_ENABLE
677   EV_BEGIN_WATCHER (periodic, periodic)
678     void set (ev_tstamp at, ev_tstamp interval = 0.) EV_NOEXCEPT
679     {
680       freeze_guard freeze (this);
681       ev_periodic_set (static_cast<ev_periodic *>(this), at, interval, 0);
682     }
683 
684     void start (ev_tstamp at, ev_tstamp interval = 0.) EV_NOEXCEPT
685     {
686       set (at, interval);
687       start ();
688     }
689 
again()690     void again () EV_NOEXCEPT
691     {
692       ev_periodic_again (EV_A_ static_cast<ev_periodic *>(this));
693     }
EV_END_WATCHER(periodic,periodic)694   EV_END_WATCHER (periodic, periodic)
695   #endif
696 
697   #if EV_SIGNAL_ENABLE
698   EV_BEGIN_WATCHER (sig, signal)
699     void set (int signum) EV_NOEXCEPT
700     {
701       freeze_guard freeze (this);
702       ev_signal_set (static_cast<ev_signal *>(this), signum);
703     }
704 
start(int signum)705     void start (int signum) EV_NOEXCEPT
706     {
707       set (signum);
708       start ();
709     }
EV_END_WATCHER(sig,signal)710   EV_END_WATCHER (sig, signal)
711   #endif
712 
713   #if EV_CHILD_ENABLE
714   EV_BEGIN_WATCHER (child, child)
715     void set (int pid, int trace = 0) EV_NOEXCEPT
716     {
717       freeze_guard freeze (this);
718       ev_child_set (static_cast<ev_child *>(this), pid, trace);
719     }
720 
721     void start (int pid, int trace = 0) EV_NOEXCEPT
722     {
723       set (pid, trace);
724       start ();
725     }
EV_END_WATCHER(child,child)726   EV_END_WATCHER (child, child)
727   #endif
728 
729   #if EV_STAT_ENABLE
730   EV_BEGIN_WATCHER (stat, stat)
731     void set (const char *path, ev_tstamp interval = 0.) EV_NOEXCEPT
732     {
733       freeze_guard freeze (this);
734       ev_stat_set (static_cast<ev_stat *>(this), path, interval);
735     }
736 
737     void start (const char *path, ev_tstamp interval = 0.) EV_NOEXCEPT
738     {
739       stop ();
740       set (path, interval);
741       start ();
742     }
743 
update()744     void update () EV_NOEXCEPT
745     {
746       ev_stat_stat (EV_A_ static_cast<ev_stat *>(this));
747     }
EV_END_WATCHER(stat,stat)748   EV_END_WATCHER (stat, stat)
749   #endif
750 
751   #if EV_IDLE_ENABLE
752   EV_BEGIN_WATCHER (idle, idle)
753     void set () EV_NOEXCEPT { }
EV_END_WATCHER(idle,idle)754   EV_END_WATCHER (idle, idle)
755   #endif
756 
757   #if EV_PREPARE_ENABLE
758   EV_BEGIN_WATCHER (prepare, prepare)
759     void set () EV_NOEXCEPT { }
EV_END_WATCHER(prepare,prepare)760   EV_END_WATCHER (prepare, prepare)
761   #endif
762 
763   #if EV_CHECK_ENABLE
764   EV_BEGIN_WATCHER (check, check)
765     void set () EV_NOEXCEPT { }
EV_END_WATCHER(check,check)766   EV_END_WATCHER (check, check)
767   #endif
768 
769   #if EV_EMBED_ENABLE
770   EV_BEGIN_WATCHER (embed, embed)
771     void set_embed (struct ev_loop *embedded_loop) EV_NOEXCEPT
772     {
773       freeze_guard freeze (this);
774       ev_embed_set (static_cast<ev_embed *>(this), embedded_loop);
775     }
776 
start(struct ev_loop * embedded_loop)777     void start (struct ev_loop *embedded_loop) EV_NOEXCEPT
778     {
779       set (embedded_loop);
780       start ();
781     }
782 
sweep()783     void sweep ()
784     {
785       ev_embed_sweep (EV_A_ static_cast<ev_embed *>(this));
786     }
EV_END_WATCHER(embed,embed)787   EV_END_WATCHER (embed, embed)
788   #endif
789 
790   #if EV_FORK_ENABLE
791   EV_BEGIN_WATCHER (fork, fork)
792     void set () EV_NOEXCEPT { }
EV_END_WATCHER(fork,fork)793   EV_END_WATCHER (fork, fork)
794   #endif
795 
796   #if EV_ASYNC_ENABLE
797   EV_BEGIN_WATCHER (async, async)
798     void send () EV_NOEXCEPT
799     {
800       ev_async_send (EV_A_ static_cast<ev_async *>(this));
801     }
802 
async_pending()803     bool async_pending () EV_NOEXCEPT
804     {
805       return ev_async_pending (static_cast<ev_async *>(this));
806     }
807   EV_END_WATCHER (async, async)
808   #endif
809 
810   #undef EV_PX
811   #undef EV_PX_
812   #undef EV_CONSTRUCT
813   #undef EV_BEGIN_WATCHER
814   #undef EV_END_WATCHER
815 }
816 
817 #endif
818 
819