Project

General

Profile

Feature #7086 ยป timeout-rk.rb

Program which tests a few alternative timeout implementations - rklemme (Robert Klemme), 09/30/2012 12:14 AM

 
#!/usr/local/bin/ruby19

require 'monitor'

Thread.abort_on_exception = true

# Process the given block in another thread (!) but at most the
# given number of seconds. If processing takes longer the result
# is discarded.
def timeout_1(timeout, &code)
raise ArgumentError, "Invalid timeout: %p" % [timeout] unless timeout > 0
raise ArgumentError, "No code to execute" if code.nil?

worker = Thread.new(&code)
worker.join(timeout) and worker.value
end

# Process the given block in another thread (!) but at most the
# given number of seconds. If processing takes longer the result
# is discarded.
def timeout_2(timeout, &code)
raise ArgumentError, "Invalid timeout: %p" % [timeout] unless timeout > 0
raise ArgumentError, "No code to execute" if code.nil?

mon = Monitor.new
cv = mon.new_cond

worker = Thread.new do
begin
code.call
ensure
mon.synchronize { cv.signal }
end
end

mon.synchronize do
cv.wait(timeout)
end ? worker.value : nil
end

# Process the given block in another thread (!) but at most the
# given number of seconds. If processing takes longer the result
# is discarded.
def timeout_3(timeout, &code)
raise ArgumentError, "Invalid timeout: %p" % [timeout] unless timeout > 0
raise ArgumentError, "No code to execute" if code.nil?

mon = Mutex.new
cv = ::ConditionVariable.new

worker = Thread.new do
begin
code.call
ensure
mon.synchronize { cv.signal }
end
end

mon.synchronize do
cv.wait(mon, timeout)
end ? worker.value : nil
end

# Process the given block in another thread (!) but at most the
# given number of seconds. If processing takes longer the result
# is discarded.
def timeout_4(timeout, &code)
raise ArgumentError, "Invalid timeout: %p" % [timeout] unless timeout > 0
raise ArgumentError, "No code to execute" if code.nil?

mon = Monitor.new
cv = ::ConditionVariable.new

worker = Thread.new do
begin
code.call
ensure
mon.synchronize { cv.signal }
end
end

mon.synchronize do
cv.wait(mon, timeout)
end ? worker.value : nil
end

[1, 2, 4, 5].each do |sec|
printf "Test with %2ds...\n", sec

%w{timeout_1 timeout_2 timeout_3 timeout_4}.each do |meth|
begin
result = send meth, sec do
sleep 3
:success
end

printf "%-10s: %p", meth, result
print " ERROR!" unless (sec > 3) == (result == :success)
puts
rescue Exception => e
printf "ERROR: method %p: %p\n", meth, e
end
end

puts
end


    (1-1/1)