1 # -*- encoding: binary -*-
5 # A partially complete IO wrapper, this exports an IO.select()-able
6 # #to_io method and gives users the illusion of a synchronous
7 # interface that yields away from the current Fiber whenever
8 # the underlying IO object cannot read or write
10 # TODO: subclass off IO and include Kgio::SocketMethods instead
11 class IO < Struct.new(:to_io, :f)
13 LOCALHOST = Kgio::LOCALHOST
15 # needed to write errors with
16 def write_nonblock(buf)
17 to_io.write_nonblock(buf)
24 # for wrapping output response bodies
26 if buf = readpartial(16384)
28 yield buf while readpartial(16384, buf)
36 RD[fileno] = WR[fileno] = nil
37 to_io.close unless to_io.closed?
60 case rv = to_io.kgio_trywrite(buf)
65 when Kgio::WaitWritable
71 # used for reading headers (respecting keepalive_timeout)
75 to_io.read_nonblock(16384)
77 return if expire && expire < Time.now
78 expire ||= Time.now + G.kato
84 def readpartial(length, buf = "")
85 if to_io.respond_to?(:kgio_tryread)
86 # TODO: use kgio_read!
88 rv = to_io.kgio_tryread(length, buf)
91 raise EOFError, "end of file reached", []
92 when Kgio::WaitReadable
100 to_io.read_nonblock(length, buf)
109 to_io.kgio_read(*args)
112 def kgio_read!(*args)
113 to_io.kgio_read!(*args)