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