Permalink
Browse files

Merge pull request #40 from hsbt/use-rb_thread_call_without_gvl

Support Ruby 2.1
  • Loading branch information...
tarcieri committed Mar 18, 2014
2 parents 860b35e + 10ade44 commit acded07663bbf27e7e38285a8cf19ff776fab434
Showing with 26 additions and 8 deletions.
  1. +18 −4 ext/libev/ev.c
  2. +5 −1 ext/nio4r/extconf.rb
  3. +3 −3 ext/nio4r/selector.c
View
@@ -3242,7 +3242,7 @@ time_update (EV_P_ ev_tstamp max_block)
}
/* ########## NIO4R PATCHERY HO! ########## */
#if defined(HAVE_RB_THREAD_BLOCKING_REGION)
#if defined(HAVE_RB_THREAD_BLOCKING_REGION) || defined(HAVE_RB_THREAD_CALL_WITHOUT_GVL)
struct ev_poll_args {
struct ev_loop *loop;
ev_tstamp waittime;
@@ -3262,7 +3262,7 @@ int
ev_run (EV_P_ int flags)
{
/* ########## NIO4R PATCHERY HO! ########## */
#if defined(HAVE_RB_THREAD_BLOCKING_REGION)
#if defined(HAVE_RB_THREAD_BLOCKING_REGION) || defined(HAVE_RB_THREAD_CALL_WITHOUT_GVL)
struct ev_poll_args poll_args;
#endif
/* ######################################## */
@@ -3425,10 +3425,24 @@ rb_thread_unsafe_dangerous_crazy_blocking_region_end(...);
#######################################################################
*/
#if defined(HAVE_RB_THREAD_BLOCKING_REGION)
/*
simulate to rb_thread_call_without_gvl using rb_theread_blocking_region.
https://github.com/brianmario/mysql2/blob/master/ext/mysql2/client.h#L8
*/
#ifndef HAVE_RB_THREAD_CALL_WITHOUT_GVL
#ifdef HAVE_RB_THREAD_BLOCKING_REGION
#define rb_thread_call_without_gvl(func, data1, ubf, data2) \
rb_thread_blocking_region((rb_blocking_function_t *)func, data1, ubf, data2)
#endif
#endif
#if defined(HAVE_RB_THREAD_BLOCKING_REGION) || defined(HAVE_RB_THREAD_CALL_WITHOUT_GVL)
poll_args.loop = loop;
poll_args.waittime = waittime;
rb_thread_blocking_region(ev_backend_poll, (void *)&poll_args, RUBY_UBF_IO, 0);
rb_thread_call_without_gvl(ev_backend_poll, (void *)&poll_args, RUBY_UBF_IO, 0);
#else
backend_poll (EV_A_ waittime);
#endif
View
@@ -4,6 +4,10 @@
$defs << '-DHAVE_RB_THREAD_BLOCKING_REGION'
end
if have_func('rb_thread_call_without_gvl')
$defs << '-DHAVE_RB_THEREAD_CALL_WITHOUT_GVL'
end
if have_header('sys/select.h')
$defs << '-DEV_USE_SELECT'
end
@@ -41,4 +45,4 @@
makefile_contents.gsub! 'LIBS = $(LIBRUBYARG_SHARED)', 'LIBS = -lws2_32 $(LIBRUBYARG_SHARED)'
File.open('Makefile', 'w') { |f| f.write makefile_contents }
end
end
View
@@ -312,7 +312,7 @@ static int NIO_Selector_run(struct NIO_Selector *selector, VALUE timeout)
int result;
selector->selecting = 1;
#if defined(HAVE_RB_THREAD_BLOCKING_REGION) || defined(HAVE_RB_THREAD_ALONE)
#if defined(HAVE_RB_THREAD_BLOCKING_REGION) || defined(HAVE_RB_THREAD_CALL_WITHOUT_GVL) || defined(HAVE_RB_THREAD_ALONE)
/* Implement the optional timeout (if any) as a ev_timer */
if(timeout != Qnil) {
/* It seems libev is not a fan of timers being zero, so fudge a little */
@@ -326,7 +326,7 @@ static int NIO_Selector_run(struct NIO_Selector *selector, VALUE timeout)
ev_tstamp started_at = ev_now(selector->ev_loop);
#endif
#if defined(HAVE_RB_THREAD_BLOCKING_REGION)
#if defined(HAVE_RB_THREAD_BLOCKING_REGION) || defined(HAVE_RB_THREAD_CALL_WITHOUT_GVL)
/* libev is patched to release the GIL when it makes its system call */
ev_loop(selector->ev_loop, EVLOOP_ONESHOT);
#elif defined(HAVE_RB_THREAD_ALONE)
@@ -337,7 +337,7 @@ static int NIO_Selector_run(struct NIO_Selector *selector, VALUE timeout)
if(0) {
#endif /* defined(HAVE_RB_THREAD_BLOCKING_REGION) */
#if !defined(HAVE_RB_THREAD_BLOCKING_REGION)
#if !defined(HAVE_RB_THREAD_BLOCKING_REGION) && !defined(HAVE_RB_THREAD_CALL_WITHOUT_GVL)
TRAP_BEG;
ev_loop(selector->ev_loop, EVLOOP_ONESHOT);
TRAP_END;

0 comments on commit acded07

Please sign in to comment.