From d0a1fcaf25b10ff1d6894d50fa981f56169195f3 Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Tue, 6 Jul 2010 02:05:01 +0000 Subject: rev: avoid unnecessary seeking when using sendfile There's no need to ever change the underlying offset of a file descriptor when using sendfile(), so don't. This allows us to avoid contention in the kernel/filesystem and eventually reuse the same filesystem file descriptor for serving multiple requests. --- lib/rainbows/rev/client.rb | 1 + lib/rainbows/rev/sendfile.rb | 17 ++++++++++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/lib/rainbows/rev/client.rb b/lib/rainbows/rev/client.rb index 68b3847..e0572bb 100644 --- a/lib/rainbows/rev/client.rb +++ b/lib/rainbows/rev/client.rb @@ -86,6 +86,7 @@ module Rainbows elsif st.file? headers.delete('Transfer-Encoding') headers['Content-Length'] ||= st.size.to_s + io = to_sendfile(io) else # char/block device, directory, whatever... nobody cares return write_response(self, response, out) end diff --git a/lib/rainbows/rev/sendfile.rb b/lib/rainbows/rev/sendfile.rb index 9ab28bd..03ce41c 100644 --- a/lib/rainbows/rev/sendfile.rb +++ b/lib/rainbows/rev/sendfile.rb @@ -1,13 +1,28 @@ # -*- encoding: binary -*- module Rainbows::Rev::Sendfile if IO.method_defined?(:sendfile_nonblock) + class F < Struct.new(:offset, :to_io) + def close + to_io.close + self.to_io = nil + end + end + + def to_sendfile(io) + F[0, io] + end + def rev_sendfile(body) - body.pos += @_io.sendfile_nonblock(body, body.pos, 0x10000) + body.offset += @_io.sendfile_nonblock(body, body.offset, 0x10000) rescue Errno::EAGAIN ensure enable_write_watcher end else + def to_sendfile(io) + io + end + def rev_sendfile(body) write(body.sysread(0x4000)) end -- cgit v1.2.3-24-ge0c7