Skip to content

Commit

Permalink
Merge pull request #40 from hsbt/use-rb_thread_call_without_gvl
Browse files Browse the repository at this point in the history
Support Ruby 2.1
  • Loading branch information
tarcieri committed Mar 18, 2014
2 parents 860b35e + 10ade44 commit acded07
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 8 deletions.
22 changes: 18 additions & 4 deletions ext/libev/ev.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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
/* ######################################## */
Expand Down Expand Up @@ -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
Expand Down
6 changes: 5 additions & 1 deletion ext/nio4r/extconf.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
6 changes: 3 additions & 3 deletions ext/nio4r/selector.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand All @@ -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)
Expand All @@ -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;
Expand Down

0 comments on commit acded07

Please sign in to comment.