From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on dcvr.yhbt.net X-Spam-Level: X-Spam-ASN: AS47066 71.19.144.0/20 X-Spam-Status: No, score=-1.9 required=3.0 tests=AWL,BAYES_00, MSGID_FROM_MTA_HEADER shortcircuit=no autolearn=unavailable version=3.3.2 Path: news.gmane.org!not-for-mail From: Eric Wong Newsgroups: gmane.comp.lang.ruby.io-splice.general Subject: [PATCH] prepare for rb_thread_blocking_region removal Date: Sun, 9 Feb 2014 00:51:02 +0000 Message-ID: <20140209005102.GA4222@dcvr.yhbt.net> References: <20140209005102.GA4222@dcvr.yhbt.net> NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit X-Trace: ger.gmane.org 1391907068 12478 80.91.229.3 (9 Feb 2014 00:51:08 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Sun, 9 Feb 2014 00:51:08 +0000 (UTC) To: ruby.io.splice@librelist.org Original-X-From: ruby.io.splice@librelist.org Sun Feb 09 01:51:17 2014 Return-path: Envelope-to: gclrig-ruby.io.splice@m.gmane.org In-Reply-To: <20140209005102.GA4222@dcvr.yhbt.net> List-Archive: List-Help: List-Id: List-Post: List-Subscribe: List-Unsubscribe: Precedence: list Original-Sender: ruby.io.splice@librelist.org Xref: news.gmane.org gmane.comp.lang.ruby.io-splice.general:47 Archived-At: Received: from zedshaw2.xen.prgmr.com ([71.19.156.177]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1WCIc7-0004IC-0n for gclrig-ruby.io.splice@m.gmane.org; Sun, 09 Feb 2014 01:51:15 +0100 Received: from zedshaw2.xen.prgmr.com (unknown [IPv6:::1]) by zedshaw2.xen.prgmr.com (Postfix) with ESMTP id 9DFEF7516B for ; Sun, 9 Feb 2014 00:59:45 +0000 (UTC) It'll be OK to use rb_thread_call_without_gvl when rb_thread_blocking_region is not detectable at all. We still use rb_thread_blocking_region for Ruby 2.0-2.1 because rb_thread_call_without_gvl was detectable in 1.9.3, but not usable as an internal symbol. ref: https://bugs.ruby-lang.org/issues/9502 --- ext/io_splice/extconf.rb | 1 + ext/io_splice/io_splice_ext.c | 45 ++++++++++++++++++++++++++----------------- 2 files changed, 28 insertions(+), 18 deletions(-) diff --git a/ext/io_splice/extconf.rb b/ext/io_splice/extconf.rb index 52dab83..bfd655a 100644 --- a/ext/io_splice/extconf.rb +++ b/ext/io_splice/extconf.rb @@ -5,6 +5,7 @@ have_func('splice', %w(fcntl.h)) or abort 'splice(2) not defined' have_func('tee', %w(fcntl.h)) or abort 'tee(2) not defined' have_func('pipe2', %w(fcntl.h unistd.h)) have_func('rb_thread_blocking_region') +have_func('rb_thread_call_without_gvl') have_macro('F_GETPIPE_SZ', %w(fcntl.h)) have_macro('F_SETPIPE_SZ', %w(fcntl.h)) diff --git a/ext/io_splice/io_splice_ext.c b/ext/io_splice/io_splice_ext.c index 9a838df..cad5dd1 100644 --- a/ext/io_splice/io_splice_ext.c +++ b/ext/io_splice/io_splice_ext.c @@ -79,23 +79,35 @@ static int check_fileno(VALUE io) errno = saved_errno; return fd; } -#ifndef HAVE_RB_THREAD_BLOCKING_REGION + /* partial emulation of the 1.9 rb_thread_blocking_region under 1.8 */ +#if defined(HAVE_RB_THREAD_BLOCKING_REGION) && \ + defined(HAVE_RB_THREAD_CALL_WITHOUT_GVL) +/* + * Ruby 1.9 - 2.1 (we use deprecated rb_thread_blocking_region in 2.0+ + * because we can detect (but not use) rb_thread_blocking_region in 1.9.3 + */ +typedef VALUE (*my_blocking_fn_t)(void*); +# define WITHOUT_GVL(fn,a,ubf,b) \ + rb_thread_blocking_region((my_blocking_fn_t)(fn),(a),(ubf),(b)) +#elif defined(HAVE_RB_THREAD_CALL_WITHOUT_GVL) /* Ruby 2.2+ */ +#include +# define WITHOUT_GVL(fn,a,ubf,b) \ + rb_thread_call_without_gvl((fn),(a),(ubf),(b)) +#else /* Ruby 1.8 */ # include # define RUBY_UBF_IO ((rb_unblock_function_t *)-1) typedef void rb_unblock_function_t(void *); -typedef VALUE rb_blocking_function_t(void *); -static VALUE -rb_thread_blocking_region( - rb_blocking_function_t *fn, void *data1, - rb_unblock_function_t *ubf, void *data2) +typedef void * rb_blocking_function_t(void *); +static void * WITHOUT_GVL(rb_blocking_function_t *func, void *data1, + rb_unblock_function_t *ubf, void *data2) { - VALUE rv; + void *rv; assert(RUBY_UBF_IO == ubf && "RUBY_UBF_IO required for emulation"); TRAP_BEG; - rv = fn(data1); + rv = func(data1); TRAP_END; return rv; @@ -112,10 +124,7 @@ rb_thread_blocking_region( # define RARRAY_LEN(s) (RARRAY(s)->len) #endif -static VALUE io_run(rb_blocking_function_t *fn, void *data) -{ - return rb_thread_blocking_region(fn, data, RUBY_UBF_IO, 0); -} +#define io_run(fn,data) WITHOUT_GVL((fn),(data),RUBY_UBF_IO,0) struct splice_args { int fd_in; @@ -126,14 +135,14 @@ struct splice_args { unsigned flags; }; -static VALUE nogvl_splice(void *ptr) +static void * nogvl_splice(void *ptr) { struct splice_args *a = ptr; if (a->len > MAX_AT_ONCE) a->len = MAX_AT_ONCE; - return (VALUE)splice(a->fd_in, a->off_in, a->fd_out, a->off_out, + return (void *)splice(a->fd_in, a->off_in, a->fd_out, a->off_out, a->len, a->flags); } @@ -275,14 +284,14 @@ struct tee_args { }; /* runs without GVL */ -static VALUE nogvl_tee(void *ptr) +static void * nogvl_tee(void *ptr) { struct tee_args *a = ptr; if (a->len > MAX_AT_ONCE) a->len = MAX_AT_ONCE; - return (VALUE)tee(a->fd_in, a->fd_out, a->len, a->flags); + return (void *)tee(a->fd_in, a->fd_out, a->len, a->flags); } static ssize_t do_tee(int argc, VALUE *argv, unsigned dflags) @@ -403,11 +412,11 @@ struct vmsplice_args { unsigned flags; }; -static VALUE nogvl_vmsplice(void *ptr) +static void * nogvl_vmsplice(void *ptr) { struct vmsplice_args *a = ptr; - return (VALUE)vmsplice(a->fd, a->iov, a->nr_segs, a->flags); + return (void *)vmsplice(a->fd, a->iov, a->nr_segs, a->flags); } /* this can't be a function since we use alloca() */ -- EW