From: Eric Wong Date: Tue, 10 May 2011 19:42:38 +0000 (-0700) Subject: copy_stream attempts to use IO::Splice::WAITALL X-Git-Tag: v4.0.0~6 X-Git-Url: https://repo.or.cz/w/ruby_io_splice.git/commitdiff_plain/7dd97ae08a4c6755427a4e2162d4232cfd1d8cac copy_stream attempts to use IO::Splice::WAITALL This reduces Ruby method dispatches --- 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