From 73769bc0bc309382689707595f57388ea5e5c737 Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Tue, 21 Mar 2017 02:32:27 +0000 Subject: http_request: support proposed Raindrops::TCP states on non-Linux 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/ --- lib/unicorn/http_request.rb | 38 +++++++++++++++++++++++++++++--------- 1 file changed, 29 insertions(+), 9 deletions(-) (limited to 'lib/unicorn') 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 -- cgit v1.2.3-24-ge0c7