1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
|
require "thread"
require "stud/interval"
module Stud
# A Task spawns a thread to execute the given block. execution completion and result retrieval is
# done using the Task#wait method. A Task is run once and the thread exists upon block completion.
# A task and its underlying thread are not reusable.
#
# Task does not provide a mean to force-interrupt a running task, it only provides the #stop!
# method to signal the task for a stop request. The task or code block can use the #stop? method
# to check for a stop request. Note that the #stop! and #stop? methods are thread safe.
class Task
# provide access to the underlying thread if ever needed.
attr_reader :thread
def initialize(*args, &block)
# A queue to receive the result of the block
# TODO(sissel): Don't use a queue, just store it in an instance variable.
@queue = Queue.new
@thread = Thread.new(@queue, *args) do |queue, *args|
begin
result = block.call(*args)
queue << [:return, result]
rescue => e
queue << [:exception, e]
end
end # thread
end # def initialize
# wait waits for the task thread to complete and return the block return value
# if the block raises an exception, this exception is propagated in this
# wait method.
# @return [Object, Exception] block return value
def wait
@thread.join
reason, result = @queue.pop
if reason == :exception
#raise StandardError.new(result)
raise result
else
return result
end
end # def wait
# stop! requests the task to stop. the Thread#wakeup method is also
# called so that a sleeping task is waked up and has a chance to verify
# the stop request using the #stop? method. also see Stud.stop!
def stop!
Stud.stop!(@thread)
end
# stop? returns true if this task stop! has been called
# See Stud.stop?
# @return [Boolean] true if the stop! has been called
def stop?
Stud.stop?(@thread)
end
alias_method :interrupted?, :stop?
end # class Task
end # module Stud
|