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;