about summary refs log tree commit homepage
diff options
context:
space:
mode:
authorEric Wong <normalperson@yhbt.net>2014-02-09 07:26:52 +0000
committerEric Wong <normalperson@yhbt.net>2014-02-09 07:26:52 +0000
commit66d8ad006ff1ca1ede0b0e1988d6a25a67321ae4 (patch)
tree7b682bd38f728934a3a6125da918cd246c2ace76
parentc54c38a95572cc1bf9d6a02fdc18500878968932 (diff)
downloadruby_io_splice-66d8ad006ff1ca1ede0b0e1988d6a25a67321ae4.tar.gz
It is deprecated, so stop testing and advertising it.
-rw-r--r--README4
-rwxr-xr-xexamples/splice-cp.rb14
-rw-r--r--io_splice.gemspec1
-rw-r--r--test/test_copy_stream.rb340
-rw-r--r--test/test_io_splice.rb124
-rw-r--r--test/test_rack_file_compat.rb31
-rw-r--r--test/test_tcp_splice.rb66
7 files changed, 4 insertions, 576 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.
diff --git a/io_splice.gemspec b/io_splice.gemspec
index bc3c477..a914029 100644
--- a/io_splice.gemspec
+++ b/io_splice.gemspec
@@ -21,7 +21,6 @@ Gem::Specification.new do |s|
   s.rubyforge_project = %q{qrp}
   s.test_files = Dir['test/test_*.rb']
   s.add_development_dependency('wrongdoc', '~> 1.5')
-  s.add_development_dependency('rack', '~> 1.2')
 
   # s.licenses = %w(LGPL) # accessor not compatible with older RubyGems
 end
