diff options
author | Eric Wong <e@80x24.org> | 2017-03-21 02:32:27 +0000 |
---|---|---|
committer | Eric Wong <e@80x24.org> | 2017-03-21 02:45:17 +0000 |
commit | 73769bc0bc309382689707595f57388ea5e5c737 (patch) | |
tree | a2dd4ae86edd2201d8d57d704ba0b0a0dec2613d /lib | |
parent | 20c66dbf1ebd0ca993e7a79c9d0d833d747df358 (diff) | |
download | unicorn-73769bc0bc309382689707595f57388ea5e5c737.tar.gz |
raindrops 0.18+ will have Raindrops::TCP state hash for portable mapping of TCP states to their respective numeric values. This was necessary because TCP state numbers (and even macro names) differ between FreeBSD and Linux (and possibly other OSes). Favor using the Raindrops::TCP state hash if available, but fall back to the hard-coded values since older versions of raindrops did not support TCP_INFO on non-Linux systems. While we're in the area, favor "const_defined?" over "defined?" to reduce the inline constant cache footprint for branches which are only evaluated once. Patches to implement Raindrops::TCP for FreeBSD are available at: https://bogomips.org/raindrops-public/20170316031652.17433-1-e@80x24.org/T/
Diffstat (limited to 'lib')
-rw-r--r-- | lib/unicorn/http_request.rb | 38 |
1 files changed, 29 insertions, 9 deletions
diff --git a/lib/unicorn/http_request.rb b/lib/unicorn/http_request.rb index 9010007..7253497 100644 --- a/lib/unicorn/http_request.rb +++ b/lib/unicorn/http_request.rb @@ -105,7 +105,7 @@ class Unicorn::HttpParser env.include?('rack.hijack_io'.freeze) end - if defined?(Raindrops::TCP_Info) + if Raindrops.const_defined?(:TCP_Info) TCPI = Raindrops::TCP_Info.allocate def check_client_connection(socket) # :nodoc: @@ -118,14 +118,34 @@ class Unicorn::HttpParser end end - def closed_state?(state) # :nodoc: - case state - when 1 # ESTABLISHED - false - when 8, 6, 7, 9, 11 # CLOSE_WAIT, TIME_WAIT, CLOSE, LAST_ACK, CLOSING - true - else - false + if Raindrops.const_defined?(:TCP) + # raindrops 0.18.0+ supports FreeBSD + Linux using the same names + # Evaluate these hash lookups at load time so we can + # generate an opt_case_dispatch instruction + eval <<-EOS + def closed_state?(state) # :nodoc: + case state + when #{Raindrops::TCP[:ESTABLISHED]} + false + when #{Raindrops::TCP.values_at( + :CLOSE_WAIT, :TIME_WAIT, :CLOSE, :LAST_ACK, :CLOSING).join(',')} + true + else + false + end + end + EOS + else + # raindrops before 0.18 only supported TCP_INFO under Linux + def closed_state?(state) # :nodoc: + case state + when 1 # ESTABLISHED + false + when 8, 6, 7, 9, 11 # CLOSE_WAIT, TIME_WAIT, CLOSE, LAST_ACK, CLOSING + true + else + false + end end end else |