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
|
class StackWaiter
QUEUE = Queue.new
WAITERS = Queue.new
ACTORS = Queue.new
class << self
def forever
WAITERS << Thread.current
# de QUEUE.pop
sleep
end
def no_longer
StackWaiter::ACTORS.pop.terminate until StackWaiter::ACTORS.empty?
loop do
break if WAITERS.empty?
QUEUE << nil
nicely_end_thread(WAITERS.pop)
end
end
def nicely_end_thread(th)
return if jruby_fiber?(th)
status = th.status
case status
when nil, false, "dead"
when "aborting"
th.join(2) || STDERR.puts("Thread join timed out...")
when "sleep", "run"
th.kill
th.join(2) || STDERR.puts("Thread join timed out...")
else
STDERR.puts "unknown status: #{th.status.inspect}"
end
end
def jruby_fiber?(th)
return false unless RUBY_PLATFORM == "java" && (java_th = th.to_java.getNativeThread)
/Fiber/ =~ java_th.get_name
end
end
end
class StackBlocker
include Celluloid
def initialize(threads)
@threads = threads
end
def blocking
StackWaiter::ACTORS << Thread.current
@threads << Thread.current
StackWaiter.forever
end
end
|