diff --git a/test/test_copy_stream.rb b/test/test_copy_stream.rb
deleted file mode 100644
index 71d7cae..0000000
--- a/test/test_copy_stream.rb
+++ /dev/null
@@ -1,340 +0,0 @@
-require 'test/unit'
-require 'tmpdir'
-require "fcntl"
-require 'io/nonblock'
-require 'socket'
-require 'timeout'
-require 'tempfile'
-require 'io/splice'
-
-class TestIOCopyStreamCompat < Test::Unit::TestCase
-  def have_nonblock?
-    IO.method_defined?("nonblock=")
-  end
-
-  def pipe(wp, rp)
-    re, we = nil, nil
-    r, w = IO.pipe
-    rt = Thread.new do
-      begin
-        rp.call(r)
-      rescue Exception
-        r.close
-        re = $!
-      end
-    end
-    wt = Thread.new do
-      begin
-        wp.call(w)
-      rescue Exception
-        w.close
-        we = $!
-      end
-    end
-    flunk("timeout") unless wt.join(10) && rt.join(10)
-  ensure
-    w.close unless !w || w.closed?
-    r.close unless !r || r.closed?
-    (wt.kill; wt.join) if wt
-    (rt.kill; rt.join) if rt
-    raise we if we
-    raise re if re
-  end
-
-  def with_pipe
-    r, w = IO.pipe
-    begin
-      yield r, w
-    ensure
-      r.close unless r.closed?
-      w.close unless w.closed?
-    end
-  end
-
-  def with_read_pipe(content)
-    pipe(proc do |w|
-      w << content
-      w.close
-    end, proc do |r|
-      yield r
-    end)
-  end
-
-  def mkcdtmpdir
-    Dir.mktmpdir {|d|
-      Dir.chdir(d) {
-        yield
-      }
-    }
-  end
-
-  def trapping_usr1
-    @usr1_rcvd  = 0
-    trap(:USR1) { @usr1_rcvd += 1 }
-    yield
-    ensure
-      trap(:USR1, "DEFAULT")
-  end
-
-  def test_copy_stream
-    mkcdtmpdir {
-      content = "foobar"
-      File.open("src", "w") {|f| f << content }
-      ret = IO::Splice.copy_stream("src", "dst")
-      assert_equal(content.bytesize, ret)
-      assert_equal(content, File.read("dst"))
-
-      # overwrite by smaller file.
-      content = "baz"
-      File.open("src", "w") {|f| f << content }
-      ret = IO::Splice.copy_stream("src", "dst")
-      assert_equal(content.bytesize, ret)
-      assert_equal(content, File.read("dst"))
-
-      ret = IO::Splice.copy_stream("src", "dst", 2)
-      assert_equal(2, ret)
-      assert_equal(content[0,2], File.read("dst"))
-
-      ret = IO::Splice.copy_stream("src", "dst", 0)
-      assert_equal(0, ret)
-      assert_equal("", File.read("dst"))
-
-      ret = IO::Splice.copy_stream("src", "dst", nil, 1)
-      assert_equal(content.bytesize-1, ret)
-      assert_equal(content[1..-1], File.read("dst"))
-
-      assert_raise(Errno::ENOENT) {
-        IO::Splice.copy_stream("nodir/foo", "dst")
-      }
-
-      assert_raise(Errno::ENOENT) {
-        IO::Splice.copy_stream("src", "nodir/bar")
-      }
-
-      pipe(proc do |w|
-        ret = IO::Splice.copy_stream("src", w)
-        assert_equal(content.bytesize, ret)
-        w.close
-      end, proc do |r|
-        assert_equal(content, r.read)
-      end)
-
-      with_pipe {|r, w|
-        w.close
-        assert_raise(IOError) { IO::Splice.copy_stream("src", w) }
-      }
-
-      pipe_content = "abc"
-      with_read_pipe(pipe_content) {|r|
-        ret = IO::Splice.copy_stream(r, "dst")
-        assert_equal(pipe_content.bytesize, ret)
-        assert_equal(pipe_content, File.read("dst"))
-      }
-
-      pipe(proc do |w|
-        ret = IO::Splice.copy_stream("src", w, 1, 1)
-        assert_equal(1, ret)
-        w.close
-      end, proc do |r|
-        assert_equal(content[1,1], r.read)
-      end)
-
-      bigcontent = "abc" * 123456
-      File.open("bigsrc", "w") {|f| f << bigcontent }
-      ret = IO::Splice.copy_stream("bigsrc", "bigdst")
-      assert_equal(bigcontent.bytesize, ret)
-      assert_equal(bigcontent, File.read("bigdst"))
-
-      File.unlink("bigdst")
-      ret = IO::Splice.copy_stream("bigsrc", "bigdst", nil, 100)
-      assert_equal(bigcontent.bytesize-100, ret)
-      assert_equal(bigcontent[100..-1], File.read("bigdst"))
-
-      File.unlink("bigdst")
-      ret = IO::Splice.copy_stream("bigsrc", "bigdst", 30000, 100)
-      assert_equal(30000, ret)
-      assert_equal(bigcontent[100, 30000], File.read("bigdst"))
-
-      File.open("bigsrc") {|f|
-        begin
-          assert_equal(0, f.pos)
-          ret = IO::Splice.copy_stream(f, "bigdst", nil, 10)
-          assert_equal(bigcontent.bytesize-10, ret)
-          assert_equal(bigcontent[10..-1], File.read("bigdst"))
-          assert_equal(0, f.pos)
-          ret = IO::Splice.copy_stream(f, "bigdst", 40, 30)
-          assert_equal(40, ret)
-          assert_equal(bigcontent[30, 40], File.read("bigdst"))
-          assert_equal(0, f.pos)
-        rescue NotImplementedError
-          #skip "pread(2) is not implemtented."
-        end
-      }
-
-      with_pipe {|r, w|
-        w.close
-        assert_raise(IOError) { IO::Splice.copy_stream("src", w) }
-      }
-
-      megacontent = "abc" * 1234567
-      File.open("megasrc", "w") {|f| f << megacontent }
-
-      if have_nonblock?
-        with_pipe {|r1, w1|
-          with_pipe {|r2, w2|
-            begin
-              r1.nonblock = true
-              w2.nonblock = true
-            rescue Errno::EBADF
-              skip "nonblocking IO for pipe is not implemented"
-            end
-            t1 = Thread.new { w1 << megacontent; w1.close }
-            t2 = Thread.new { r2.read }
-            ret = IO::Splice.copy_stream(r1, w2)
-            assert_equal(megacontent.bytesize, ret)
-            w2.close
-            t1.join
-            assert_equal(megacontent, t2.value)
-          }
-        }
-      end
-
-      with_pipe {|r1, w1|
-        with_pipe {|r2, w2|
-          t1 = Thread.new { w1 << megacontent; w1.close }
-          t2 = Thread.new { r2.read }
-          ret = IO::Splice.copy_stream(r1, w2)
-          assert_equal(megacontent.bytesize, ret)
-          w2.close
-          t1.join
-          assert_equal(megacontent, t2.value)
-        }
-      }
-
-      with_pipe {|r, w|
-        t = Thread.new { r.read }
-        ret = IO::Splice.copy_stream("megasrc", w)
-        assert_equal(megacontent.bytesize, ret)
-        w.close
-        assert_equal(megacontent, t.value)
-      }
-    }
-  end
-
-  def with_socketpair
-    s1, s2 = UNIXSocket.pair
-    begin
-      yield s1, s2
-    ensure
-      s1.close unless s1.closed?
-      s2.close unless s2.closed?
-    end
-  end
-
-  def test_copy_stream_socket
-    mkcdtmpdir {
-
-      content = "foobar"
-      File.open("src", "w") {|f| f << content }
-
-      with_socketpair {|s1, s2|
-        ret = IO::Splice.copy_stream("src", s1)
-        assert_equal(content.bytesize, ret)
-        s1.close
-        assert_equal(content, s2.read)
-      }
-
-      bigcontent = "abc" * 123456
-      File.open("bigsrc", "w") {|f| f << bigcontent }
-
-      with_socketpair {|s1, s2|
-        t = Thread.new { s2.read }
-        ret = IO::Splice.copy_stream("bigsrc", s1)
-        assert_equal(bigcontent.bytesize, ret)
-        s1.close
-        result = t.value
-        assert_equal(bigcontent, result)
-      }
-
-      with_socketpair {|s1, s2|
-        t = Thread.new { s2.read }
-        ret = IO::Splice.copy_stream("bigsrc", s1, 10000)
-        assert_equal(10000, ret)
-        s1.close
-        result = t.value
-        assert_equal(bigcontent[0,10000], result)
-      }
-
-      File.open("bigsrc") {|f|
-        assert_equal(0, f.pos)
-        with_socketpair {|s1, s2|
-          t = Thread.new { s2.read }
-          ret = IO::Splice.copy_stream(f, s1, nil, 100)
-          assert_equal(bigcontent.bytesize-100, ret)
-          assert_equal(0, f.pos)
-          s1.close
-          result = t.value
-          assert_equal(bigcontent[100..-1], result)
-        }
-      }
-
-      File.open("bigsrc") {|f|
-        assert_equal(bigcontent[0,100], f.sysread(100))
-        assert_equal(100, f.pos)
-        with_socketpair {|s1, s2|
-          t = Thread.new { s2.read }
-          ret = IO::Splice.copy_stream(f, s1)
-          assert_equal(bigcontent.bytesize-100, ret)
-          assert_equal(bigcontent.length, f.sysseek(0, IO::SEEK_CUR))
-          s1.close
-          result = t.value
-          assert_equal(bigcontent[100..-1], result)
-        }
-      }
-
-      megacontent = "abc" * 1234567
-      File.open("megasrc", "w") {|f| f << megacontent }
-
-      if have_nonblock?
-        with_socketpair {|s1, s2|
-          begin
-            s1.nonblock = true
-          rescue Errno::EBADF
-            skip "nonblocking IO for pipe is not implemented"
-          end
-          t = Thread.new { s2.read }
-          ret = IO::Splice.copy_stream("megasrc", s1)
-          assert_equal(megacontent.bytesize, ret)
-          s1.close
-          result = t.value
-          assert_equal(megacontent, result)
-        }
-        with_socketpair {|s1, s2|
-          begin
-            s1.nonblock = true
-          rescue Errno::EBADF
-            skip "nonblocking IO for pipe is not implemented"
-          end
-          trapping_usr1 do
-            nr = 10
-            pid = fork do
-              s1.close
-              IO.select([s2])
-              Process.kill(:USR1, Process.ppid)
-              s2.read
-            end
-            s2.close
-            nr.times do
-              assert_equal megacontent.bytesize,
-                          IO::Splice.copy_stream("megasrc", s1)
-            end
-            assert_equal(1, @usr1_rcvd)
-            s1.close
-            _, status = Process.waitpid2(pid)
-            assert status.success?, status.inspect
-          end
-        }
-      end
-    }
-  end
-end
diff --git a/test/test_io_splice.rb b/test/test_io_splice.rb
index 26f2e00..ba66a61 100644
--- a/test/test_io_splice.rb
+++ b/test/test_io_splice.rb
@@ -332,130 +332,6 @@ class Test_IO_Splice < Test::Unit::TestCase
     assert IO::Splice::PIPE_CAPA >= IO::Splice::PIPE_BUF
   end
 
