about summary refs log tree commit homepage
path: root/lib
diff options
context:
space:
mode:
authorEric Wong <normalperson@yhbt.net>2009-03-25 01:52:09 -0700
committerEric Wong <normalperson@yhbt.net>2009-03-25 16:13:54 -0700
commit1bf10b3a73509f3fc72fb7f267e767c0e2fa9376 (patch)
treead5fd7cf9e7ace00c3526842036d3b0345486a9e /lib
parent32b6e838c28b7948811a6470d8c0a49d5767ec69 (diff)
downloadunicorn-1bf10b3a73509f3fc72fb7f267e767c0e2fa9376.tar.gz
bind_listen takes a hash as its second parameter now, allowing
the addition of :sndbuf and :rcvbuf options to specify the size
of the buffers in bytes.  These correspond to the SO_SNDBUF and
SO_RCVBUF options via setsockopt(2) respectively.

This also adds support for per-listener backlogs to be used.

However, this is only an internal API change and the changes
have not yet been exposed to the user via Unicorn::Configurator,
yet.

Also add a bunch of SocketHelper tests
Diffstat (limited to 'lib')
-rw-r--r--lib/unicorn.rb2
-rw-r--r--lib/unicorn/socket.rb17
2 files changed, 16 insertions, 3 deletions
diff --git a/lib/unicorn.rb b/lib/unicorn.rb
index eefbfc1..e36cb1e 100644
--- a/lib/unicorn.rb
+++ b/lib/unicorn.rb
@@ -135,7 +135,7 @@ module Unicorn
     def listen(address)
       return if String === address && listener_names.include?(address)
 
-      if io = bind_listen(address, @backlog)
+      if io = bind_listen(address, { :backlog => @backlog })
         if Socket == io.class
           @io_purgatory << io
           io = server_cast(io)
diff --git a/lib/unicorn/socket.rb b/lib/unicorn/socket.rb
index 9519448..4870133 100644
--- a/lib/unicorn/socket.rb
+++ b/lib/unicorn/socket.rb
@@ -62,10 +62,17 @@ module Unicorn
       end
     end
 
+    def log_buffer_sizes(sock, pfx = '')
+      respond_to?(:logger) or return
+      rcvbuf = sock.getsockopt(SOL_SOCKET, SO_RCVBUF).unpack('i')
+      sndbuf = sock.getsockopt(SOL_SOCKET, SO_SNDBUF).unpack('i')
+      logger.info "#{pfx}#{sock_name(sock)} rcvbuf=#{rcvbuf} sndbuf=#{sndbuf}"
+    end
+
     # creates a new server, socket. address may be a HOST:PORT or
     # an absolute path to a UNIX socket.  address can even be a Socket
     # object in which case it is immediately returned
-    def bind_listen(address = '0.0.0.0:8080', backlog = 1024)
+    def bind_listen(address = '0.0.0.0:8080', opt = { :backlog => 1024 })
       return address unless String === address
 
       domain, bind_addr = if address[0..0] == "/"
@@ -95,7 +102,13 @@ module Unicorn
         sock.close rescue nil
         return nil
       end
-      sock.listen(backlog)
+      if opt[:rcvbuf] || opt[:sndbuf]
+        log_buffer_sizes(sock, "before: ")
+        sock.setsockopt(SOL_SOCKET, SO_RCVBUF, opt[:rcvbuf]) if opt[:rcvbuf]
+        sock.setsockopt(SOL_SOCKET, SO_SNDBUF, opt[:sndbuf]) if opt[:sndbuf]
+        log_buffer_sizes(sock, " after: ")
+      end
+      sock.listen(opt[:backlog] || 1024)
       set_server_sockopt(sock) if domain == AF_INET
       sock
     end