From 3b0bf229c40a9e460b71e751932481e66e90c26a Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Sat, 10 Oct 2009 15:57:12 -0700 Subject: thread_spawn: clean up nuking of timed-out threads We log thread destruction times now and also make a best-effort to avoid race conditions on threads that just finished. --- lib/rainbows/thread_spawn.rb | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) (limited to 'lib/rainbows/thread_spawn.rb') diff --git a/lib/rainbows/thread_spawn.rb b/lib/rainbows/thread_spawn.rb index 99647d5..0e023cd 100644 --- a/lib/rainbows/thread_spawn.rb +++ b/lib/rainbows/thread_spawn.rb @@ -37,9 +37,7 @@ module Rainbows end ret.first.each do |l| - while threads.list.size >= limit - nuke_old_thread(threads) - end + nuke_old_thread(threads, limit) c = begin l.accept_nonblock rescue Errno::EAGAIN, Errno::ECONNABORTED @@ -56,15 +54,18 @@ module Rainbows join_spawned_threads(threads) end - def nuke_old_thread(threads) - threads.list.each do |thr| - next if (Time.now - (thr[:t] || next)) < timeout - thr.kill - logger.error "killed #{thr.inspect} for being too old" - return + def nuke_old_thread(threads, limit) + while (list = threads.list).size > limit + list.each do |thr| + thr.alive? or return # it _just_ died, we don't need it + next if (age = (Time.now - (thr[:t] || next))) < timeout + thr.kill # no-op if already dead + logger.error "killed #{thr.inspect} for being too old: #{age}" + return + end + # nothing to kill, yield to another thread + Thread.pass end - # nothing to kill, yield to another thread - Thread.pass end def join_spawned_threads(threads) -- cgit v1.2.3-24-ge0c7