[ruby/timeout] Handle Timeout + fork and add test for it

https://github.com/ruby/timeout/commit/4baee63b9b
This commit is contained in:
Benoit Daloze 2022-05-15 13:43:29 +02:00 committed by git
parent 89fbec224d
commit 354cd6f210
2 changed files with 49 additions and 22 deletions

View File

@ -95,10 +95,8 @@ module Timeout
end end
private_constant :Request private_constant :Request
def self.ensure_timeout_thread_created def self.create_timeout_thread
unless @timeout_thread Thread.new do
TIMEOUT_THREAD_MUTEX.synchronize do
@timeout_thread ||= Thread.new do
requests = [] requests = []
while true while true
until QUEUE.empty? and !requests.empty? # wait to have at least one request until QUEUE.empty? and !requests.empty? # wait to have at least one request
@ -121,6 +119,15 @@ module Timeout
end end
end end
end end
private_class_method :create_timeout_thread
def self.ensure_timeout_thread_created
unless @timeout_thread and @timeout_thread.alive?
TIMEOUT_THREAD_MUTEX.synchronize do
unless @timeout_thread and @timeout_thread.alive?
@timeout_thread = create_timeout_thread
end
end
end end
end end
# :startdoc: # :startdoc:

View File

@ -139,4 +139,24 @@ class TestTimeout < Test::Unit::TestCase
} }
assert(ok, bug11344) assert(ok, bug11344)
end end
def test_fork
omit 'fork not supported' unless Process.respond_to?(:fork)
r, w = IO.pipe
pid = fork do
r.close
begin
r = Timeout.timeout(0.01) { sleep 5 }
w.write r.inspect
rescue Timeout::Error
w.write 'timeout'
ensure
w.close
end
end
w.close
Process.wait pid
assert_equal 'timeout', r.read
r.close
end
end end