--- cvsroot/EV/EV.xs 2007/10/31 11:55:42 1.18 +++ cvsroot/EV/EV.xs 2007/10/31 20:19:20 1.25 @@ -2,15 +2,12 @@ #include "perl.h" #include "XSUB.h" -#include -#include +/*#include */ #define TIMEOUT_NONE HUGE_VAL +#define HAVE_EPOLL 1 -#define EV_COMMON \ - SV *self; /* contains this struct */ \ - SV *cb_sv, *fh; - +#define EV_PROTOTYPES 1 #include "EV/EVAPI.h" #include "libev/ev.c" @@ -27,7 +24,9 @@ *stash_periodic, *stash_signal, *stash_idle, - *stash_check; + *stash_prepare, + *stash_check, + *stash_child; static int sv_signum (SV *sig) @@ -44,21 +43,6 @@ return -1; } -static void -api_once (int fd, short events, double timeout, void (*cb)(int, short, void *), void *arg) -{ -#if 0 - if (timeout >= 0.) - { - struct timeval tv; - tv_set (&tv, timeout); - event_once (fd, events, cb, arg, &tv); - } - else - event_once (fd, events, cb, arg, 0); -#endif -} - ///////////////////////////////////////////////////////////////////////////// // Event @@ -122,7 +106,7 @@ { dSP; I32 mark = SP - PL_stack_base; - SV *sv_self, *sv_events; + SV *sv_self, *sv_events, *sv_status = 0; static SV *sv_events_cache; sv_self = newRV_inc (w->self); /* w->self MUST be blessed by now */ @@ -139,11 +123,16 @@ EXTEND (SP, 2); PUSHs (sv_self); PUSHs (sv_events); + + if (revents & EV_CHILD) + XPUSHs (sv_status = newSViv (((struct ev_child *)w)->status)); + PUTBACK; call_sv (w->cb_sv, G_DISCARD | G_VOID | G_EVAL); SP = PL_stack_base + mark; PUTBACK; SvREFCNT_dec (sv_self); + SvREFCNT_dec (sv_status); if (sv_events_cache) SvREFCNT_dec (sv_events); @@ -221,6 +210,8 @@ MODULE = EV PACKAGE = EV PREFIX = ev_ +PROTOTYPES: ENABLE + BOOT: { int i; @@ -231,6 +222,7 @@ IV iv; } *civ, const_iv[] = { # define const_iv(pfx, name) { # name, (IV) pfx ## name }, + const_iv (EV_, UNDEF) const_iv (EV_, NONE) const_iv (EV_, TIMEOUT) const_iv (EV_, READ) @@ -238,6 +230,7 @@ const_iv (EV_, SIGNAL) const_iv (EV_, IDLE) const_iv (EV_, CHECK) + const_iv (EV_, ERROR) const_iv (EV, LOOP_ONESHOT) const_iv (EV, LOOP_NONBLOCK) @@ -257,7 +250,9 @@ stash_periodic = gv_stashpv ("EV::Periodic", 1); stash_signal = gv_stashpv ("EV::Signal" , 1); stash_idle = gv_stashpv ("EV::Idle" , 1); + stash_prepare = gv_stashpv ("EV::Prepare" , 1); stash_check = gv_stashpv ("EV::Check" , 1); + stash_child = gv_stashpv ("EV::Child" , 1); { SV *sv = perl_get_sv ("EV::API", TRUE); @@ -266,7 +261,6 @@ /* the poor man's shared library emulator */ evapi.ver = EV_API_VERSION; evapi.rev = EV_API_REVISION; - evapi.once = api_once; evapi.sv_fileno = sv_fileno; evapi.sv_signum = sv_signum; evapi.now = &ev_now; @@ -274,6 +268,7 @@ evapi.loop_done = &ev_loop_done; evapi.time = ev_time; evapi.loop = ev_loop; + evapi.once = ev_once; evapi.io_start = evio_start; evapi.io_stop = evio_stop; evapi.timer_start = evtimer_start; @@ -285,8 +280,12 @@ evapi.signal_stop = evsignal_stop; evapi.idle_start = evidle_start; evapi.idle_stop = evidle_stop; + evapi.prepare_start = evprepare_start; + evapi.prepare_stop = evprepare_stop; evapi.check_start = evcheck_start; evapi.check_stop = evcheck_stop; + evapi.child_start = evchild_start; + evapi.child_stop = evchild_stop; sv_setiv (sv, (IV)&evapi); SvREADONLY_on (sv); @@ -370,6 +369,16 @@ OUTPUT: RETVAL +struct ev_prepare *prepare (SV *cb) + ALIAS: + prepare_ns = 1 + CODE: + RETVAL = e_new (sizeof (struct ev_prepare), cb); + evprepare_set (RETVAL); + if (!ix) evprepare_start (RETVAL); + OUTPUT: + RETVAL + struct ev_check *check (SV *cb) ALIAS: check_ns = 1 @@ -380,6 +389,16 @@ OUTPUT: RETVAL +struct ev_child *child (int pid, SV *cb) + ALIAS: + check_ns = 1 + CODE: + RETVAL = e_new (sizeof (struct ev_check), cb); + evchild_set (RETVAL, pid); + if (!ix) evchild_start (RETVAL); + OUTPUT: + RETVAL + PROTOTYPES: DISABLE @@ -520,12 +539,39 @@ void evidle_stop (struct ev_idle *w) +MODULE = EV PACKAGE = EV::Prepare PREFIX = evcheck_ + +void evprepare_start (struct ev_prepare *w) + +void evprepare_stop (struct ev_prepare *w) + MODULE = EV PACKAGE = EV::Check PREFIX = evcheck_ void evcheck_start (struct ev_check *w) void evcheck_stop (struct ev_check *w) +MODULE = EV PACKAGE = EV::Child PREFIX = evchild_ + +void evchild_start (struct ev_child *w) + +void evchild_stop (struct ev_child *w) + +void set (struct ev_child *w, int pid) + CODE: +{ + int active = w->active; + if (active) evchild_stop (w); + evchild_set (w, pid); + if (active) evchild_start (w); +} + +int status (struct ev_child *w) + CODE: + RETVAL = w->status; + OUTPUT: + RETVAL + #if 0 MODULE = EV PACKAGE = EV::DNS PREFIX = evdns_