diff options
Diffstat (limited to 'lib/unicorn/socket_helper.rb')
-rw-r--r-- | lib/unicorn/socket_helper.rb | 23 |
1 files changed, 19 insertions, 4 deletions
diff --git a/lib/unicorn/socket_helper.rb b/lib/unicorn/socket_helper.rb index df8315e..f52dde2 100644 --- a/lib/unicorn/socket_helper.rb +++ b/lib/unicorn/socket_helper.rb @@ -3,6 +3,18 @@ require 'socket' module Unicorn + + # Instead of using a generic Kgio::Socket for everything, + # tag TCP sockets so we can use TCP_INFO under Linux without + # incurring extra syscalls for Unix domain sockets. + # TODO: remove these when we remove kgio + TCPClient = Class.new(Kgio::Socket) # :nodoc: + class TCPSrv < Kgio::TCPServer # :nodoc: + def kgio_tryaccept # :nodoc: + super(TCPClient) + end + end + module SocketHelper # internal interface @@ -63,12 +75,15 @@ module Unicorn elsif respond_to?(:accf_arg) name = opt[:accept_filter] name = DEFAULTS[:accept_filter] if name.nil? + sock.listen(opt[:backlog]) + got = (sock.getsockopt(:SOL_SOCKET, :SO_ACCEPTFILTER) rescue nil).to_s + arg = accf_arg(name) begin - sock.setsockopt(:SOL_SOCKET, :SO_ACCEPTFILTER, accf_arg(name)) + sock.setsockopt(:SOL_SOCKET, :SO_ACCEPTFILTER, arg) rescue => e logger.error("#{sock_name(sock)} " \ "failed to set accept_filter=#{name} (#{e.inspect})") - end + end if arg != got end end @@ -148,7 +163,7 @@ module Unicorn end sock.bind(Socket.pack_sockaddr_in(port, addr)) sock.autoclose = false - Kgio::TCPServer.for_fd(sock.fileno) + TCPSrv.for_fd(sock.fileno) end # returns rfc2732-style (e.g. "[::1]:666") addresses for IPv6 @@ -185,7 +200,7 @@ module Unicorn def server_cast(sock) begin Socket.unpack_sockaddr_in(sock.getsockname) - Kgio::TCPServer.for_fd(sock.fileno) + TCPSrv.for_fd(sock.fileno) rescue ArgumentError Kgio::UNIXServer.for_fd(sock.fileno) end |