-  def test_splice_copy_stream_file_to_file_small
-    a, b = Tempfile.new('a'), Tempfile.new('b')
-    a.syswrite 'hello world'
-    a.sysseek(0)
-    IO::Splice.copy_stream(a, b)
-    b.rewind
-    assert_equal 'hello world', b.read
-  end
-
-  def test_splice_copy_stream_file_to_file_big
-    buf = ('ab' * IO::Splice::PIPE_CAPA) + 'hi'
-    a, b = Tempfile.new('a'), Tempfile.new('b')
-    a.syswrite buf
-    a.sysseek(0)
-    IO::Splice.copy_stream(a, b)
-    b.rewind
-    assert_equal buf, b.read
-  end
-
-  def test_splice_copy_stream_file_to_file_big_partial
-    nr = IO::Splice::PIPE_CAPA
-    buf = ('ab' * nr) + 'hi'
-    a, b = Tempfile.new('a'), Tempfile.new('b')
-    a.syswrite buf
-    a.sysseek(0)
-    assert_equal nr, IO::Splice.copy_stream(a, b, nr)
-    b.rewind
-    assert_equal('ab' * (nr/2), b.read)
-  end
-
-  def test_splice_copy_stream_file_to_file_len
-    a, b = Tempfile.new('a'), Tempfile.new('b')
-    a.syswrite 'hello world'
-    a.sysseek(0)
-    IO::Splice.copy_stream(a, b, 5)
-    b.rewind
-    assert_equal 'hello', b.read
-  end
-
-  def test_splice_copy_stream_pipe_to_file_len
-    a = Tempfile.new('a')
-    r, w = IO.pipe
-    w.syswrite 'hello world'
-    IO::Splice.copy_stream(r, a, 5)
-    a.rewind
-    assert_equal 'hello', a.read
-  end
-
-  def test_splice_copy_stream_paths
-    a = Tempfile.new('a')
-    b = Tempfile.new('a')
-    a.syswrite('hello world')
-    IO::Splice.copy_stream(a.path, b.path, 5)
-    assert_equal 'hello', b.read
-  end
-
-  def test_splice_copy_stream_src_offset
-    a = Tempfile.new('a')
-    b = Tempfile.new('a')
-    a.syswrite('hello world')
-    IO::Splice.copy_stream(a.path, b.path, 5, 6)
-    assert_equal 'world', b.read
-  end
-
-  def test_splice_copy_stream_src_offset_unchanged
-    a = Tempfile.new('a')
-    b = Tempfile.new('a')
-    a.syswrite('hello world')
-    assert_equal 0, a.sysseek(0, IO::SEEK_SET)
-    IO::Splice.copy_stream(a, b.path, 5, 6)
-    assert_equal 'world', b.read
-    assert_equal 0, a.sysseek(0, IO::SEEK_CUR)
-  end
-
-  def test_copy_stream_nonblock_src
-    server = TCPServer.new('127.0.0.1', 0)
-    port = server.addr[1]
-    rp, wp = IO.pipe
-    rs = TCPSocket.new('127.0.0.1', port)
-    rs.nonblock = true
-    nr = 0
-    assert_raises(Timeout::Error) do
-      timeout(0.05) { nr += IO::Splice.copy_stream(rs, wp, 5) }
-    end
-    assert_equal 0, nr
-    rs.close
-    server.close
-  end if mri?
-
-  def test_copy_stream_nonblock_dst
-    server = TCPServer.new('127.0.0.1', 0)
-    port = server.addr[1]
-    rp, wp = IO.pipe
-    rs = TCPSocket.new('127.0.0.1', port)
-    rs.nonblock = true
-    client = server.accept
-    buf = ' ' * IO::Splice::PIPE_CAPA
-    nr = 0
-    assert_raises(Timeout::Error) do
-      loop do
-        begin
-          wp.write_nonblock(buf)
-        rescue Errno::EAGAIN
-        end
-        timeout(0.05) do
-          nr += IO::Splice.copy_stream(rp, rs, IO::Splice::PIPE_CAPA)
-        end
-      end
-    end
-    assert_equal nr, client.read(nr).size
-    rs.close
-    server.close
-  end if mri?
-
-  def test_copy_stream_eof
-    r, w = IO.pipe
-    w.syswrite 'hello world'
-    w.close
-    a = Tempfile.new('a')
-    assert_equal 11, IO::Splice.copy_stream(r, a)
-    a.rewind
-    assert_equal 'hello world', a.read
-  end
-
   def test_pipe_size
     r, w = IO.pipe
     assert_kind_of Integer, r.pipe_size
