--- EV/EV.xs 2007/11/23 05:13:48 1.74 +++ EV/EV.xs 2007/11/23 12:22:26 1.75 @@ -91,7 +91,7 @@ if (SvTYPE (fh) == SVt_PVGV) return PerlIO_fileno (IoIFP (sv_2io (fh))); - if ((SvIV (fh) >= 0) && (SvIV (fh) < 0x7ffffff)) + if (SvOK (fh) && (SvIV (fh) >= 0) && (SvIV (fh) < 0x7fffffffL)) return SvIV (fh); return -1; @@ -144,13 +144,14 @@ return rv; } +static SV *sv_events_cache; + static void e_cb (struct ev_watcher *w, int revents) { dSP; I32 mark = SP - PL_stack_base; - SV *sv_self, *sv_events, *sv_status = 0; - static SV *sv_events_cache; + SV *sv_self, *sv_events; sv_self = newRV_inc (w->self); /* w->self MUST be blessed by now */ @@ -171,7 +172,45 @@ call_sv (w->cb_sv, G_DISCARD | G_VOID | G_EVAL); SvREFCNT_dec (sv_self); - SvREFCNT_dec (sv_status); + + if (sv_events_cache) + SvREFCNT_dec (sv_events); + else + sv_events_cache = sv_events; + + if (SvTRUE (ERRSV)) + { + PUSHMARK (SP); + PUTBACK; + call_sv (get_sv ("EV::DIED", 1), G_DISCARD | G_VOID | G_EVAL | G_KEEPERR); + } + + SP = PL_stack_base + mark; + PUTBACK; +} + +static void +e_once_cb (int revents, void *arg) +{ + dSP; + I32 mark = SP - PL_stack_base; + SV *sv_events; + + if (sv_events_cache) + { + sv_events = sv_events_cache; sv_events_cache = 0; + SvIV_set (sv_events, revents); + } + else + sv_events = newSViv (revents); + + PUSHMARK (SP); + XPUSHs (sv_events); + + PUTBACK; + call_sv ((SV *)arg, G_DISCARD | G_VOID | G_EVAL); + + SvREFCNT_dec ((SV *)arg); if (sv_events_cache) SvREFCNT_dec (sv_events); @@ -497,6 +536,9 @@ OUTPUT: RETVAL +void once (SV *fh, int events, NV timeout, SV *cb) + CODE: + ev_once (sv_fileno (fh), events, timeout, e_once_cb, newSVsv (cb)); PROTOTYPES: DISABLE