From: Eric Wong <normalperson@yhbt.net>
To: ruby.io.splice@librelist.org
Subject: [PATCH] prepare for rb_thread_blocking_region removal
Date: Sun, 9 Feb 2014 00:51:02 +0000 [thread overview]
Message-ID: <20140209005102.GA4222@dcvr.yhbt.net> (raw)
In-Reply-To: <20140209005102.GA4222@dcvr.yhbt.net>
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 <ruby/thread.h>
+# define WITHOUT_GVL(fn,a,ubf,b) \
+ rb_thread_call_without_gvl((fn),(a),(ubf),(b))
+#else /* Ruby 1.8 */
# include <rubysig.h>
# 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
next parent reply other threads:[~2014-02-09 0:51 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-02-09 0:51 Eric Wong [this message]
2014-02-09 7:29 ` [PUSHED] remove copy_stream tests and references Eric Wong
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://yhbt.net/ruby_io_splice/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20140209005102.GA4222@dcvr.yhbt.net \
--to=normalperson@yhbt.net \
--cc=ruby.io.splice@librelist.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://yhbt.net/ruby_io_splice.git/
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).