* [PATCH] prepare for rb_thread_blocking_region removal
@ 2014-02-09 0:51 Eric Wong
2014-02-09 7:29 ` [PUSHED] remove copy_stream tests and references Eric Wong
0 siblings, 1 reply; 2+ messages in thread
From: Eric Wong @ 2014-02-09 0:51 UTC (permalink / raw)
To: ruby.io.splice
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
^ permalink raw reply related [flat|nested] 2+ messages in thread
* [PUSHED] remove copy_stream tests and references
2014-02-09 0:51 [PATCH] prepare for rb_thread_blocking_region removal Eric Wong
@ 2014-02-09 7:29 ` Eric Wong
0 siblings, 0 replies; 2+ messages in thread
From: Eric Wong @ 2014-02-09 7:29 UTC (permalink / raw)
To: ruby.io.splice
It is deprecated, so stop testing and advertising it.
---
README | 4 +-
examples/splice-cp.rb | 14 +-
io_splice.gemspec | 1 -
test/test_copy_stream.rb | 340 ------------------------------------------
test/test_io_splice.rb | 124 ---------------
test/test_rack_file_compat.rb | 31 ----
test/test_tcp_splice.rb | 66 --------
7 files changed, 4 insertions(+), 576 deletions(-)
delete mode 100644 test/test_copy_stream.rb
delete mode 100644 test/test_rack_file_compat.rb
delete mode 100644 test/test_tcp_splice.rb
(abbreviated diff, since the rest is all deletions)
diff --git a/README b/README
index 6300ac6..5245cb1 100644
--- a/README
+++ b/README
@@ -14,11 +14,9 @@ buffer.
arbitrary file descriptors (assuming kernel support), not just
file-to-socket (or file-to-anything in newer Linux).
-* Thread-safe blocking operations under Ruby 1.9, releases GVL
+* Thread-safe blocking operations under Ruby 1.9+, releases GVL
if blocking operations are used.
-* Almost drop-in replacement for IO.copy_stream: IO::Splice.copy_stream
-
* Safely usable with non-blocking I/O frameworks (unlike IO.copy_stream)
when combined with the IO::Splice::F_NONBLOCK flag.
diff --git a/examples/splice-cp.rb b/examples/splice-cp.rb
index bf0d518..8141e51 100755
--- a/examples/splice-cp.rb
+++ b/examples/splice-cp.rb
@@ -1,13 +1,5 @@
#!/usr/bin/env ruby
# -*- encoding: binary -*-
-
-# Example of using IO.splice to copy a file
-# This can be significantly faster than IO.copy_stream as data
-# is never copied into userspace.
-
-require 'io/splice'
-
-usage = "#$0 SOURCE DEST"
-source = ARGV.shift or abort usage
-dest = ARGV.shift or abort usage
-IO::Splice.copy_stream(source, dest)
+# This example is no longer valid, IO.copy_stream is faster in Ruby 2.2+
+# since it uses sendfile directly, which now allows direct file-to-file
+# copying (on Linux only) with fewer syscalls than splice.
^ permalink raw reply related [flat|nested] 2+ messages in thread
end of thread, other threads:[~2014-02-09 7:30 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-02-09 0:51 [PATCH] prepare for rb_thread_blocking_region removal Eric Wong
2014-02-09 7:29 ` [PUSHED] remove copy_stream tests and references Eric Wong
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).