1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
| | # -*- encoding: binary -*-
# :enddoc:
# A \Fiber-aware IO class, gives users the illusion of a synchronous
# interface that yields away from the current \Fiber whenever
# the underlying descriptor is blocked on reads or write
#
# It's not recommended to use any of this in your applications
# unless you're willing to accept breakage. Most of this is very
# difficult-to-use, fragile and we don't have much time to devote to
# supporting these in the future.
#
# This is a stable, legacy interface and should be preserved for all
# future versions of Rainbows! However, new apps should use
# Rainbows::Fiber::IO::Socket or Rainbows::Fiber::IO::Pipe instead
# (or better yet, avoid any of the Rainbows::Fiber* stuff).
class Rainbows::Fiber::IO
attr_accessor :to_io
# :stopdoc:
# see Rainbows::Fiber::IO::Compat for initialize implementation
class << self
alias :[] :new
end
# :startdoc:
# no longer used internally within Rainbows!, only for compatibility
def write_nonblock(buf)
@to_io.write_nonblock(buf)
end
def kgio_addr
@to_io.kgio_addr
end
# for wrapping output response bodies
def each
buf = readpartial(16384)
yield buf
yield buf while readpartial(16384, buf)
rescue EOFError
self
end
def closed?
@to_io.closed?
end
def fileno
@to_io.fileno
end
def write(buf)
case rv = Kgio.trywrite(@to_io, buf)
when String
buf = rv
when :wait_writable
kgio_wait_writable
end until nil == rv
end
# used for reading headers (respecting keepalive_timeout)
def timed_read(buf)
expire = nil
case rv = Kgio.tryread(@to_io, 16384, buf)
when :wait_readable
return if expire && expire < Time.now
expire ||= read_expire
kgio_wait_readable
else
return rv
end while true
end
def readpartial(length, buf = "")
case rv = Kgio.tryread(@to_io, length, buf)
when nil
raise EOFError, "end of file reached", []
when :wait_readable
kgio_wait_readable
else
return rv
end while true
end
def kgio_read(*args)
@to_io.kgio_read(*args)
end
def kgio_read!(*args)
@to_io.kgio_read!(*args)
end
def kgio_trywrite(*args)
@to_io.kgio_trywrite(*args)
end
autoload :Socket, 'rainbows/fiber/io/socket'
autoload :Pipe, 'rainbows/fiber/io/pipe'
end
# :stopdoc:
require 'rainbows/fiber/io/methods'
require 'rainbows/fiber/io/compat'
class Rainbows::Fiber::IO
include Rainbows::Fiber::IO::Compat
include Rainbows::Fiber::IO::Methods
alias_method :wait_readable, :kgio_wait_readable
alias_method :wait_writable, :kgio_wait_writable
end
|