Permalink
Browse files

Use non-blocking sockets when checking for server port availability i…

…n Phusion Passenger Standalone. Otherwise the socket creation function can freeze indefinitely on OS X.
  • Loading branch information...
1 parent e12c9fe commit c923e2d6f6c5487f2da0f5ca9445adf803f5b5cf @FooBarWidget FooBarWidget committed May 1, 2012
Showing with 32 additions and 16 deletions.
  1. +32 −16 lib/phusion_passenger/standalone/start_command.rb
@@ -242,24 +242,40 @@ def check_port_bind_permission_and_display_sudo_suggestion
end
end
end
-
- def check_port_availability
- if !@options[:socket_file]
+
+ def check_port(address, port)
+ begin
+ socket = Socket.new(Socket::Constants::AF_INET, Socket::Constants::SOCK_STREAM, 0)
+ sockaddr = Socket.pack_sockaddr_in(port, address)
begin
- TCPSocket.new(@options[:address], @options[:port]).close
- port_taken = true
- rescue SystemCallError
- port_taken = false
- end
- if port_taken
- error "The address #{@options[:address]}:#{@options[:port]} is already " <<
- "in use by another process, perhaps another Phusion Passenger " <<
- "Standalone instance.\n\n" <<
- "If you want to run this Phusion Passenger Standalone instance on " <<
- "another port, use the -p option, like this:\n\n" <<
- " passenger start -p #{@options[:port] + 1}"
- exit 1
+ socket.connect_nonblock(sockaddr)
+ rescue Errno::ENOENT, Errno::EINPROGRESS, Errno::EAGAIN, Errno::EWOULDBLOCK
+ if select(nil, [socket], nil, 0.1)
+ begin
+ socket.connect_nonblock(sockaddr)
+ rescue Errno::EISCONN
+ end
+ else
+ raise Errno::ECONNREFUSED
+ end
end
+ return true
+ rescue Errno::ECONNREFUSED
+ return false
+ ensure
+ socket.close if socket
+ end
+ end
+
+ def check_port_availability
+ if !@options[:socket_file] && check_port(@options[:address], @options[:port])
+ error "The address #{@options[:address]}:#{@options[:port]} is already " <<
+ "in use by another process, perhaps another Phusion Passenger " <<
+ "Standalone instance.\n\n" <<
+ "If you want to run this Phusion Passenger Standalone instance on " <<
+ "another port, use the -p option, like this:\n\n" <<
+ " passenger start -p #{@options[:port] + 1}"
+ exit 1
end
end

0 comments on commit c923e2d

Please sign in to comment.