aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/webrick/utils.rb38
-rw-r--r--test/lib/leakchecker.rb2
-rw-r--r--test/net/http/utils.rb1
-rw-r--r--test/open-uri/test_open-uri.rb2
-rw-r--r--test/open-uri/test_ssl.rb2
-rw-r--r--test/rubygems/test_gem_remote_fetcher.rb1
-rw-r--r--test/webrick/test_cgi.rb5
-rw-r--r--test/webrick/test_filehandler.rb5
-rw-r--r--test/webrick/test_httpauth.rb5
-rw-r--r--test/webrick/test_httpproxy.rb5
-rw-r--r--test/webrick/test_httprequest.rb5
-rw-r--r--test/webrick/test_httpserver.rb5
-rw-r--r--test/webrick/test_utils.rb5
-rw-r--r--test/xmlrpc/webrick_testing.rb5
14 files changed, 78 insertions, 8 deletions
diff --git a/lib/webrick/utils.rb b/lib/webrick/utils.rb
index 9c978a2b7b..846829b01f 100644
--- a/lib/webrick/utils.rb
+++ b/lib/webrick/utils.rb
@@ -124,8 +124,6 @@ module WEBrick
class TimeoutHandler
include Singleton
- class Thread < ::Thread; end
-
##
# Mutex used to synchronize access across threads
TimeoutMutex = Mutex.new # :nodoc:
@@ -145,6 +143,10 @@ module WEBrick
instance.cancel(Thread.current, id)
end
+ def self.terminate
+ instance.terminate
+ end
+
##
# Creates a new TimeoutHandler. You should use ::register and ::cancel
# instead of creating the timeout handler directly.
@@ -153,7 +155,12 @@ module WEBrick
@timeout_info = Hash.new
}
@queue = Queue.new
- @watcher = Thread.start{
+ @watcher = nil
+ end
+
+ # :nodoc:
+ private \
+ def watch
to_interrupt = []
while true
now = Time.now
@@ -184,8 +191,17 @@ module WEBrick
end
@queue.clear
end
- }
- end
+ end
+
+ # :nodoc:
+ private \
+ def watcher
+ (w = @watcher)&.alive? and return w # usual case
+ TimeoutMutex.synchronize{
+ (w = @watcher)&.alive? and next w # pathological check
+ @watcher = Thread.start(&method(:watch))
+ }
+ end
##
# Interrupts the timeout handler +id+ and raises +exception+
@@ -203,10 +219,10 @@ module WEBrick
def register(thread, time, exception)
info = nil
TimeoutMutex.synchronize{
- @timeout_info[thread] ||= Array.new
- @timeout_info[thread] << (info = [time, exception])
+ (@timeout_info[thread] ||= []) << (info = [time, exception])
}
@queue.push nil
+ watcher
return info.object_id
end
@@ -224,6 +240,14 @@ module WEBrick
return false
}
end
+
+ ##
+ def terminate
+ TimeoutMutex.synchronize{
+ @timeout_info.clear
+ @watcher&.kill&.join
+ }
+ end
end
##
diff --git a/test/lib/leakchecker.rb b/test/lib/leakchecker.rb
index a9bc5813c5..355f93dc79 100644
--- a/test/lib/leakchecker.rb
+++ b/test/lib/leakchecker.rb
@@ -139,7 +139,7 @@ class LeakChecker
def find_threads
Thread.list.find_all {|t|
- t != Thread.current && /\AWEBrick::/ !~ t.class.name && t.alive?
+ t != Thread.current && t.alive?
}
end
diff --git a/test/net/http/utils.rb b/test/net/http/utils.rb
index 8d0ecd6020..8a00615fbe 100644
--- a/test/net/http/utils.rb
+++ b/test/net/http/utils.rb
@@ -36,6 +36,7 @@ module TestNetHTTPUtils
if @server
@server.shutdown
@server_thread.join
+ WEBrick::Utils::TimeoutHandler.terminate
end
@log_tester.call(@log) if @log_tester
# resume global state
diff --git a/test/open-uri/test_open-uri.rb b/test/open-uri/test_open-uri.rb
index b3702e6067..c64c2be324 100644
--- a/test/open-uri/test_open-uri.rb
+++ b/test/open-uri/test_open-uri.rb
@@ -43,6 +43,8 @@ class TestOpenURI < Test::Unit::TestCase
}
assert_join_threads([client_thread, server_thread2])
}
+ ensure
+ WEBrick::Utils::TimeoutHandler.terminate
end
def with_env(h)
diff --git a/test/open-uri/test_ssl.rb b/test/open-uri/test_ssl.rb
index 956fe05399..b78ef24615 100644
--- a/test/open-uri/test_ssl.rb
+++ b/test/open-uri/test_ssl.rb
@@ -52,6 +52,8 @@ class TestOpenURISSL
}
assert_join_threads(threads)
}
+ ensure
+ WEBrick::Utils::TimeoutHandler.terminate
end
def setup
diff --git a/test/rubygems/test_gem_remote_fetcher.rb b/test/rubygems/test_gem_remote_fetcher.rb
index 8b46921401..3439194858 100644
--- a/test/rubygems/test_gem_remote_fetcher.rb
+++ b/test/rubygems/test_gem_remote_fetcher.rb
@@ -924,6 +924,7 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg==
@ssl_server_thread.kill.join
@ssl_server_thread = nil
end
+ WEBrick::Utils::TimeoutHandler.terminate
end
def normal_server_port
diff --git a/test/webrick/test_cgi.rb b/test/webrick/test_cgi.rb
index 090286840b..9dd6be8155 100644
--- a/test/webrick/test_cgi.rb
+++ b/test/webrick/test_cgi.rb
@@ -7,6 +7,11 @@ require "test/unit"
class TestWEBrickCGI < Test::Unit::TestCase
CRLF = "\r\n"
+ def teardown
+ WEBrick::Utils::TimeoutHandler.terminate
+ super
+ end
+
def start_cgi_server(log_tester=TestWEBrick::DefaultLogTester, &block)
config = {
:CGIInterpreter => TestWEBrick::RubyBin,
diff --git a/test/webrick/test_filehandler.rb b/test/webrick/test_filehandler.rb
index 663b237a82..0e05c6824c 100644
--- a/test/webrick/test_filehandler.rb
+++ b/test/webrick/test_filehandler.rb
@@ -5,6 +5,11 @@ require "webrick"
require "stringio"
class WEBrick::TestFileHandler < Test::Unit::TestCase
+ def teardown
+ WEBrick::Utils::TimeoutHandler.terminate
+ super
+ end
+
def default_file_handler(filename)
klass = WEBrick::HTTPServlet::DefaultFileHandler
klass.new(WEBrick::Config::HTTP, filename)
diff --git a/test/webrick/test_httpauth.rb b/test/webrick/test_httpauth.rb
index 4376b91842..126bc6ee54 100644
--- a/test/webrick/test_httpauth.rb
+++ b/test/webrick/test_httpauth.rb
@@ -7,6 +7,11 @@ require "webrick/httpauth/basicauth"
require_relative "utils"
class TestWEBrickHTTPAuth < Test::Unit::TestCase
+ def teardown
+ WEBrick::Utils::TimeoutHandler.terminate
+ super
+ end
+
def test_basic_auth
log_tester = lambda {|log, access_log|
assert_equal(1, log.length)
diff --git a/test/webrick/test_httpproxy.rb b/test/webrick/test_httpproxy.rb
index 6837f0c738..335d442fbb 100644
--- a/test/webrick/test_httpproxy.rb
+++ b/test/webrick/test_httpproxy.rb
@@ -13,6 +13,11 @@ end
require File.expand_path("utils.rb", File.dirname(__FILE__))
class TestWEBrickHTTPProxy < Test::Unit::TestCase
+ def teardown
+ WEBrick::Utils::TimeoutHandler.terminate
+ super
+ end
+
def test_fake_proxy
assert_nil(WEBrick::FakeProxyURI.scheme)
assert_nil(WEBrick::FakeProxyURI.host)
diff --git a/test/webrick/test_httprequest.rb b/test/webrick/test_httprequest.rb
index 45d26f8699..3ece8a3ad9 100644
--- a/test/webrick/test_httprequest.rb
+++ b/test/webrick/test_httprequest.rb
@@ -4,6 +4,11 @@ require "stringio"
require "test/unit"
class TestWEBrickHTTPRequest < Test::Unit::TestCase
+ def teardown
+ WEBrick::Utils::TimeoutHandler.terminate
+ super
+ end
+
def test_simple_request
msg = <<-_end_of_message_
GET /
diff --git a/test/webrick/test_httpserver.rb b/test/webrick/test_httpserver.rb
index 5adf617fa5..5aa94637ba 100644
--- a/test/webrick/test_httpserver.rb
+++ b/test/webrick/test_httpserver.rb
@@ -12,6 +12,11 @@ class TestWEBrickHTTPServer < Test::Unit::TestCase
end
NoLog = WEBrick::Log.new(empty_log, WEBrick::BasicLog::WARN)
+ def teardown
+ WEBrick::Utils::TimeoutHandler.terminate
+ super
+ end
+
def test_mount
httpd = WEBrick::HTTPServer.new(
:Logger => NoLog,
diff --git a/test/webrick/test_utils.rb b/test/webrick/test_utils.rb
index 23996de5d2..c34ba8bb73 100644
--- a/test/webrick/test_utils.rb
+++ b/test/webrick/test_utils.rb
@@ -3,6 +3,11 @@ require "test/unit"
require "webrick/utils"
class TestWEBrickUtils < Test::Unit::TestCase
+ def teardown
+ WEBrick::Utils::TimeoutHandler.terminate
+ super
+ end
+
def assert_expired(m)
Thread.handle_interrupt(Timeout::Error => :never, EX => :never) do
assert_empty(m::TimeoutHandler.instance.instance_variable_get(:@timeout_info))
diff --git a/test/xmlrpc/webrick_testing.rb b/test/xmlrpc/webrick_testing.rb
index ff287f7024..7a3325df3c 100644
--- a/test/xmlrpc/webrick_testing.rb
+++ b/test/xmlrpc/webrick_testing.rb
@@ -3,6 +3,11 @@ require 'timeout'
module TestXMLRPC
module WEBrick_Testing
+ def teardown
+ WEBrick::Utils::TimeoutHandler.terminate
+ super
+ end
+
def start_server(logger, config={})
raise "already started" if defined?(@__server) && @__server
@__started = false