io_splice RubyGem user+dev discussion/patches/pulls/bugs/help
 help / color / mirror / code / Atom feed
* [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).