require "fcntl"

module Selenium
  module WebDriver
    module Firefox

      #
      # @private
      #

      class SocketLock

        #
        # Need to be really specific about what host to use
        #
        # On os x, "localhost" will resolve to 3 different addresses (see /etc/hosts).
        # Ruby will loop over these and happily bind to the same port on each one,
        # making it completely unusable for our purposes.
        #

        HOST = "127.0.0.1"

        def initialize(port, timeout)
          @port    = port
          @timeout = timeout
        end

        def locked(&blk)
          lock

          begin
            yield
          ensure
            release
          end
        end

        private

        def lock
          max_time = Time.now + @timeout

          until can_lock? || Time.now >= max_time
            sleep 0.1
          end

          unless did_lock?
            raise Error::WebDriverError, "unable to bind to locking port #{@port} within #{@timeout} seconds"
          end
        end

        def release
          @server && @server.close
        end

        def can_lock?
          @server = TCPServer.new(@host, @port)

          # make sure the fd is not inherited by exec()'d processes
          if defined? Fcntl::FD_CLOEXEC
            @server.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC)
          end

          true
        rescue SocketError, Errno::EADDRINUSE => ex
          $stderr.puts "#{self}: #{ex.message}" if $DEBUG
          false
        end

        def did_lock?
          !!@server
        end

      end # SocketLock
    end # Firefox
  end # WebDriver
end # Selenium

require "fcntl"

module Selenium
  module WebDriver
    module Firefox

      #
      # @private
      #

      class SocketLock

        #
        # Need to be really specific about what host to use
        #
        # On os x, "localhost" will resolve to 3 different addresses (see /etc/hosts).
        # Ruby will loop over these and happily bind to the same port on each one,
        # making it completely unusable for our purposes.
        #

        HOST = "127.0.0.1"

        def initialize(port, timeout)
          @port    = port
          @timeout = timeout
        end

        def locked(&blk)
          lock

          begin
            yield
          ensure
            release
          end
        end

        private

        def lock
          max_time = Time.now + @timeout

          until can_lock? || Time.now >= max_time
            sleep 0.1
          end

          unless did_lock?
            raise Error::WebDriverError, "unable to bind to locking port #{@port} within #{@timeout} seconds"
          end
        end

        def release
          @server && @server.close
        end

        def can_lock?
          @server = TCPServer.new(HOST, @port)

          # make sure the fd is not inherited by exec()'d processes
          if defined? Fcntl::FD_CLOEXEC
            @server.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC)
          end

          true
        rescue SocketError, Errno::EADDRINUSE => ex
          $stderr.puts "#{self}: #{ex.message}" if $DEBUG
          false
        end

        def did_lock?
          !!@server
        end

      end # SocketLock
    end # Firefox
  end # WebDriver
end # Selenium

Fix wrong ivar usage in SocketLock.
JariBakken: Fix wrong ivar usage in SocketLock.

This passed the tests since nil is a valid argument for TCPServer.new,
defaulting to 0.0.0.0.

git-svn-id: 4179480af2c2519a5eb5e1e9b541cbdf5cf27696@9900 07704840-8298-11de-bf8c-fd130f914ac9
