rev: split out deferred chunk logic from unchunked
[rainbows.git] / lib / rainbows / rev / thread.rb
blob2dbaa84b3524441ef80e5973c18c7551e4b62a5d
1 # -*- encoding: binary -*-
2 # :enddoc:
3 require 'thread'
4 require 'rainbows/rev/master'
6 RUBY_VERSION =~ %r{\A1\.8} && Rev::VERSION < "0.3.2" and
7   warn "Rev (< 0.3.2) and Threads do not mix well under Ruby 1.8"
9 module Rainbows
10   module Rev
12     class ThreadClient < Client
14       def app_call
15         KATO.delete(self)
16         disable
17         @env[RACK_INPUT] = @input
18         app_dispatch # must be implemented by subclass
19       end
21       # this is only called in the master thread
22       def response_write(response)
23         enable
24         alive = @hp.keepalive? && G.alive
25         rev_write_response(response, alive)
26         return quit unless alive
28         @env.clear
29         @hp.reset
30         @state = :headers
31         # keepalive requests are always body-less, so @input is unchanged
32         if @hp.headers(@env, @buf)
33           @input = HttpRequest::NULL_IO
34           app_call
35         else
36           KATO[self] = Time.now
37         end
38       end
40       # fails-safe application dispatch, we absolutely cannot
41       # afford to fail or raise an exception (killing the thread)
42       # here because that could cause a deadlock and we'd leak FDs
43       def app_response
44         begin
45           @env[REMOTE_ADDR] = @remote_addr
46           APP.call(@env.update(RACK_DEFAULTS))
47         rescue => e
48           Error.app(e) # we guarantee this does not raise
49           [ 500, {}, [] ]
50         end
51       end
53     end
54   end
55 end