# Author:: Nicolas Despres . # Copyright:: Copyright (c) 2004, 2005 Uttk team. All rights reserved. # License:: LGPL # $Id: /w/fey/uttk/trunk/lib/uttk/strategies/Pool.rb 22102 2006-02-21T23:03:39.538964Z pouillar $ module Uttk module Strategies # I'm a collection of strategies and I run all of them in a separated # thread. class Pool < Collection include Concrete class PoolComponent attr_accessor :test, :thread, :flow, :log end def initialize ( *a, &b ) @pool_contents = [] super end def abort_hook return if defined? @already_aborted @already_aborted = true @pool_contents.each do |comp| test = comp.test next if test.status.is_a? StartStatus test.abort('pool aborted') if test.running? end super end protected :abort_hook def prologue super @pool_upper = @log.new_node :contents, :ordered => true path = @log.path @pool_contents = @contents.map do |test| comp = PoolComponent.new comp.test = test comp.log = Filters::Saver.new comp.flow = @symtbl[:flow_factory].new_flow test.symtbl[:flow] = comp.flow comp.thread = Thread.new do begin sleep new_log = Logger.new(comp.log) new_log.chpath(path) run_test(test, new_log) rescue Exception => ex display_unexpected_exc ex end end comp end # This thread is here to catch properly exceptions. @real_parent_thread = @thread @thread = Thread.new do begin sleep rescue Exception => ex abort_hook() @real_parent_thread.raise ex end end end protected :prologue def run_composite @pool_contents.each { |comp| comp.thread.wakeup } @pool_contents.each { |comp| comp.thread.join } end protected :run_composite def epilogue @pool_contents.each do |comp| comp.flow << :not_running? @log << comp.log end @pool_upper.up @pool_contents.each do |comp| comp.thread.kill if comp.thread.alive? comp.flow.destroy end @pool_contents.clear super end protected :epilogue end # class Pool end # module Strategies end # module Uttk