use threads; use Thread::Queue; use threads::shared; use IPC::Open2; sub pipeCommand ($$$$;@) { my $uut = shift; my $cmd = shift; my $test = shift; my $wd = $homedir; $wd .= shift; my @input = @_ ? @_ : (); my $thread = async { my $tid = threads->tid(); my ( $out, $in ); $cmd = "cd ".$wd."; ".$cmd; my $pid = open2( $out, $in, $cmd ); print $in "$_\n" foreach (@input); close $in or warn "close of input: $! $?\n"; my $err = 0; while (<$out>) { last if ($die); #drops me out of loop and lets me exit cleanly chomp; $err = 1 if (/^thread failed/); next unless length $_; $Q->enqueue("$tid:$uut:$test:$_"); last if ($err); } kill( 2, $pid ) if ($err or $die); close $out or warn "close of output: $! $?\n"; my $kpid = waitpid ($pid, 0); $Q->enqueue("$tid:$uut:$test:ENDEND"); return; }; $thread->detach(); return ( $thread->tid() ); } #### my $tests = 7; # a number of tests sub recv_results { my $done = 0; my $err_count = 0; while (1) { if ( $Q->pending ) { my $line = $Q->dequeue; $_ = $line; chomp; if (/ENDEND$/) { $done++; } last if ( $done == $t_count ); last if (/^DIEDIE$/); next if (/ENDEND$/); if (/some pattern/) { #log something } else { #log something else } } else { usleep 5000; } } return $err_count; } #### sub ALRM_handler { alarm 0; $Q->enqueue("DIEDIE"); $die = 1; } #### my $time = 3600; #or some number of seconds launch_tests(); $SIG{ALRM} = 'ALRM_handler'; my $alrm = $time + 35; #little extra time for init and close alarm $alrm; my $err_count = recv_results(); $die = 1; #this will force any threads that are still stuck in the while loop to exit