ext/rev/rev_loop.c in rev-0.3.1 vs ext/rev/rev_loop.c in rev-0.3.2

- old
+ new

@@ -10,10 +10,18 @@ #include "ev_wrap.h" #include "rev.h" +#if defined(HAVE_RB_THREAD_BLOCKING_REGION) +# define Rev_Loop_may_block_safely() (1) +#elif defined(HAVE_RB_THREAD_ALONE) +# define Rev_Loop_may_block_safely() (rb_thread_alone()) +#else /* just in case Ruby changes: */ +# define Rev_Loop_may_block_safely() (0) +#endif + static VALUE mRev = Qnil; static VALUE cRev_Loop = Qnil; static VALUE Rev_Loop_allocate(VALUE klass); static void Rev_Loop_mark(struct Rev_Loop *loop); @@ -173,23 +181,30 @@ * * Run the Rev::Loop once, blocking until events are received. */ static VALUE Rev_Loop_run_once(VALUE self) { - struct Rev_Loop *loop_data; VALUE nevents; - - Data_Get_Struct(self, struct Rev_Loop, loop_data); - assert(loop_data->ev_loop && !loop_data->events_received); - - Rev_Loop_ev_loop_oneshot(loop_data); - Rev_Loop_dispatch_events(loop_data); - - nevents = INT2NUM(loop_data->events_received); - loop_data->events_received = 0; - + if (Rev_Loop_may_block_safely()) { + struct Rev_Loop *loop_data; + + Data_Get_Struct(self, struct Rev_Loop, loop_data); + + assert(loop_data->ev_loop && !loop_data->events_received); + + Rev_Loop_ev_loop_oneshot(loop_data); + Rev_Loop_dispatch_events(loop_data); + + nevents = INT2NUM(loop_data->events_received); + loop_data->events_received = 0; + + } else { + nevents = Rev_Loop_run_nonblock(self); + rb_thread_schedule(); + } + return nevents; } /* Ruby 1.9 supports blocking system calls through rb_thread_blocking_region() */ #ifdef HAVE_RB_THREAD_BLOCKING_REGION @@ -258,10 +273,12 @@ Data_Get_Struct(self, struct Rev_Loop, loop_data); assert(loop_data->ev_loop && !loop_data->events_received); + TRAP_BEG; RUN_LOOP(loop_data, EVLOOP_NONBLOCK); + TRAP_END; Rev_Loop_dispatch_events(loop_data); nevents = INT2NUM(loop_data->events_received); loop_data->events_received = 0;