--- cvsroot/EV/EV.xs 2008/11/19 10:20:25 1.118 +++ cvsroot/EV/EV.xs 2009/06/29 18:46:52 1.124 @@ -36,33 +36,30 @@ # define SvRV_set(a,b) SvRV ((a)) = (b) #endif -#if __GNUC__ >= 3 -# define expect(expr,value) __builtin_expect ((expr),(value)) -#else -# define expect(expr,value) (expr) -#endif - -#define expect_false(expr) expect ((expr) != 0, 0) -#define expect_true(expr) expect ((expr) != 0, 1) - #define e_loop(w) INT2PTR (struct ev_loop *, SvIVX ((w)->loop)) #define WFLAG_KEEPALIVE 1 +#define WFLAG_UNREFED 2 /* has been unref'ed */ #define UNREF(w) \ - if (!((w)->e_flags & WFLAG_KEEPALIVE) \ - && !ev_is_active (w)) \ - ev_unref (e_loop (w)); + if (!((w)->e_flags & (WFLAG_KEEPALIVE | WFLAG_UNREFED)) \ + && ev_is_active (w)) \ + { \ + ev_unref (e_loop (w)); \ + (w)->e_flags |= WFLAG_UNREFED; \ + } #define REF(w) \ - if (!((w)->e_flags & WFLAG_KEEPALIVE) \ - && ev_is_active (w)) \ - ev_ref (e_loop (w)); + if ((w)->e_flags & WFLAG_UNREFED) \ + { \ + (w)->e_flags &= ~WFLAG_UNREFED; \ + ev_ref (e_loop (w)); \ + } #define START(type,w) \ do { \ - UNREF (w); \ ev_ ## type ## _start (e_loop (w), w); \ + UNREF (w); \ } while (0) #define STOP(type,w) \ @@ -221,6 +218,11 @@ I32 mark = SP - PL_stack_base; SV *sv_self, *sv_events; + /* libev might have stopped the watcher */ + if (expect_false (w->e_flags & WFLAG_UNREFED) + && !ev_is_active (w)) + REF (w); + if (expect_true (sv_self_cache)) { sv_self = sv_self_cache; sv_self_cache = 0; @@ -251,7 +253,7 @@ PUTBACK; call_sv (w->cb_sv, G_DISCARD | G_VOID | G_EVAL); - if (expect_false (sv_self_cache)) + if (expect_false (SvREFCNT (sv_self) != 1 || sv_self_cache)) SvREFCNT_dec (sv_self); else { @@ -260,12 +262,12 @@ sv_self_cache = sv_self; } - if (expect_false (sv_events_cache)) + if (expect_false (SvREFCNT (sv_events) != 1 || sv_events_cache)) SvREFCNT_dec (sv_events); else sv_events_cache = sv_events; - if (SvTRUE (ERRSV)) + if (expect_false (SvTRUE (ERRSV))) { SPAGAIN; PUSHMARK (SP); @@ -390,16 +392,28 @@ const_iv (EV_, UNDEF) const_iv (EV_, NONE) - const_iv (EV_, TIMEOUT) const_iv (EV_, READ) const_iv (EV_, WRITE) + const_iv (EV_, IO) + const_iv (EV_, TIMEOUT) + const_iv (EV_, TIMER) + const_iv (EV_, PERIODIC) const_iv (EV_, SIGNAL) + const_iv (EV_, CHILD) + const_iv (EV_, STAT) const_iv (EV_, IDLE) + const_iv (EV_, PREPARE) const_iv (EV_, CHECK) + const_iv (EV_, EMBED) + const_iv (EV_, FORK) + const_iv (EV_, ASYNC) + const_iv (EV_, CUSTOM) const_iv (EV_, ERROR) - const_iv (EV, LOOP_ONESHOT) const_iv (EV, LOOP_NONBLOCK) + const_iv (EV, LOOP_ONESHOT) + + const_iv (EV, UNLOOP_CANCEL) const_iv (EV, UNLOOP_ONE) const_iv (EV, UNLOOP_ALL) @@ -412,6 +426,9 @@ const_iv (EV, FLAG_AUTO) const_iv (EV, FLAG_NOENV) const_iv (EV, FLAG_FORKCHECK) + + const_iv (EV_, VERSION_MAJOR) + const_iv (EV_, VERSION_MINOR) }; for (civ = const_iv + sizeof (const_iv) / sizeof (const_iv [0]); civ-- > const_iv; ) @@ -452,6 +469,8 @@ evapi.loop_count = ev_loop_count; evapi.now = ev_now; evapi.now_update = ev_now_update; + evapi.suspend = ev_suspend; + evapi.resume = ev_resume; evapi.backend = ev_backend; evapi.unloop = ev_unloop; evapi.ref = ev_ref; @@ -537,6 +556,12 @@ void ev_now_update () C_ARGS: evapi.default_loop +void ev_suspend () + C_ARGS: evapi.default_loop + +void ev_resume () + C_ARGS: evapi.default_loop + unsigned int ev_backend () C_ARGS: evapi.default_loop @@ -749,8 +774,8 @@ if (items > 1 && ((new_value ^ w->e_flags) & WFLAG_KEEPALIVE)) { - REF (w); w->e_flags = (w->e_flags & ~WFLAG_KEEPALIVE) | new_value; + REF (w); UNREF (w); } } @@ -935,7 +960,6 @@ INIT: CHECK_REPEAT (w->repeat); CODE: - REF (w); ev_timer_again (e_loop (w), w); UNREF (w); @@ -964,7 +988,6 @@ void ev_periodic_again (ev_periodic *w) CODE: - REF (w); ev_periodic_again (e_loop (w), w); UNREF (w); @@ -1257,6 +1280,10 @@ void ev_now_update (struct ev_loop *loop) +void ev_suspend (struct ev_loop *loop) + +void ev_resume (struct ev_loop *loop) + void ev_set_io_collect_interval (struct ev_loop *loop, NV interval) void ev_set_timeout_collect_interval (struct ev_loop *loop, NV interval)