about summary refs log tree commit homepage
path: root/lib
diff options
context:
space:
mode:
authorEric Wong <normalperson@yhbt.net>2010-10-04 04:17:31 +0000
committerEric Wong <normalperson@yhbt.net>2010-10-04 04:17:50 +0000
commit1a2363b17b1d06be6b35d347ebcaed6a0c940200 (patch)
treedc0e5030525f630ded02405af307196f6b7c34c1 /lib
parent505a9e72d320fe3ae521ceb0f381c1c0f5ae4389 (diff)
downloadunicorn-1a2363b17b1d06be6b35d347ebcaed6a0c940200.tar.gz
While we've always unlinked dead sockets from nuked/leftover
processes, blindly unlinking them can cause unnecessary failures
when an active process is already listening on them.  We now
make a simple connect(2) check to ensure the socket is not in
use before unlinking it.

Thanks to Jordan Ritter for the detailed bug report leading to
this fix.

ref: http://mid.gmane.org/8D95A44B-A098-43BE-B532-7D74BD957F31@darkridge.com
Diffstat (limited to 'lib')
-rw-r--r--lib/unicorn/socket_helper.rb10
1 files changed, 8 insertions, 2 deletions
diff --git a/lib/unicorn/socket_helper.rb b/lib/unicorn/socket_helper.rb
index 9a155e1..1d03eab 100644
--- a/lib/unicorn/socket_helper.rb
+++ b/lib/unicorn/socket_helper.rb
@@ -111,8 +111,14 @@ module Unicorn
       sock = if address[0] == ?/
         if File.exist?(address)
           if File.socket?(address)
-            logger.info "unlinking existing socket=#{address}"
-            File.unlink(address)
+            begin
+              UNIXSocket.new(address).close
+              # fall through, try to bind(2) and fail with EADDRINUSE
+              # (or succeed from a small race condition we can't sanely avoid).
+            rescue Errno::ECONNREFUSED
+              logger.info "unlinking existing socket=#{address}"
+              File.unlink(address)
+            end
           else
             raise ArgumentError,
                   "socket=#{address} specified but it is not a socket!"