about summary refs log tree commit homepage
path: root/lib/unicorn/socket.rb
diff options
context:
space:
mode:
authorEric Wong <normalperson@yhbt.net>2009-02-05 20:50:58 -0800
committerEric Wong <normalperson@yhbt.net>2009-02-09 19:50:50 -0800
commitbc44990ddb16669030cf0ca72f48e1c6c620a4f2 (patch)
tree0118dccd255738aaf365bc15aaf2360c98f5479b /lib/unicorn/socket.rb
parenta105f96edd9bc842170c6272b0d37b8891152824 (diff)
downloadunicorn-bc44990ddb16669030cf0ca72f48e1c6c620a4f2.tar.gz
We'll be supporting UNIX domain sockets soon...  Get rid of
tcphack since it was overriding a default method and just
manually call Socket.new, bind, listen ourselves.  Additionaly,
use SO_REUSEADDR when binding since it is convenient for
restarts.
Diffstat (limited to 'lib/unicorn/socket.rb')
-rw-r--r--lib/unicorn/socket.rb53
1 files changed, 53 insertions, 0 deletions
diff --git a/lib/unicorn/socket.rb b/lib/unicorn/socket.rb
new file mode 100644
index 0000000..40631d5
--- /dev/null
+++ b/lib/unicorn/socket.rb
@@ -0,0 +1,53 @@
+# non-portable Socket code goes here:
+class Socket
+
+  # configure platform-specific options (only tested on Linux 2.6 so far)
+  case RUBY_PLATFORM
+  when /linux/
+    # from /usr/include/linux/tcp.h
+    TCP_DEFER_ACCEPT = 9 unless defined?(TCP_DEFER_ACCEPT)
+    TCP_CORK = 3 unless defined?(TCP_CORK)
+
+    def unicorn_server_init
+      self.setsockopt(SOL_TCP, TCP_DEFER_ACCEPT, 1)
+    end
+  when /freebsd(([1-4]\..{1,2})|5\.[0-4])/
+  when /freebsd/
+    # Use the HTTP accept filter if available.
+    # The struct made by pack() is defined in /usr/include/sys/socket.h as accept_filter_arg
+    unless `/sbin/sysctl -nq net.inet.accf.http`.empty?
+      unless defined?(SO_ACCEPTFILTER_HTTPREADY)
+        SO_ACCEPTFILTER_HTTPREADY = ['httpready',nil].pack('a16a240').freeze
+      end
+
+      def unicorn_server_init
+        self.setsockopt(SOL_SOCKET, SO_ACCEPTFILTER, SO_ACCEPTFILTER_HTTPREADY)
+      end
+    end
+  end
+
+  def unicorn_client_init
+    self.sync = true
+    self.setsockopt(IPPROTO_TCP, TCP_NODELAY, 1) if defined?(TCP_NODELAY)
+    self.setsockopt(SOL_TCP, TCP_CORK, 1) if defined?(TCP_CORK)
+  end
+
+  def unicorn_peeraddr
+    Socket.unpack_sockaddr_in(getpeername)
+  end
+
+  class << self
+
+    def unicorn_tcp_server(host, port, backlog = 5)
+      s = new(AF_INET, SOCK_STREAM, 0)
+      s.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC) if defined?(Fcntl::FD_CLOEXEC)
+      s.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1) if defined?(SO_REUSEADDR)
+      s.bind(pack_sockaddr_in(port, host))
+      s.listen(backlog)
+      s
+    end
+
+  end
+
+end
+