#!/usr/local/bin/perl -w use strict; $|++; use Win32::Event; sub DBUG() {0} my $time = shift||2; # mimic external process execution time (in seconds) my $timeout = shift||3; # time to wait for process (in seconds) my $event = Win32::Event->new() or die "ERROR: cannot create new Win32::Event! $!"; $SIG{CHLD} = 'IGNORE'; # ignore dead children until they go away FORK: { if( my $code_pid = fork() ) { # PARENT, control max execution time print "---timing control loop, entering...\n"; my $val = $event->wait($timeout * 1_000); # convert time to ms (not M$) if($val == 0) # test system event { # event timeout DBUG && print " -event timeout...\n"; print " -killing child...\n"; kill 1, $code_pid; # kill, force return code 1 } elsif($val == 1) { # event set DBUG && print " -event set...\n"; } elsif($val == -1) { # abandoned mutex DBUG && print " -mommy?...\n"; } else { # error occured DBUG && print " -event strangeness...\n"; } print "---timing control loop, exiting...\n"; } # PARENT, end elsif( defined $code_pid ) { # CHILD, execute process, set event when complete print " ---child process, entering...\n"; sleep($time); # fake execution of slow process print " ---child process, exiting successfully...\n"; $event->set(); # tell PARENT i'm done! exit 0; } # CHILD, end elsif( $! =~ /No more process/ ) { # recoverable fork error, redo sleep 2; redo FORK; } else { # unrecoverable fork error, die die "ERROR: can't fork! $!"; } } print "end of program\n";