Hi,

I attached a slighty different version of the previous patch, which simply 
tries to open the port. It also correctly waits for a possible exit of the 
server.

bye, Roman
diff -ur subversion-1.3.2.org/subversion/bindings/swig/ruby/test/util.rb 
subversion-1.3.2/subversion/bindings/swig/ruby/test/util.rb
--- subversion-1.3.2.org/subversion/bindings/swig/ruby/test/util.rb     
2006-01-04 03:06:58.000000000 +0100
+++ subversion-1.3.2/subversion/bindings/swig/ruby/test/util.rb 2006-08-28 
02:22:31.000000000 +0200
@@ -1,4 +1,5 @@
 require "fileutils"
+require "socket"
 
 require "svn/client"
 require "svn/repos"
@@ -105,9 +106,7 @@
              "-d", "--foreground")
       }
       pid, status = Process.waitpid2(@svnserve_pid, Process::WNOHANG)
-      if status and status.exited?
-        STDERR.puts "port #{port} couldn't be used for svnserve"
-      else
+      if wait_until_svnserve_gets_available_at(port)
         @svnserve_port = port
         @repos_svnserve_uri =
           "svn://[EMAIL PROTECTED]:[EMAIL PROTECTED]@full_repos_path}"
@@ -221,4 +220,25 @@
     auth_baton[Svn::Core::AUTH_PARAM_CONFIG_DIR] = @config_path
     auth_baton[Svn::Core::AUTH_PARAM_DEFAULT_USERNAME] = @author
   end
+
+  # Waits until svnserve gets available at port +port+, avoiding the race
+  # condition between starting up a svnserve process and trying to connect
+  # to it (Bug#378837 in Debian's BTS).
+  def wait_until_svnserve_gets_available_at(port)
+    1000.times do |n|
+      begin
+       pid, status = Process.waitpid2(@svnserve_pid, Process::WNOHANG)
+       if status and status.exited?
+         STDERR.puts "port #{port} couldn't be used for svnserve"
+         return false
+       end
+       TCPSocket.new(@svnserve_host, port).close
+      rescue Errno::ECONNREFUSED
+       sleep(n < 10 ? 0.2 : 0.5)
+      else
+       return true
+      end
+    end
+    raise "svnserve couldn't get available at port #{port}"
+  end
 end

Reply via email to