1 #include "EXTERN.h"
2 #include "perl.h"
3 #include "XSUB.h"
4 
5 /* fix perl api breakage */
6 #ifndef WIN32
7 # undef signal
8 # undef sigaction
9 #endif
10 
11 #include "schmorp.h"
12 
13 /* old API compatibility */
14 static int
sv_fileno(SV * fh)15 sv_fileno (SV *fh)
16 {
17   return s_fileno (fh, 0);
18 }
19 
20 #ifndef GvCV_set
21 # define GvCV_set(gv,cv) GvCV (gv) = cv
22 #endif
23 
24 #if EV_ENABLE_ASSERTIONS
25 # undef NDEBUG
26 #else
27 # define NDEBUG 1
28 #endif
29 
30 /* make sure we get a real assert, not perl's incompatible version */
31 #undef assert
32 #include <assert.h>
33 
34 #define EV_STANDALONE 1
35 #define EV_PROTOTYPES 1
36 #define EV_USE_NANOSLEEP EV_USE_MONOTONIC
37 #define EV_USE_FLOOR 1
38 #define EV_API_STATIC
39 #define EV_H "../libev/ev.h"
40 #define EV_CONFIG_H error
41 #include "EV/EVAPI.h"
42 
43 #define EV_SELECT_IS_WINSOCKET 0
44 #ifdef _WIN32
45 # define EV_SELECT_USE_FD_SET 0
46 # define NFDBITS PERL_NFDBITS
47 # define fd_mask Perl_fd_mask
48 #endif
49 /* due to bugs in OS X we have to use libev/ explicitly here */
50 #include "libev/ev.c"
51 
52 #if !defined _WIN32 && !defined __minix && !EV_NO_ATFORK
53 # include <pthread.h>
54 #endif
55 
56 #define e_loop(w)  INT2PTR (struct ev_loop *, SvIVX (((ev_watcher *)(w))->loop))
57 #define e_flags(w) ((ev_watcher *)(w))->e_flags
58 #define e_self(w)  ((ev_watcher *)(w))->self
59 #define e_fh(w)    ((ev_watcher *)(w))->fh
60 #define e_data(w)  ((ev_watcher *)(w))->data
61 
62 #define WFLAG_KEEPALIVE 1
63 #define WFLAG_UNREFED   2 /* has been unref'ed */
64 
65 #define UNREF(w)				\
66   if (!(e_flags (w) & (WFLAG_KEEPALIVE | WFLAG_UNREFED))	\
67       && ev_is_active (w))			\
68     {						\
69       ev_unref (e_loop (w));			\
70       e_flags (w) |= WFLAG_UNREFED;		\
71     }
72 
73 #define REF(w)					\
74   if (e_flags (w) & WFLAG_UNREFED)		\
75     {						\
76       e_flags (w) &= ~WFLAG_UNREFED;		\
77       ev_ref (e_loop (w));			\
78     }
79 
80 #define START(type,w)				\
81   do {						\
82     ev_ ## type ## _start (e_loop (w), w);	\
83     UNREF (w);					\
84   } while (0)
85 
86 #define STOP(type,w)				\
87   do {						\
88     REF (w);					\
89     ev_ ## type ## _stop (e_loop (w), w);	\
90   } while (0)
91 
92 #define PAUSE(type)				\
93   do {						\
94     int active = ev_is_active (w);		\
95     if (active) STOP  (type, w)
96 
97 #define RESUME(type)				\
98     if (active) START (type, w);		\
99   } while (0)
100 
101 
102 #define RESET(type,w,seta)			\
103   PAUSE (type);					\
104     ev_ ## type ## _set seta;                   \
105   RESUME (type)
106 
107 typedef int Signal;
108 
109 /* horrible... */
110 #define CHECK_SIGNAL_CAN_START(w)		\
111   do {						\
112     /* dive into the internals of libev to avoid aborting in libev */ \
113     if (signals [(w)->signum - 1].loop		\
114         && signals [(w)->signum - 1].loop != e_loop (w)) \
115       croak ("unable to start signal watcher, signal %d already registered in another loop", w->signum); \
116   } while (0)
117 
118 #define START_SIGNAL(w)				\
119   do {						\
120     CHECK_SIGNAL_CAN_START (w);			\
121     START (signal, w);				\
122   } while (0)					\
123 
124 #define RESET_SIGNAL(w,seta)			\
125   do {                                          \
126     int active = ev_is_active (w);              \
127     if (active) STOP (signal, w);               \
128     ev_ ## signal ## _set seta;                 \
129     if (active) START_SIGNAL (w);               \
130   } while (0)
131 
132 static SV *default_loop_sv;
133 
134 static struct EVAPI evapi;
135 
136 static HV
137   *stash_loop,
138   *stash_watcher,
139   *stash_io,
140   *stash_timer,
141   *stash_periodic,
142   *stash_signal,
143   *stash_child,
144   *stash_stat,
145   *stash_idle,
146   *stash_prepare,
147   *stash_check,
148   *stash_embed,
149   *stash_fork,
150   *stash_cleanup,
151   *stash_async;
152 
153 /////////////////////////////////////////////////////////////////////////////
154 // Event
155 
156 static void e_cb (EV_P_ ev_watcher *w, int revents);
157 
158 static void *
e_new(int size,SV * cb_sv,SV * loop)159 e_new (int size, SV *cb_sv, SV *loop)
160 {
161   SV *cv = cb_sv ? s_get_cv_croak (cb_sv) : 0;
162   ev_watcher *w;
163   SV *self = NEWSV (0, size);
164   SvPOK_only (self);
165   SvCUR_set (self, size);
166 
167   w = (ev_watcher *)SvPVX (self);
168 
169   ev_init (w, cv ? e_cb : 0);
170 
171   w->loop    = SvREFCNT_inc (SvRV (loop));
172   w->e_flags = WFLAG_KEEPALIVE;
173   w->data    = 0;
174   w->fh      = 0;
175   w->cb_sv   = SvREFCNT_inc (cv);
176   w->self    = self;
177 
178   return (void *)w;
179 }
180 
181 static void
e_destroy(void * w_)182 e_destroy (void *w_)
183 {
184   ev_watcher *w = (ev_watcher *)w_;
185 
186   SvREFCNT_dec (w->loop ); w->loop  = 0;
187   SvREFCNT_dec (w->fh   ); w->fh    = 0;
188   SvREFCNT_dec (w->cb_sv); w->cb_sv = 0;
189   SvREFCNT_dec (w->data ); w->data  = 0;
190 }
191 
192 static SV *
e_bless(ev_watcher * w,HV * stash)193 e_bless (ev_watcher *w, HV *stash)
194 {
195   SV *rv;
196 
197   if (SvOBJECT (w->self))
198     rv = newRV_inc (w->self);
199   else
200     {
201       rv = newRV_noinc (w->self);
202       sv_bless (rv, stash);
203       SvREADONLY_on (w->self);
204     }
205 
206   return rv;
207 }
208 
209 static SV *sv_self_cache, *sv_events_cache;
210 
211 static void
e_cb(EV_P_ ev_watcher * w,int revents)212 e_cb (EV_P_ ev_watcher *w, int revents)
213 {
214   dSP;
215   I32 mark = SP - PL_stack_base;
216   SV *sv_self, *sv_events;
217 
218   /* libev might have stopped the watcher */
219   if (ecb_expect_false (w->e_flags & WFLAG_UNREFED)
220       && !ev_is_active (w))
221     REF (w);
222 
223   if (ecb_expect_true (sv_self_cache))
224     {
225       sv_self = sv_self_cache; sv_self_cache = 0;
226       SvRV_set (sv_self, SvREFCNT_inc_NN (w->self));
227     }
228   else
229     {
230       sv_self = newRV_inc (w->self); /* e_self (w) MUST be blessed by now */
231       SvREADONLY_on (sv_self);
232     }
233 
234   if (ecb_expect_true (sv_events_cache))
235     {
236       sv_events = sv_events_cache; sv_events_cache = 0;
237       SvIV_set (sv_events, revents);
238       SvIOK_only (sv_events);
239     }
240   else
241     {
242       sv_events = newSViv (revents);
243       SvREADONLY_on (sv_events);
244     }
245 
246   PUSHMARK (SP);
247   EXTEND (SP, 2);
248   PUSHs (sv_self);
249   PUSHs (sv_events);
250 
251   PUTBACK;
252   call_sv (w->cb_sv, G_DISCARD | G_VOID | G_EVAL);
253 
254   if (ecb_expect_false (SvREFCNT (sv_self) != 1 || sv_self_cache))
255     SvREFCNT_dec (sv_self);
256   else
257     {
258       SvREFCNT_dec (SvRV (sv_self));
259       SvRV_set (sv_self, &PL_sv_undef);
260       sv_self_cache = sv_self;
261     }
262 
263   if (ecb_expect_false (SvREFCNT (sv_events) != 1 || sv_events_cache))
264     SvREFCNT_dec (sv_events);
265   else
266     sv_events_cache = sv_events;
267 
268   if (ecb_expect_false (SvTRUE (ERRSV)))
269     {
270       SPAGAIN;
271       PUSHMARK (SP);
272       PUTBACK;
273       call_sv (get_sv ("EV::DIED", 1), G_DISCARD | G_VOID | G_EVAL | G_KEEPERR);
274     }
275 
276   SP = PL_stack_base + mark;
277   PUTBACK;
278 }
279 
280 static void
e_once_cb(int revents,void * arg)281 e_once_cb (int revents, void *arg)
282 {
283   dSP;
284   I32 mark = SP - PL_stack_base;
285   SV *sv_events;
286 
287   if (sv_events_cache)
288     {
289       sv_events = sv_events_cache; sv_events_cache = 0;
290       SvIV_set (sv_events, revents);
291     }
292   else
293     sv_events = newSViv (revents);
294 
295   PUSHMARK (SP);
296   XPUSHs (sv_events);
297 
298   PUTBACK;
299   call_sv ((SV *)arg, G_DISCARD | G_VOID | G_EVAL);
300 
301   SvREFCNT_dec ((SV *)arg);
302 
303   if (sv_events_cache)
304     SvREFCNT_dec (sv_events);
305   else
306     sv_events_cache = sv_events;
307 
308   if (SvTRUE (ERRSV))
309     {
310       SPAGAIN;
311       PUSHMARK (SP);
312       PUTBACK;
313       call_sv (get_sv ("EV::DIED", 1), G_DISCARD | G_VOID | G_EVAL | G_KEEPERR);
314     }
315 
316   SP = PL_stack_base + mark;
317   PUTBACK;
318 }
319 
320 static ev_tstamp
e_periodic_cb(ev_periodic * w,ev_tstamp now)321 e_periodic_cb (ev_periodic *w, ev_tstamp now)
322 {
323   ev_tstamp retval;
324   int count;
325   dSP;
326 
327   ENTER;
328   SAVETMPS;
329 
330   PUSHMARK (SP);
331   EXTEND (SP, 2);
332   PUSHs (newRV_inc (e_self (w))); /* e_self (w) MUST be blessed by now */
333   PUSHs (newSVnv (now));
334 
335   PUTBACK;
336   count = call_sv (w->fh, G_SCALAR | G_EVAL);
337   SPAGAIN;
338 
339   if (SvTRUE (ERRSV))
340     {
341       PUSHMARK (SP);
342       PUTBACK;
343       call_sv (get_sv ("EV::DIED", 1), G_DISCARD | G_VOID | G_EVAL | G_KEEPERR);
344       SPAGAIN;
345     }
346 
347   if (count > 0)
348     {
349       retval = SvNV (TOPs);
350 
351       if (retval < now)
352         retval = now;
353     }
354   else
355     retval = now;
356 
357   FREETMPS;
358   LEAVE;
359 
360   return retval;
361 }
362 
363 #define CHECK_REPEAT(repeat) if (repeat < 0.) \
364   croak (# repeat " value must be >= 0");
365 
366 #define CHECK_FD(fh,fd) if ((fd) < 0) \
367   croak ("illegal file descriptor or filehandle (either no attached file descriptor or illegal value): %s", SvPV_nolen (fh));
368 
369 #define CHECK_SIG(sv,num) if ((num) < 0) \
370   croak ("illegal signal number or name: %s", SvPV_nolen (sv));
371 
372 static void
default_fork(void)373 default_fork (void)
374 {
375   ev_loop_fork (EV_DEFAULT_UC);
376 }
377 
378 /////////////////////////////////////////////////////////////////////////////
379 // XS interface functions
380 
381 MODULE = EV		PACKAGE = EV		PREFIX = ev_
382 
383 PROTOTYPES: ENABLE
384 
385 BOOT:
386 {
387   HV *stash = gv_stashpv ("EV", 1);
388 
389   static const struct {
390     const char *name;
391     IV iv;
392   } *civ, const_iv[] = {
393 #   define const_iv(pfx, name) { # name, (IV) pfx ## name },
394     const_iv (EV_, MINPRI)
395     const_iv (EV_, MAXPRI)
396 
397     const_iv (EV_, UNDEF)
398     const_iv (EV_, NONE)
399     const_iv (EV_, READ)
400     const_iv (EV_, WRITE)
401     const_iv (EV_, IO)
402     const_iv (EV_, TIMER)
403     const_iv (EV_, PERIODIC)
404     const_iv (EV_, SIGNAL)
405     const_iv (EV_, CHILD)
406     const_iv (EV_, STAT)
407     const_iv (EV_, IDLE)
408     const_iv (EV_, PREPARE)
409     /*const_iv (EV_, CHECK) needs special tretament */
410     const_iv (EV_, EMBED)
411     const_iv (EV_, FORK)
412     const_iv (EV_, CLEANUP)
413     const_iv (EV_, ASYNC)
414     const_iv (EV_, CUSTOM)
415     const_iv (EV_, ERROR)
416 
417     const_iv (EV, RUN_NOWAIT)
418     const_iv (EV, RUN_ONCE)
419 
420     const_iv (EV, BREAK_CANCEL)
421     const_iv (EV, BREAK_ONE)
422     const_iv (EV, BREAK_ALL)
423     const_iv (EV, BACKEND_SELECT)
424     const_iv (EV, BACKEND_POLL)
425     const_iv (EV, BACKEND_EPOLL)
426     const_iv (EV, BACKEND_KQUEUE)
427     const_iv (EV, BACKEND_DEVPOLL)
428     const_iv (EV, BACKEND_PORT)
429     const_iv (EV, BACKEND_ALL)
430     const_iv (EV, BACKEND_MASK)
431     const_iv (EV, FLAG_AUTO)
432     const_iv (EV, FLAG_FORKCHECK)
433     const_iv (EV, FLAG_SIGNALFD)
434     const_iv (EV, FLAG_NOSIGMASK)
435     const_iv (EV, FLAG_NOENV)
436     const_iv (EV, FLAG_NOINOTIFY)
437 
438     const_iv (EV_, VERSION_MAJOR)
439     const_iv (EV_, VERSION_MINOR)
440 #if EV_COMPAT3
441     const_iv (EV, FLAG_NOSIGFD) /* compatibility, always 0 */
442     const_iv (EV_, TIMEOUT)
443     const_iv (EV, LOOP_NONBLOCK)
444     const_iv (EV, LOOP_ONESHOT)
445     const_iv (EV, UNLOOP_CANCEL)
446     const_iv (EV, UNLOOP_ONE)
447     const_iv (EV, UNLOOP_ALL)
448 #endif
449   };
450 
451   for (civ = const_iv + sizeof (const_iv) / sizeof (const_iv [0]); civ > const_iv; civ--)
452     newCONSTSUB (stash, (char *)civ[-1].name, newSViv (civ[-1].iv));
453 
454   /* since this clashes with perl CHECK blocks, */
455   /* but we are interested in constants, */
456   /* and not blocks, we treat CHECK specially. */
457   {
458     /* the local $^W = 0 takes care of the warning */
459     CV *cv = newCONSTSUB (stash, "CHECK", newSViv (EV_CHECK));
460     /* now we need to re-set the gv, in case it was hijacked */
461     GvCV_set (gv_fetchpv ("EV::CHECK", GV_ADD, SVt_PVCV), cv);
462   }
463 
464   stash_loop     = gv_stashpv ("EV::Loop"    , 1);
465   stash_watcher  = gv_stashpv ("EV::Watcher" , 1);
466   stash_io       = gv_stashpv ("EV::IO"      , 1);
467   stash_timer    = gv_stashpv ("EV::Timer"   , 1);
468   stash_periodic = gv_stashpv ("EV::Periodic", 1);
469   stash_signal   = gv_stashpv ("EV::Signal"  , 1);
470   stash_idle     = gv_stashpv ("EV::Idle"    , 1);
471   stash_prepare  = gv_stashpv ("EV::Prepare" , 1);
472   stash_check    = gv_stashpv ("EV::Check"   , 1);
473   stash_child    = gv_stashpv ("EV::Child"   , 1);
474   stash_embed    = gv_stashpv ("EV::Embed"   , 1);
475   stash_stat     = gv_stashpv ("EV::Stat"    , 1);
476   stash_fork     = gv_stashpv ("EV::Fork"    , 1);
477   stash_cleanup  = gv_stashpv ("EV::Cleanup" , 1);
478   stash_async    = gv_stashpv ("EV::Async"   , 1);
479 
480   {
481     SV *sv = perl_get_sv ("EV::API", TRUE);
482              perl_get_sv ("EV::API", TRUE); /* silence 5.10 warning */
483 
484     /* the poor man's shared library emulator */
485     evapi.ver                  = EV_API_VERSION;
486     evapi.rev                  = EV_API_REVISION;
487     evapi.sv_fileno            = sv_fileno;
488     evapi.sv_signum            = s_signum;
489     evapi.supported_backends   = ev_supported_backends ();
490     evapi.recommended_backends = ev_recommended_backends ();
491     evapi.embeddable_backends  = ev_embeddable_backends ();
492     evapi.time_                = ev_time;
493     evapi.sleep_               = ev_sleep;
494     evapi.loop_new             = ev_loop_new;
495     evapi.loop_destroy         = ev_loop_destroy;
496     evapi.loop_fork            = ev_loop_fork;
497     evapi.iteration            = ev_iteration;
498     evapi.depth                = ev_depth;
499     evapi.set_userdata         = ev_set_userdata;
500     evapi.userdata             = ev_userdata;
501     evapi.now                  = ev_now;
502     evapi.now_update           = ev_now_update;
503     evapi.suspend              = ev_suspend;
504     evapi.resume               = ev_resume;
505     evapi.backend              = ev_backend;
506     evapi.break_               = ev_break;
507     evapi.invoke_pending       = ev_invoke_pending;
508     evapi.pending_count        = ev_pending_count;
509     evapi.verify               = ev_verify;
510     evapi.set_loop_release_cb  = ev_set_loop_release_cb;
511     evapi.set_invoke_pending_cb= ev_set_invoke_pending_cb;
512     evapi.ref                  = ev_ref;
513     evapi.unref                = ev_unref;
514     evapi.run                  = ev_run;
515     evapi.once                 = ev_once;
516     evapi.io_start             = ev_io_start;
517     evapi.io_stop              = ev_io_stop;
518     evapi.timer_start          = ev_timer_start;
519     evapi.timer_stop           = ev_timer_stop;
520     evapi.timer_again          = ev_timer_again;
521     evapi.timer_remaining      = ev_timer_remaining;
522     evapi.periodic_start       = ev_periodic_start;
523     evapi.periodic_stop        = ev_periodic_stop;
524     evapi.signal_start         = ev_signal_start;
525     evapi.signal_stop          = ev_signal_stop;
526     evapi.idle_start           = ev_idle_start;
527     evapi.idle_stop            = ev_idle_stop;
528     evapi.prepare_start        = ev_prepare_start;
529     evapi.prepare_stop         = ev_prepare_stop;
530     evapi.check_start          = ev_check_start;
531     evapi.check_stop           = ev_check_stop;
532 #if EV_CHILD_ENABLE
533     evapi.child_start          = ev_child_start;
534     evapi.child_stop           = ev_child_stop;
535 #endif
536     evapi.stat_start           = ev_stat_start;
537     evapi.stat_stop            = ev_stat_stop;
538     evapi.stat_stat            = ev_stat_stat;
539     evapi.embed_start          = ev_embed_start;
540     evapi.embed_stop           = ev_embed_stop;
541     evapi.embed_sweep          = ev_embed_sweep;
542     evapi.fork_start           = ev_fork_start;
543     evapi.fork_stop            = ev_fork_stop;
544     evapi.cleanup_start        = ev_cleanup_start;
545     evapi.cleanup_stop         = ev_cleanup_stop;
546     evapi.async_start          = ev_async_start;
547     evapi.async_stop           = ev_async_stop;
548     evapi.async_send           = ev_async_send;
549     evapi.clear_pending        = ev_clear_pending;
550     evapi.invoke               = ev_invoke;
551 
552     sv_setiv (sv, (IV)&evapi);
553     SvREADONLY_on (sv);
554   }
555 #if !defined _WIN32 && !defined _MINIX && !EV_NO_ATFORK
556 /* unfortunately, musl neither implements the linux standard base,
557 /* nor makes itself detectable via macros. yeah, right... */
558 #if __linux && (__GLIBC__ || __UCLIBC__)
559   int __register_atfork(void (*prepare) (void), void (*parent) (void), void (*child) (void), void *   __dso_handle);
560   __register_atfork (0, 0, default_fork, 0);
561 #else
562   pthread_atfork (0, 0, default_fork);
563 #endif
564 #endif
565 }
566 
567 SV *ev_default_loop (unsigned int flags = 0)
568 	CODE:
569 {
570 	if (!default_loop_sv)
571           {
572             evapi.default_loop = ev_default_loop (flags);
573 
574             if (!evapi.default_loop)
575               XSRETURN_UNDEF;
576 
577             default_loop_sv = sv_bless (newRV_noinc (newSViv (PTR2IV (evapi.default_loop))), stash_loop);
578           }
579 
580         RETVAL = newSVsv (default_loop_sv);
581 }
582 	OUTPUT:
583         RETVAL
584 
585 void ev_default_destroy ()
586 	CODE:
587         ev_loop_destroy (EV_DEFAULT_UC);
588         SvREFCNT_dec (default_loop_sv);
589         default_loop_sv = 0;
590 
ev_supported_backends()591 unsigned int ev_supported_backends ()
592 
593 unsigned int ev_recommended_backends ()
594 
595 unsigned int ev_embeddable_backends ()
596 
597 void ev_sleep (NV interval)
598 
599 NV ev_time ()
600 
601 void ev_feed_signal (SV *signal)
602 	CODE:
603 {
604 	Signal signum = s_signum (signal);
605         CHECK_SIG (signal, signum);
606 
607         ev_feed_signal (signum);
608 }
609 
ev_now()610 NV ev_now ()
611 	C_ARGS: evapi.default_loop
612 
613 void ev_now_update ()
614 	C_ARGS: evapi.default_loop
615 
616 void ev_suspend ()
617 	C_ARGS: evapi.default_loop
618 
619 void ev_resume ()
620 	C_ARGS: evapi.default_loop
621 
622 unsigned int ev_backend ()
623 	C_ARGS: evapi.default_loop
624 
625 void ev_verify ()
626 	ALIAS:
627         loop_verify = 1
628 	C_ARGS: evapi.default_loop
629 
630 unsigned int ev_iteration ()
631 	ALIAS:
632         loop_count = 1
633 	C_ARGS: evapi.default_loop
634 
635 unsigned int ev_depth ()
636 	ALIAS:
637         loop_depth = 1
638 	C_ARGS: evapi.default_loop
639 
640 void ev_set_io_collect_interval (NV interval)
641 	C_ARGS: evapi.default_loop, interval
642 
643 void ev_set_timeout_collect_interval (NV interval)
644 	C_ARGS: evapi.default_loop, interval
645 
646 int ev_run (int flags = 0)
647 	ALIAS:
648         loop = 1
649 	C_ARGS: evapi.default_loop, flags
650 
651 void ev_break (int how = EVBREAK_ONE)
652 	ALIAS:
653         unloop = 1
654 	C_ARGS: evapi.default_loop, how
655 
656 void ev_feed_fd_event (int fd, int revents = EV_NONE)
657 	C_ARGS: evapi.default_loop, fd, revents
658 
659 void ev_feed_signal_event (SV *signal)
660 	CODE:
661 {
662 	Signal signum = s_signum (signal);
663         CHECK_SIG (signal, signum);
664 
665         ev_feed_signal_event (evapi.default_loop, signum);
666 }
667 
ev_pending_count()668 unsigned int ev_pending_count ()
669 	C_ARGS: evapi.default_loop
670 
671 void ev_invoke_pending ()
672 	C_ARGS: evapi.default_loop
673 
674 ev_io *io (SV *fh, int events, SV *cb)
675 	ALIAS:
676         io_ns = 1
677         _ae_io = 2
678 	CODE:
679 {
680 	int fd = s_fileno (fh, events & EV_WRITE);
681         CHECK_FD (fh, fd);
682 
683         if (ix == 2)
684           {
685             ix = 0;
686             events = events ? EV_WRITE : EV_READ;
687           }
688 
689         RETVAL = e_new (sizeof (ev_io), cb, default_loop_sv);
690         e_fh (RETVAL) = newSVsv (fh);
691         ev_io_set (RETVAL, fd, events);
692         if (!ix) START (io, RETVAL);
693 }
694 	OUTPUT:
695         RETVAL
696 
697 ev_timer *timer (NV after, NV repeat, SV *cb)
698 	ALIAS:
699         timer_ns = 1
700         INIT:
701         CHECK_REPEAT (repeat);
702 	CODE:
703         RETVAL = e_new (sizeof (ev_timer), cb, default_loop_sv);
704         ev_timer_set (RETVAL, after, repeat);
705         if (!ix) START (timer, RETVAL);
706 	OUTPUT:
707         RETVAL
708 
709 SV *periodic (NV at, NV interval, SV *reschedule_cb, SV *cb)
710 	ALIAS:
711         periodic_ns = 1
712         INIT:
713         CHECK_REPEAT (interval);
714 	CODE:
715 {
716 	ev_periodic *w;
717         w = e_new (sizeof (ev_periodic), cb, default_loop_sv);
718         e_fh (w) = SvTRUE (reschedule_cb) ? newSVsv (reschedule_cb) : 0;
719         ev_periodic_set (w, at, interval, e_fh (w) ? e_periodic_cb : 0);
720         RETVAL = e_bless ((ev_watcher *)w, stash_periodic);
721         if (!ix) START (periodic, w);
722 }
723 	OUTPUT:
724         RETVAL
725 
signal(SV * signal,SV * cb)726 ev_signal *signal (SV *signal, SV *cb)
727 	ALIAS:
728         signal_ns = 1
729 	CODE:
730 {
731 	Signal signum = s_signum (signal);
732         CHECK_SIG (signal, signum);
733 
734         RETVAL = e_new (sizeof (ev_signal), cb, default_loop_sv);
735         ev_signal_set (RETVAL, signum);
736         if (!ix) START_SIGNAL (RETVAL);
737 }
738 	OUTPUT:
739         RETVAL
740 
741 ev_idle *idle (SV *cb)
742 	ALIAS:
743         idle_ns = 1
744 	CODE:
745         RETVAL = e_new (sizeof (ev_idle), cb, default_loop_sv);
746         ev_idle_set (RETVAL);
747         if (!ix) START (idle, RETVAL);
748 	OUTPUT:
749         RETVAL
750 
751 ev_prepare *prepare (SV *cb)
752 	ALIAS:
753         prepare_ns = 1
754 	CODE:
755         RETVAL = e_new (sizeof (ev_prepare), cb, default_loop_sv);
756         ev_prepare_set (RETVAL);
757         if (!ix) START (prepare, RETVAL);
758 	OUTPUT:
759         RETVAL
760 
761 ev_check *check (SV *cb)
762 	ALIAS:
763         check_ns = 1
764 	CODE:
765         RETVAL = e_new (sizeof (ev_check), cb, default_loop_sv);
766         ev_check_set (RETVAL);
767         if (!ix) START (check, RETVAL);
768 	OUTPUT:
769         RETVAL
770 
771 ev_fork *fork (SV *cb)
772 	ALIAS:
773         fork_ns = 1
774 	CODE:
775         RETVAL = e_new (sizeof (ev_fork), cb, default_loop_sv);
776         ev_fork_set (RETVAL);
777         if (!ix) START (fork, RETVAL);
778 	OUTPUT:
779         RETVAL
780 
781 #if CLEANUP_ENABLED
782 
783 ev_cleanup *cleanup (SV *cb)
784 	ALIAS:
785         cleanup_ns = 1
786 	CODE:
787         RETVAL = e_new (sizeof (ev_cleanup), cb, default_loop_sv);
788         SvREFCNT_dec (RETVAL->loop); /* must not keep loop object alive */
789         ev_cleanup_set (RETVAL);
790         if (!ix) START (cleanup, RETVAL);
791 	OUTPUT:
792         RETVAL
793 
794 #endif
795 
796 ev_child *child (int pid, int trace, SV *cb)
797 	ALIAS:
798         child_ns = 1
799 	CODE:
800 #if EV_CHILD_ENABLE
801         RETVAL = e_new (sizeof (ev_child), cb, default_loop_sv);
802         ev_child_set (RETVAL, pid, trace);
803         if (!ix) START (child, RETVAL);
804 #else
805         croak ("EV::child watchers not supported on this platform");
806 #endif
807 	OUTPUT:
808         RETVAL
809 
810 
811 ev_stat *stat (SV *path, NV interval, SV *cb)
812 	ALIAS:
813         stat_ns = 1
814 	CODE:
815         RETVAL = e_new (sizeof (ev_stat), cb, default_loop_sv);
816         e_fh (RETVAL) = newSVsv (path);
817         ev_stat_set (RETVAL, SvPVbyte_nolen (e_fh (RETVAL)), interval);
818         if (!ix) START (stat, RETVAL);
819 	OUTPUT:
820         RETVAL
821 
822 #ifndef EV_NO_LOOPS
823 
824 ev_embed *embed (struct ev_loop *loop, SV *cb = 0)
825 	ALIAS:
826         embed_ns = 1
827 	CODE:
828 {
829         if (!(ev_backend (loop) & ev_embeddable_backends ()))
830           croak ("passed loop is not embeddable via EV::embed,");
831 
832         RETVAL = e_new (sizeof (ev_embed), cb, default_loop_sv);
833         e_fh (RETVAL) = newSVsv (ST (0));
834         ev_embed_set (RETVAL, loop);
835         if (!ix) START (embed, RETVAL);
836 }
837 	OUTPUT:
838         RETVAL
839 
840 #endif
841 
842 ev_async *async (SV *cb)
843 	ALIAS:
844         async_ns = 1
845 	CODE:
846         RETVAL = e_new (sizeof (ev_async), cb, default_loop_sv);
847         ev_async_set (RETVAL);
848         if (!ix) START (async, RETVAL);
849 	OUTPUT:
850         RETVAL
851 
852 void once (SV *fh, int events, SV *timeout, SV *cb)
853 	CODE:
854         ev_once (
855            evapi.default_loop,
856            s_fileno (fh, events & EV_WRITE), events,
857            SvOK (timeout) ? SvNV (timeout) : -1.,
858            e_once_cb,
859            newSVsv (cb)
860         );
861 
862 PROTOTYPES: DISABLE
863 
864 MODULE = EV		PACKAGE = EV::Watcher	PREFIX = ev_
865 
ev_is_active(ev_watcher * w)866 int ev_is_active (ev_watcher *w)
867 
868 int ev_is_pending (ev_watcher *w)
869 
870 void ev_invoke (ev_watcher *w, int revents = EV_NONE)
871 	C_ARGS: e_loop (w), w, revents
872 
873 int ev_clear_pending (ev_watcher *w)
874 	C_ARGS: e_loop (w), w
875 
876 void ev_feed_event (ev_watcher *w, int revents = EV_NONE)
877 	C_ARGS: e_loop (w), w, revents
878 
879 int keepalive (ev_watcher *w, SV *new_value = NO_INIT)
880 	CODE:
881 {
882         RETVAL = w->e_flags & WFLAG_KEEPALIVE;
883 
884         if (items > 1)
885           {
886             int value = SvTRUE (new_value) ? WFLAG_KEEPALIVE : 0;
887 
888             if ((value ^ w->e_flags) & WFLAG_KEEPALIVE)
889               {
890                 w->e_flags = (w->e_flags & ~WFLAG_KEEPALIVE) | value;
891                 REF (w);
892                 UNREF (w);
893               }
894           }
895 }
896 	OUTPUT:
897         RETVAL
898 
899 SV *cb (ev_watcher *w, SV *new_cb = NO_INIT)
900 	CODE:
901 {
902         if (items > 1)
903           {
904             new_cb = s_get_cv_croak (new_cb);
905             RETVAL = newRV_noinc (w->cb_sv);
906             w->cb_sv = SvREFCNT_inc (new_cb);
907           }
908         else
909           RETVAL = newRV_inc (w->cb_sv);
910 }
911 	OUTPUT:
912         RETVAL
913 
914 SV *data (ev_watcher *w, SV *new_data = NO_INIT)
915 	CODE:
916 {
917 	RETVAL = w->data ? newSVsv (w->data) : &PL_sv_undef;
918 
919         if (items > 1)
920           {
921             SvREFCNT_dec (w->data);
922             w->data = newSVsv (new_data);
923           }
924 }
925 	OUTPUT:
926         RETVAL
927 
928 SV *loop (ev_watcher *w)
929 	CODE:
930 	RETVAL = newRV_inc (w->loop);
931 	OUTPUT:
932         RETVAL
933 
934 int priority (ev_watcher *w, SV *new_priority = NO_INIT)
935 	CODE:
936 {
937         RETVAL = w->priority;
938 
939         if (items > 1)
940           {
941             int active = ev_is_active (w);
942 
943             if (active)
944               {
945                 /* grrr. */
946                 PUSHMARK (SP);
947                 XPUSHs (ST (0));
948                 PUTBACK;
949                 call_method ("stop", G_DISCARD | G_VOID);
950               }
951 
952             ev_set_priority (w, SvIV (new_priority));
953 
954             if (active)
955               {
956                 PUSHMARK (SP);
957                 XPUSHs (ST (0));
958                 PUTBACK;
959                 call_method ("start", G_DISCARD | G_VOID);
960               }
961           }
962 }
963 	OUTPUT:
964         RETVAL
965 
966 MODULE = EV		PACKAGE = EV::IO	PREFIX = ev_io_
967 
968 void ev_io_start (ev_io *w)
969 	CODE:
970         START (io, w);
971 
972 void ev_io_stop (ev_io *w)
973 	CODE:
974         STOP (io, w);
975 
976 void DESTROY (ev_io *w)
977 	CODE:
978         STOP (io, w);
979         e_destroy (w);
980 
set(ev_io * w,SV * fh,int events)981 void set (ev_io *w, SV *fh, int events)
982 	CODE:
983 {
984 	int fd = s_fileno (fh, events & EV_WRITE);
985         CHECK_FD (fh, fd);
986 
987         sv_setsv (e_fh (w), fh);
988         RESET (io, w, (w, fd, events));
989 }
990 
991 SV *fh (ev_io *w, SV *new_fh = NO_INIT)
992 	CODE:
993 {
994         if (items > 1)
995           {
996             int fd = s_fileno (new_fh, w->events & EV_WRITE);
997             CHECK_FD (new_fh, fd);
998 
999             RETVAL = e_fh (w);
1000             e_fh (w) = newSVsv (new_fh);
1001 
1002             RESET (io, w, (w, fd, w->events));
1003           }
1004         else
1005           RETVAL = newSVsv (e_fh (w));
1006 }
1007 	OUTPUT:
1008         RETVAL
1009 
1010 int events (ev_io *w, int new_events = NO_INIT)
1011 	CODE:
1012 {
1013         RETVAL = w->events;
1014 
1015         if (items > 1 && (new_events ^ w->events) & (EV_READ | EV_WRITE))
1016           {
1017             PAUSE (io);
1018             ev_io_modify (w, new_events);
1019             RESUME (io);
1020           }
1021 }
1022 	OUTPUT:
1023         RETVAL
1024 
1025 MODULE = EV		PACKAGE = EV::Signal	PREFIX = ev_signal_
1026 
1027 void ev_signal_start (ev_signal *w)
1028 	CODE:
1029         START_SIGNAL (w);
1030 
1031 void ev_signal_stop (ev_signal *w)
1032 	CODE:
1033         STOP (signal, w);
1034 
1035 void DESTROY (ev_signal *w)
1036 	CODE:
1037         STOP (signal, w);
1038         e_destroy (w);
1039 
set(ev_signal * w,SV * signal)1040 void set (ev_signal *w, SV *signal)
1041 	CODE:
1042 {
1043 	Signal signum = s_signum (signal);
1044         CHECK_SIG (signal, signum);
1045 
1046         RESET_SIGNAL (w, (w, signum));
1047 }
1048 
1049 int signal (ev_signal *w, SV *new_signal = NO_INIT)
1050 	CODE:
1051 {
1052         RETVAL = w->signum;
1053 
1054         if (items > 1)
1055           {
1056             Signal signum = s_signum (new_signal);
1057             CHECK_SIG (new_signal, signum);
1058             RESET_SIGNAL (w, (w, signum));
1059           }
1060 }
1061 	OUTPUT:
1062         RETVAL
1063 
1064 MODULE = EV		PACKAGE = EV::Timer	PREFIX = ev_timer_
1065 
1066 void ev_timer_start (ev_timer *w)
1067         INIT:
1068         CHECK_REPEAT (w->repeat);
1069 	CODE:
1070         START (timer, w);
1071 
1072 void ev_timer_stop (ev_timer *w)
1073 	CODE:
1074         STOP (timer, w);
1075 
1076 void ev_timer_again (ev_timer *w, NV repeat = NO_INIT)
1077         CODE:
1078 {
1079         if (items > 1)
1080           {
1081             CHECK_REPEAT (repeat);
1082             w->repeat = repeat;
1083           }
1084 
1085         ev_timer_again (e_loop (w), w);
1086         UNREF (w);
1087 }
1088 
1089 NV ev_timer_remaining (ev_timer *w)
1090 	C_ARGS: e_loop (w), w
1091 
1092 void DESTROY (ev_timer *w)
1093 	CODE:
1094         STOP (timer, w);
1095         e_destroy (w);
1096 
1097 void set (ev_timer *w, NV after, NV repeat = 0.)
1098         INIT:
1099         CHECK_REPEAT (repeat);
1100 	CODE:
1101         RESET (timer, w, (w, after, repeat));
1102 
1103 NV repeat (ev_timer *w, SV *new_repeat = NO_INIT)
1104 	CODE:
1105         RETVAL = w->repeat;
1106         if (items > 1)
1107           {
1108             NV repeat = SvNV (new_repeat);
1109             CHECK_REPEAT (repeat);
1110             w->repeat = repeat;
1111           }
1112 	OUTPUT:
1113         RETVAL
1114 
1115 MODULE = EV		PACKAGE = EV::Periodic	PREFIX = ev_periodic_
1116 
1117 void ev_periodic_start (ev_periodic *w)
1118         INIT:
1119         CHECK_REPEAT (w->interval);
1120 	CODE:
1121         START (periodic, w);
1122 
1123 void ev_periodic_stop (ev_periodic *w)
1124 	CODE:
1125         STOP (periodic, w);
1126 
1127 void ev_periodic_again (ev_periodic *w)
1128 	CODE:
1129         ev_periodic_again (e_loop (w), w);
1130         UNREF (w);
1131 
1132 void DESTROY (ev_periodic *w)
1133 	CODE:
1134         STOP (periodic, w);
1135         e_destroy (w);
1136 
1137 void set (ev_periodic *w, NV at, NV interval = 0., SV *reschedule_cb = &PL_sv_undef)
1138         INIT:
1139         CHECK_REPEAT (interval);
1140 	CODE:
1141 {
1142         SvREFCNT_dec (e_fh (w));
1143         e_fh (w) = SvTRUE (reschedule_cb) ? newSVsv (reschedule_cb) : 0;
1144 
1145         RESET (periodic, w, (w, at, interval, e_fh (w) ? e_periodic_cb : 0));
1146 }
1147 
1148 NV at (ev_periodic *w)
1149 	CODE:
1150         RETVAL = ev_periodic_at (w);
1151 	OUTPUT:
1152         RETVAL
1153 
1154 NV offset (ev_periodic *w, SV *new_offset = NO_INIT)
1155 	CODE:
1156         RETVAL = w->offset;
1157         if (items > 1)
1158           w->offset = SvNV (new_offset);
1159 	OUTPUT:
1160         RETVAL
1161 
1162 NV interval (ev_periodic *w, SV *new_interval = NO_INIT)
1163 	CODE:
1164         RETVAL = w->interval;
1165         if (items > 1)
1166           {
1167             NV interval = SvNV (new_interval);
1168             CHECK_REPEAT (interval);
1169             w->interval = interval;
1170           }
1171 	OUTPUT:
1172         RETVAL
1173 
1174 SV *reschedule_cb (ev_periodic *w, SV *new_reschedule_cb = NO_INIT)
1175 	CODE:
1176         RETVAL = e_fh (w) ? e_fh (w) : &PL_sv_undef;
1177         if (items > 1)
1178           {
1179             sv_2mortal (RETVAL);
1180             e_fh (w) = SvTRUE (new_reschedule_cb) ? newSVsv (new_reschedule_cb) : 0;
1181           }
1182 	OUTPUT:
1183         RETVAL
1184 
1185 MODULE = EV		PACKAGE = EV::Idle	PREFIX = ev_idle_
1186 
1187 void ev_idle_start (ev_idle *w)
1188 	CODE:
1189         START (idle, w);
1190 
1191 void ev_idle_stop (ev_idle *w)
1192 	CODE:
1193         STOP (idle, w);
1194 
1195 void DESTROY (ev_idle *w)
1196 	CODE:
1197         STOP (idle, w);
1198         e_destroy (w);
1199 
1200 MODULE = EV		PACKAGE = EV::Prepare	PREFIX = ev_prepare_
1201 
1202 void ev_prepare_start (ev_prepare *w)
1203 	CODE:
1204         START (prepare, w);
1205 
1206 void ev_prepare_stop (ev_prepare *w)
1207 	CODE:
1208         STOP (prepare, w);
1209 
1210 void DESTROY (ev_prepare *w)
1211 	CODE:
1212         STOP (prepare, w);
1213         e_destroy (w);
1214 
1215 MODULE = EV		PACKAGE = EV::Check	PREFIX = ev_check_
1216 
1217 void ev_check_start (ev_check *w)
1218 	CODE:
1219         START (check, w);
1220 
1221 void ev_check_stop (ev_check *w)
1222 	CODE:
1223         STOP (check, w);
1224 
1225 void DESTROY (ev_check *w)
1226 	CODE:
1227         STOP (check, w);
1228         e_destroy (w);
1229 
1230 MODULE = EV		PACKAGE = EV::Fork	PREFIX = ev_fork_
1231 
1232 void ev_fork_start (ev_fork *w)
1233 	CODE:
1234         START (fork, w);
1235 
1236 void ev_fork_stop (ev_fork *w)
1237 	CODE:
1238         STOP (fork, w);
1239 
1240 void DESTROY (ev_fork *w)
1241 	CODE:
1242         STOP (fork, w);
1243         e_destroy (w);
1244 
1245 #if CLEANUP_ENABLED
1246 
1247 MODULE = EV		PACKAGE = EV::Cleanup	PREFIX = ev_cleanup_
1248 
1249 void ev_cleanup_start (ev_cleanup *w)
1250 	CODE:
1251         START (cleanup, w);
1252 
1253 void ev_cleanup_stop (ev_cleanup *w)
1254 	CODE:
1255         STOP (cleanup, w);
1256 
1257 void DESTROY (ev_cleanup *w)
1258 	CODE:
1259         STOP (cleanup, w);
1260         SvREFCNT_inc (w->loop); /* has been dec'ed on creation */
1261         e_destroy (w);
1262 
1263 int keepalive (ev_watcher *w, SV *new_value = 0)
1264 	CODE:
1265         RETVAL = 1;
1266 	OUTPUT:
1267         RETVAL
1268 
1269 #endif
1270 
1271 MODULE = EV		PACKAGE = EV::Child	PREFIX = ev_child_
1272 
1273 #if EV_CHILD_ENABLE
1274 
1275 void ev_child_start (ev_child *w)
1276 	CODE:
1277         START (child, w);
1278 
1279 void ev_child_stop (ev_child *w)
1280 	CODE:
1281         STOP (child, w);
1282 
1283 void DESTROY (ev_child *w)
1284 	CODE:
1285         STOP (child, w);
1286         e_destroy (w);
1287 
1288 void set (ev_child *w, int pid, int trace)
1289 	CODE:
1290         RESET (child, w, (w, pid, trace));
1291 
1292 int pid (ev_child *w)
1293 	ALIAS:
1294         rpid    = 1
1295         rstatus = 2
1296 	CODE:
1297         RETVAL = ix == 0 ? w->pid
1298                : ix == 1 ? w->rpid
1299                :           w->rstatus;
1300 	OUTPUT:
1301         RETVAL
1302 
1303 #endif
1304 
1305 MODULE = EV		PACKAGE = EV::Stat	PREFIX = ev_stat_
1306 
1307 void ev_stat_start (ev_stat *w)
1308 	CODE:
1309         START (stat, w);
1310 
1311 void ev_stat_stop (ev_stat *w)
1312 	CODE:
1313         STOP (stat, w);
1314 
1315 void DESTROY (ev_stat *w)
1316 	CODE:
1317         STOP (stat, w);
1318         e_destroy (w);
1319 
set(ev_stat * w,SV * path,NV interval)1320 void set (ev_stat *w, SV *path, NV interval)
1321 	CODE:
1322 {
1323         sv_setsv (e_fh (w), path);
1324 	RESET (stat, w, (w, SvPVbyte_nolen (e_fh (w)), interval));
1325 }
1326 
1327 SV *path (ev_stat *w, SV *new_path = NO_INIT)
1328 	CODE:
1329 {
1330         RETVAL = e_fh (w) ? e_fh (w) : &PL_sv_undef;
1331 
1332         if (items > 1)
1333           {
1334             sv_2mortal (RETVAL);
1335             e_fh (w) = newSVsv (new_path);
1336             RESET (stat, w, (w, SvPVbyte_nolen (e_fh (w)), w->interval));
1337           }
1338 }
1339 	OUTPUT:
1340         RETVAL
1341 
1342 NV interval (ev_stat *w, SV *new_interval = NO_INIT)
1343 	CODE:
1344         RETVAL = w->interval;
1345         if (items > 1)
1346           {
1347             PAUSE (stat);
1348             w->interval = SvNV (new_interval);
1349             RESUME (stat);
1350           }
1351 	OUTPUT:
1352         RETVAL
1353 
prev(ev_stat * w)1354 void prev (ev_stat *w)
1355 	ALIAS:
1356         stat = 1
1357         attr = 2
1358 	PPCODE:
1359 {
1360 	ev_statdata *s = ix ? &w->attr : &w->prev;
1361 
1362         if (ix == 1)
1363           ev_stat_stat (e_loop (w), w);
1364         else if (!s->st_nlink)
1365           errno = ENOENT;
1366 
1367         PL_statcache.st_dev   = s->st_nlink;
1368         PL_statcache.st_ino   = s->st_ino;
1369         PL_statcache.st_mode  = s->st_mode;
1370         PL_statcache.st_nlink = s->st_nlink;
1371         PL_statcache.st_uid   = s->st_uid;
1372         PL_statcache.st_gid   = s->st_gid;
1373         PL_statcache.st_rdev  = s->st_rdev;
1374         PL_statcache.st_size  = s->st_size;
1375         PL_statcache.st_atime = s->st_atime;
1376         PL_statcache.st_mtime = s->st_mtime;
1377         PL_statcache.st_ctime = s->st_ctime;
1378 
1379         if (GIMME_V == G_SCALAR)
1380           XPUSHs (boolSV (s->st_nlink));
1381         else if (GIMME_V == G_ARRAY && s->st_nlink)
1382           {
1383             EXTEND (SP, 13);
1384             PUSHs (sv_2mortal (newSViv (s->st_dev)));
1385             PUSHs (sv_2mortal (newSViv (s->st_ino)));
1386             PUSHs (sv_2mortal (newSVuv (s->st_mode)));
1387             PUSHs (sv_2mortal (newSVuv (s->st_nlink)));
1388             PUSHs (sv_2mortal (newSViv (s->st_uid)));
1389             PUSHs (sv_2mortal (newSViv (s->st_gid)));
1390             PUSHs (sv_2mortal (newSViv (s->st_rdev)));
1391             PUSHs (sv_2mortal (newSVnv ((NV)s->st_size)));
1392             PUSHs (sv_2mortal (newSVnv (s->st_atime)));
1393             PUSHs (sv_2mortal (newSVnv (s->st_mtime)));
1394             PUSHs (sv_2mortal (newSVnv (s->st_ctime)));
1395             PUSHs (sv_2mortal (newSVuv (4096)));
1396             PUSHs (sv_2mortal (newSVnv ((NV)((s->st_size + 4095) / 4096))));
1397           }
1398 }
1399 
1400 MODULE = EV		PACKAGE = EV::Embed	PREFIX = ev_embed_
1401 
1402 void ev_embed_start (ev_embed *w)
1403 	CODE:
1404         START (embed, w);
1405 
1406 void ev_embed_stop (ev_embed *w)
1407 	CODE:
1408         STOP (embed, w);
1409 
1410 void DESTROY (ev_embed *w)
1411 	CODE:
1412         STOP (embed, w);
1413         e_destroy (w);
1414 
set(ev_embed * w,struct ev_loop * loop)1415 void set (ev_embed *w, struct ev_loop *loop)
1416 	CODE:
1417 {
1418         sv_setsv (e_fh (w), ST (1));
1419 	RESET (embed, w, (w, loop));
1420 }
1421 
1422 SV *other (ev_embed *w)
1423 	CODE:
1424         RETVAL = newSVsv (e_fh (w));
1425 	OUTPUT:
1426         RETVAL
1427 
1428 void ev_embed_sweep (ev_embed *w)
1429 	C_ARGS: e_loop (w), w
1430 
1431 MODULE = EV		PACKAGE = EV::Async	PREFIX = ev_async_
1432 
1433 void ev_async_start (ev_async *w)
1434 	CODE:
1435         START (async, w);
1436 
1437 void ev_async_stop (ev_async *w)
1438 	CODE:
1439         STOP (async, w);
1440 
1441 void DESTROY (ev_async *w)
1442 	CODE:
1443         STOP (async, w);
1444         e_destroy (w);
1445 
1446 void ev_async_send (ev_async *w)
1447 	C_ARGS: e_loop (w), w
1448 
1449 SV *ev_async_async_pending (ev_async *w)
1450         CODE:
1451         RETVAL = boolSV (ev_async_pending (w));
1452 	OUTPUT:
1453         RETVAL
1454 
1455 #ifndef EV_NO_LOOPS
1456 
1457 MODULE = EV		PACKAGE = EV::Loop	PREFIX = ev_
1458 
1459 SV *new (SV *klass, unsigned int flags = 0)
1460 	CODE:
1461 {
1462 	struct ev_loop *loop = ev_loop_new (flags);
1463 
1464         if (!loop)
1465           XSRETURN_UNDEF;
1466 
1467         RETVAL = sv_bless (newRV_noinc (newSViv (PTR2IV (loop))), stash_loop);
1468 }
1469 	OUTPUT:
1470         RETVAL
1471 
1472 void DESTROY (struct ev_loop *loop)
1473 	CODE:
1474         /* 1. the default loop shouldn't be freed by destroying it's perl loop object */
1475         /* 2. not doing so helps avoid many global destruction bugs in perl, too */
1476         if (loop != evapi.default_loop)
1477           ev_loop_destroy (loop);
1478 
ev_loop_fork(struct ev_loop * loop)1479 void ev_loop_fork (struct ev_loop *loop)
1480 
1481 NV ev_now (struct ev_loop *loop)
1482 
1483 void ev_now_update (struct ev_loop *loop)
1484 
1485 void ev_suspend (struct ev_loop *loop)
1486 
1487 void ev_resume (struct ev_loop *loop)
1488 
1489 void ev_set_io_collect_interval (struct ev_loop *loop, NV interval)
1490 
1491 void ev_set_timeout_collect_interval (struct ev_loop *loop, NV interval)
1492 
1493 unsigned int ev_backend (struct ev_loop *loop)
1494 
1495 void ev_verify (struct ev_loop *loop)
1496 	ALIAS:
1497         loop_verify = 1
1498 
1499 unsigned int ev_iteration (struct ev_loop *loop)
1500 	ALIAS:
1501         loop_count = 1
1502 
1503 unsigned int ev_depth (struct ev_loop *loop)
1504 	ALIAS:
1505         loop_depth = 1
1506 
1507 int ev_run (struct ev_loop *loop, int flags = 0)
1508 	ALIAS:
1509         loop = 1
1510 
1511 void ev_break (struct ev_loop *loop, int how = 1)
1512 	ALIAS:
1513         unloop = 1
1514 
1515 void ev_feed_fd_event (struct ev_loop *loop, int fd, int revents = EV_NONE)
1516 
1517 unsigned int ev_pending_count (struct ev_loop *loop)
1518 
1519 void ev_invoke_pending (struct ev_loop *loop)
1520 
1521 #if 0
1522 
1523 void ev_feed_signal_event (struct ev_loop *loop, SV *signal)
1524 	CODE:
1525 {
1526 	Signal signum = s_signum (signal);
1527         CHECK_SIG (signal, signum);
1528 
1529         ev_feed_signal_event (loop, signum);
1530 }
1531 
1532 #endif
1533 
1534 ev_io *io (struct ev_loop *loop, SV *fh, int events, SV *cb)
1535 	ALIAS:
1536         io_ns = 1
1537 	CODE:
1538 {
1539 	int fd = s_fileno (fh, events & EV_WRITE);
1540         CHECK_FD (fh, fd);
1541 
1542         RETVAL = e_new (sizeof (ev_io), cb, ST (0));
1543         e_fh (RETVAL) = newSVsv (fh);
1544         ev_io_set (RETVAL, fd, events);
1545         if (!ix) START (io, RETVAL);
1546 }
1547 	OUTPUT:
1548         RETVAL
1549 
1550 ev_timer *timer (struct ev_loop *loop, NV after, NV repeat, SV *cb)
1551 	ALIAS:
1552         timer_ns = 1
1553         INIT:
1554         CHECK_REPEAT (repeat);
1555 	CODE:
1556         RETVAL = e_new (sizeof (ev_timer), cb, ST (0));
1557         ev_timer_set (RETVAL, after, repeat);
1558         if (!ix) START (timer, RETVAL);
1559 	OUTPUT:
1560         RETVAL
1561 
1562 SV *periodic (struct ev_loop *loop, NV at, NV interval, SV *reschedule_cb, SV *cb)
1563 	ALIAS:
1564         periodic_ns = 1
1565         INIT:
1566         CHECK_REPEAT (interval);
1567 	CODE:
1568 {
1569 	ev_periodic *w;
1570         w = e_new (sizeof (ev_periodic), cb, ST (0));
1571         e_fh (w) = SvTRUE (reschedule_cb) ? newSVsv (reschedule_cb) : 0;
1572         ev_periodic_set (w, at, interval, e_fh (w) ? e_periodic_cb : 0);
1573         RETVAL = e_bless ((ev_watcher *)w, stash_periodic);
1574         if (!ix) START (periodic, w);
1575 }
1576 	OUTPUT:
1577         RETVAL
1578 
signal(struct ev_loop * loop,SV * signal,SV * cb)1579 ev_signal *signal (struct ev_loop *loop, SV *signal, SV *cb)
1580 	ALIAS:
1581         signal_ns = 1
1582 	CODE:
1583 {
1584 	Signal signum = s_signum (signal);
1585         CHECK_SIG (signal, signum);
1586 
1587         RETVAL = e_new (sizeof (ev_signal), cb, ST (0));
1588         ev_signal_set (RETVAL, signum);
1589         if (!ix) START_SIGNAL (RETVAL);
1590 }
1591 	OUTPUT:
1592         RETVAL
1593 
1594 ev_idle *idle (struct ev_loop *loop, SV *cb)
1595 	ALIAS:
1596         idle_ns = 1
1597 	CODE:
1598         RETVAL = e_new (sizeof (ev_idle), cb, ST (0));
1599         ev_idle_set (RETVAL);
1600         if (!ix) START (idle, RETVAL);
1601 	OUTPUT:
1602         RETVAL
1603 
1604 ev_prepare *prepare (struct ev_loop *loop, SV *cb)
1605 	ALIAS:
1606         prepare_ns = 1
1607 	CODE:
1608         RETVAL = e_new (sizeof (ev_prepare), cb, ST (0));
1609         ev_prepare_set (RETVAL);
1610         if (!ix) START (prepare, RETVAL);
1611 	OUTPUT:
1612         RETVAL
1613 
1614 ev_check *check (struct ev_loop *loop, SV *cb)
1615 	ALIAS:
1616         check_ns = 1
1617 	CODE:
1618         RETVAL = e_new (sizeof (ev_check), cb, ST (0));
1619         ev_check_set (RETVAL);
1620         if (!ix) START (check, RETVAL);
1621 	OUTPUT:
1622         RETVAL
1623 
1624 ev_fork *fork (struct ev_loop *loop, SV *cb)
1625 	ALIAS:
1626         fork_ns = 1
1627 	CODE:
1628         RETVAL = e_new (sizeof (ev_fork), cb, ST (0));
1629         ev_fork_set (RETVAL);
1630         if (!ix) START (fork, RETVAL);
1631 	OUTPUT:
1632         RETVAL
1633 
1634 #if CLEANUP_ENABLED
1635 
1636 ev_cleanup *cleanup (struct ev_loop *loop, SV *cb)
1637 	ALIAS:
1638         cleanup_ns = 1
1639 	CODE:
1640         RETVAL = e_new (sizeof (ev_cleanup), cb, ST (0));
1641         SvREFCNT_dec (RETVAL->loop); /* must not keep loop object alive */
1642         ev_cleanup_set (RETVAL);
1643         if (!ix) START (cleanup, RETVAL);
1644 	OUTPUT:
1645         RETVAL
1646 
1647 #endif
1648 
1649 ev_child *child (struct ev_loop *loop, int pid, int trace, SV *cb)
1650 	ALIAS:
1651         child_ns = 1
1652 	CODE:
1653 #if EV_CHILD_ENABLE
1654         RETVAL = e_new (sizeof (ev_child), cb, ST (0));
1655         ev_child_set (RETVAL, pid, trace);
1656         if (!ix) START (child, RETVAL);
1657 #else
1658         croak ("EV::child watchers not supported on this platform");
1659 #endif
1660 	OUTPUT:
1661         RETVAL
1662 
1663 ev_stat *stat (struct ev_loop *loop, SV *path, NV interval, SV *cb)
1664 	ALIAS:
1665         stat_ns = 1
1666 	CODE:
1667         RETVAL = e_new (sizeof (ev_stat), cb, ST (0));
1668         e_fh (RETVAL) = newSVsv (path);
1669         ev_stat_set (RETVAL, SvPVbyte_nolen (e_fh (RETVAL)), interval);
1670         if (!ix) START (stat, RETVAL);
1671 	OUTPUT:
1672         RETVAL
1673 
1674 ev_embed *embed (struct ev_loop *loop, struct ev_loop *other, SV *cb = 0)
1675 	ALIAS:
1676         embed_ns = 1
1677 	CODE:
1678 {
1679         if (!(ev_backend (other) & ev_embeddable_backends ()))
1680           croak ("passed loop is not embeddable via EV::embed,");
1681 
1682         RETVAL = e_new (sizeof (ev_embed), cb, ST (0));
1683         e_fh (RETVAL) = newSVsv (ST (1));
1684         ev_embed_set (RETVAL, other);
1685         if (!ix) START (embed, RETVAL);
1686 }
1687 	OUTPUT:
1688         RETVAL
1689 
1690 ev_async *async (struct ev_loop *loop, SV *cb)
1691 	ALIAS:
1692         async_ns = 1
1693 	CODE:
1694         RETVAL = e_new (sizeof (ev_async), cb, ST (0));
1695         ev_async_set (RETVAL);
1696         if (!ix) START (async, RETVAL);
1697 	OUTPUT:
1698         RETVAL
1699 
1700 void once (struct ev_loop *loop, SV *fh, int events, SV *timeout, SV *cb)
1701 	CODE:
1702         ev_once (
1703            loop,
1704            s_fileno (fh, events & EV_WRITE), events,
1705            SvOK (timeout) ? SvNV (timeout) : -1.,
1706            e_once_cb,
1707            newSVsv (cb)
1708         );
1709 
1710 #endif
1711 
1712