Permalink
Browse files

Deal with unsupported sockopts. Fixes #1241

Seems that the ability to extract the TCP_INFO is a conditional
capability, with it failing in some common situations. So if it works,
great, but as soon as it stops working, disable it entirely.
1 parent 5bac8d5 commit 604885b1fe2b4d2be0658c78914ebf16c13fb173 @evanphx evanphx committed Mar 14, 2017
Showing with 14 additions and 4 deletions.
  1. +14 −4 lib/puma/server.rb
View
@@ -78,6 +78,8 @@ def initialize(app, events=Events.stdio, options={})
ENV['RACK_ENV'] ||= "development"
@mode = :http
+
+ @precheck_closing = true
end
attr_accessor :binder, :leak_stack_on_error
@@ -121,10 +123,18 @@ def uncork_socket(socket)
def closed_socket?(socket)
return false unless socket.kind_of? TCPSocket
- tcp_info = socket.getsockopt(Socket::SOL_TCP, Socket::TCP_INFO)
- state = tcp_info.unpack(UNPACK_TCP_STATE_FROM_TCP_INFO)[0]
- # TIME_WAIT: 6, CLOSE: 7, CLOSE_WAIT: 8, LAST_ACK: 9, CLOSING: 11
- (state >= 6 && state <= 9) || state == 11
+ return false unless @precheck_closing
+
+ begin
+ tcp_info = socket.getsockopt(Socket::SOL_TCP, Socket::TCP_INFO)
+ rescue IOError, SystemCallError
+ @precheck_closing = false
+ false
+ else
+ state = tcp_info.unpack(UNPACK_TCP_STATE_FROM_TCP_INFO)[0]
+ # TIME_WAIT: 6, CLOSE: 7, CLOSE_WAIT: 8, LAST_ACK: 9, CLOSING: 11
+ (state >= 6 && state <= 9) || state == 11
+ end
end
else
def cork_socket(socket)

0 comments on commit 604885b

Please sign in to comment.