Hi,
I've improved yesterday's patch. This patch will be more effective.
I've tested Ruby bindings with my subversion/svnserve/main.c inserted
sleep() before calling apr_socket_bind().
Thanks,
-nori
Index: subversion/bindings/swig/ruby/test/util.rb
===================================================================
--- subversion/bindings/swig/ruby/test/util.rb (revision 20818)
+++ subversion/bindings/swig/ruby/test/util.rb (working copy)
@@ -1,4 +1,5 @@
require "fileutils"
+require "socket"
require "svn/client"
require "svn/repos"
@@ -106,8 +107,8 @@
"-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"
+ if (status and status.exited?) or (not svnserve_available_at?(port))
+ STDERR.puts "svnserve couldn't get available at port #{port}"
else
@svnserve_port = port
@repos_svnserve_uri =
@@ -129,6 +130,7 @@
Process.waitpid(@svnserve_pid)
rescue Errno::ECHILD
end
+ @svnserve_pid = nil
end
end
@@ -222,4 +224,21 @@
auth_baton[Svn::Core::AUTH_PARAM_CONFIG_DIR] = @config_path
auth_baton[Svn::Core::AUTH_PARAM_DEFAULT_USERNAME] = @author
end
+
+ # Check whether svnserve gets available at port +port+ to avoid the race
+ # condition between starting up a svnserve process and trying to connect
+ # to it (Bug#378837 in Debian's BTS). Returns +true+ when svnserve gets
+ # available.
+ def svnserve_available_at?(port)
+ begin
+ 50.times do |n|
+ TCPServer.new(port).close
+ sleep 0.1 + rand(0.2)
+ end
+ teardown_svnserve
+ false
+ rescue Errno::EADDRINUSE
+ true
+ end
+ end
end