1 # -*- encoding: binary -*-
3 module Rainbows::Revactor::Body
4 # TODO non-blocking splice(2) under Linux
6 :write_body_stream => :write_body_each
9 if IO.method_defined?(:sendfile_nonblock)
10 def write_body_file_sendfile_revactor(client, body, range)
11 body = body_to_io(body)
12 sock = client.instance_variable_get(:@_io)
13 pfx = Revactor::TCP::Socket === client ? :tcp : :unix
14 write_complete = T[:"#{pfx}_write_complete", client]
15 closed = T[:"#{pfx}_closed", client]
16 offset, count = range ? range : [ 0, body.stat.size ]
18 offset += (n = sock.sendfile_nonblock(body, offset, count))
20 # The @_write_buffer is empty at this point, trigger the
21 # on_readable method which in turn triggers on_write_complete
22 # even though nothing was written
23 client.controller = Actor.current
24 client.__send__(:enable_write_watcher)
25 Actor.receive do |filter|
26 filter.when(write_complete) {}
27 filter.when(closed) { raise Errno::EPIPE }
32 end while (count -= n) > 0
34 close_if_private(body)
36 ALIASES[:write_body_file] = :write_body_file_sendfile_revactor
38 ALIASES[:write_body] = :write_body_each
41 def self.included(klass)
42 ALIASES.each do |new_method, orig_method|
43 klass.__send__(:alias_method, new_method, orig_method)