about summary refs log tree commit homepage
diff options
context:
space:
mode:
authorEric Wong <normalperson@yhbt.net>2011-05-10 12:42:38 -0700
committerEric Wong <normalperson@yhbt.net>2011-05-10 12:42:38 -0700
commit7dd97ae08a4c6755427a4e2162d4232cfd1d8cac (patch)
treef4ecb008a8ba96b0a24bed50ce48f91e10b5acb5
parentb8b2d02b56e29466a0437b4bb8e8e0608a933f89 (diff)
downloadruby_io_splice-7dd97ae08a4c6755427a4e2162d4232cfd1d8cac.tar.gz
This reduces Ruby method dispatches
-rw-r--r--lib/io/splice.rb55
1 files changed, 20 insertions, 35 deletions
diff --git a/lib/io/splice.rb b/lib/io/splice.rb
index 4ec44e4..0802c3b 100644
--- a/lib/io/splice.rb
+++ b/lib/io/splice.rb
@@ -1,5 +1,6 @@
 # -*- encoding: binary -*-
 require 'io_splice_ext'
+require 'io/wait'
 
 module IO::Splice
 
@@ -39,14 +40,13 @@ module IO::Splice
     dst.kind_of?(String) and close << (dst = File.open(dst, "w"))
     src, dst = src.to_io, dst.to_io
     rv = len
-    select_args = selectable(src, dst)
 
     if src.stat.pipe? || dst.stat.pipe?
       if len
-        len -= full(src, dst, len, src_offset, select_args) until len == 0
+        len -= full(src, dst, len, src_offset) until len == 0
       else
         rv = 0
-        while n = partial(src, dst, PIPE_CAPA, src_offset, select_args)
+        while n = partial(src, dst, PIPE_CAPA, src_offset)
           rv += n
         end
       end
@@ -54,13 +54,13 @@ module IO::Splice
       r, w = tmp = IO.pipe
       close.concat(tmp)
       if len
-        while len != 0 && n = partial(src, w, len, src_offset, select_args)
-          len -= full(r, dst, n, nil, select_args)
+        while len != 0 && n = partial(src, w, len, src_offset)
+          len -= full(r, dst, n, nil)
         end
       else
         rv = 0
-        while n = partial(src, w, PIPE_CAPA, src_offset, select_args)
-          rv += full(r, dst, n, nil, select_args)
+        while n = partial(src, w, PIPE_CAPA, src_offset)
+          rv += full(r, dst, n, nil)
         end
       end
     end
@@ -76,17 +76,8 @@ module IO::Splice
   # This will block and wait for IO completion of +len+
   # Raises +EOFError+ if end of file is reached.
   # bytes.  Returns the number of bytes actually spliced (always +len+)
-  # The +_select_args+ parameter is reserved for internal use and
-  # may be removed in future versions.  Do not write code that
-  # depends on +_select_args+.
-  def self.full(src, dst, len, src_offset, _select_args = selectable(src, dst))
-    nr = len
-    while nr > 0
-      n = partial(src, dst, nr, src_offset, _select_args) or
-                                     raise EOFError, "end of file reached"
-      nr -= n
-    end
-    len
+  def self.full(src, dst, len, src_offset)
+    IO.splice(src, src_offset, dst, nil, len, F_MOVE | WAITALL)
   end
 
   # splice up to +len+ bytes from +src+ to +dst+.
@@ -94,22 +85,16 @@ module IO::Splice
   # may BOTH be pipes in Linux 2.6.31 or later.
   # Returns the number of bytes actually spliced.
   # Like IO#readpartial, this never returns Errno::EAGAIN
-  # The +_select_args+ parameter is reserved for internal use and
-  # may be removed in future versions.  Do not write code that
-  # depends on +_select_args+.
-  def self.partial(src, dst, len, src_offset,
-                   _select_args = selectable(src, dst))
-    begin
-      rv = IO.trysplice(src, src_offset, dst, nil, len, F_MOVE)
-    end while rv == :EAGAIN and IO.select(*_select_args)
-    rv
-  end
-
-  # returns an array suitable for splat-ing to IO.select for blocking I/O
-  def self.selectable(src, dst) # :nodoc:
-    rv = []
-    src.stat.pipe? or rv[0] = [ src ]
-    dst.stat.pipe? or rv[1] = [ dst ]
-    rv
+  def self.partial(src, dst, len, src_offset)
+    IO.splice(src, src_offset, dst, nil, len, F_MOVE)
+    rescue EOFError
+      nil
+    rescue Errno::EAGAIN
+      begin
+        src.to_io.wait
+        IO.select(nil, [dst])
+        rv = IO.trysplice(src, src_offset, dst, nil, len, F_MOVE)
+      end while rv == :EAGAIN
+      rv
   end
 end