require 'thread'

class ThreadEnsemble
#--{{{
  attr 'threads'

  def initialize
    @threads, @argv, @done, @running = [], [], Queue.new, false
  end

  def add_thread *a, &b
    @running ? raise : (@argv << [a, b])
  end

  def killall
    (@threads - [Thread.current]).each{|t| t.kill rescue nil} if @running
  end

  def run
    @running = true

    begin
      @argv.each do |a, b|
        @threads << Thread.new(*a) do |*a|
          begin
            b[*a]
          ensure
            killall rescue nil if $!
            @done.push Thread.current
          end
        end
      end
    rescue
      killall
      raise
    ensure
      all_done
    end

    @threads.map{|t| t.value}
  end

  def all_done
    @threads.size.times{ @done.pop }
  end
#--}}}
end

loop do
  te = ThreadEnsemble.new

  1000.times do
    te.add_thread do
      raise
    end
  end

  begin
    te.run
  rescue
    running = te.threads.select{|t| t.status} 
    abort running.inspect if running.size > 0
  end
end