diff --git a/test/test_rack_file_compat.rb b/test/test_rack_file_compat.rb
deleted file mode 100644
index 5505262..0000000
--- a/test/test_rack_file_compat.rb
+++ /dev/null
@@ -1,31 +0,0 @@
-# -*- encoding: binary -*-
-require "rack"
-require "test/unit"
-require "socket"
-require "io/splice"
-
-class TestRackFileCompat < Test::Unit::TestCase
-  def setup
-    @app = Rack::File.new(File.dirname(__FILE__))
-    @req = Rack::MockRequest.new(@app)
-    @base_file = File.basename(__FILE__)
-    @r, @w = UNIXSocket.pair
-  end
-
-  def teardown
-    [ @r, @w ].each { |io| io.closed? or io.close }
-  end
-
-  def test_get_rack_file
-    env = Rack::MockRequest.env_for "http://example.com/#@base_file"
-    status, headers, body = @app.call(env)
-    assert_equal 200, status.to_i
-    headers.each { |k,v|
-      assert_instance_of String, k.to_str
-      assert_instance_of String, v.to_str
-    }
-    thr = Thread.new { @r.read(File.size(__FILE__)) }
-    assert_equal File.size(__FILE__), IO::Splice.copy_stream(body, @w)
-    assert_equal File.read(__FILE__), thr.value
-  end
-end if IO.respond_to?(:copy_stream)
diff --git a/test/test_tcp_splice.rb b/test/test_tcp_splice.rb
deleted file mode 100644
index 686333c..0000000
--- a/test/test_tcp_splice.rb
+++ /dev/null
@@ -1,66 +0,0 @@
-require 'socket'
-require 'io/wait'
-require 'io/splice'
-require 'io/nonblock'
-require "test/unit"
-
-class TestTCPCopyStream < Test::Unit::TestCase
-  def setup
-    host = ENV["TEST_HOST"] || "127.0.0.1"
-    @srv = TCPServer.new(host, 0)
-    @port = @srv.addr[1]
-    @client = TCPSocket.new(host, @port)
-    @client.setsockopt Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1
-    @accept = @srv.accept
-    @accept.setsockopt Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1
-    @client.sync = @accept.sync = true
-    @r, @w = IO.pipe
-  end
-
-  def teardown
-    @srv.close
-    [ @client, @accept, @r, @w ].each { |io| io.close unless io.closed? }
-  end
-
-  def test_client_to_server_eof
-    nr = 2000
-    buf = '0123456789abcdef' * 1024
-    expect = buf.size * nr
-    thr = Thread.new do
-      nr.times { @client.write(buf) }
-      @client.close
-    end
-    sleep 1 # wait for rcvbuf to fill up
-    bytes = IO::Splice.copy_stream(@accept, "/dev/null")
-    assert_equal expect, bytes
-  end
-
-  def test_client_to_server_expect
-    nr = 2000
-    buf = '0123456789abcdef' * 1024
-    expect = buf.size * nr
-    thr = Thread.new do
-      nr.times { @client.write(buf) }
-    end
-    sleep 1 # wait for rcvbuf to fill up
-    bytes = IO::Splice.copy_stream(@accept, "/dev/null", expect)
-    assert_equal expect, bytes
-  end
-
-  def test_mega_splice
-    nr = 2000
-    buf = '0123456789abcdef' * 1024
-    expect = buf.size * nr
-    thr = Thread.new do
-      nr.times { @client.write(buf) }
-      @client.close
-    end
-    size_t_max = if (1 << 30).kind_of?(Bignum)
-      0xffffffff
-    else
-      0xffffffffffffffff
-    end
-    bytes = IO::Splice.copy_stream(@accept, "/dev/null", size_t_max)
-    assert_equal expect, bytes
-  end
-end