--- EV/EV.xs 2007/10/29 18:33:02 1.13 +++ EV/EV.xs 2007/10/30 12:48:29 1.14 @@ -200,33 +200,48 @@ { struct ev *ev = (struct ev*)arg; dSP; - - ENTER; - SAVETMPS; + I32 mark = SP - PL_stack_base; + SV *sv_self, *sv_events; + static SV *sv_events_cache; if (!(ev->ev.ev_events & EV_PERSIST) || (events & EV_TIMEOUT)) ev->active = 0; + sv_self = e_self (ev); + + if (sv_events_cache) + { + sv_events = sv_events_cache; sv_events_cache = 0; + SvIV_set (sv_events, events); + } + else + sv_events = newSViv (events); + PUSHMARK (SP); EXTEND (SP, 2); - PUSHs (sv_2mortal (e_self (ev))); - PUSHs (sv_2mortal (newSViv (events))); + PUSHs (sv_self); + PUSHs (sv_events); PUTBACK; call_sv (ev->cb, G_DISCARD | G_VOID | G_EVAL); + SP = PL_stack_base + mark; PUTBACK; + + SvREFCNT_dec (sv_self); + + if (sv_events_cache) + SvREFCNT_dec (sv_events); + else + sv_events_cache = sv_events; if (ev->interval && !ev->active) e_start (ev); - FREETMPS; - 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; } - - LEAVE; } /////////////////////////////////////////////////////////////////////////////