>>>>> "MD" == Mark Dedlow <[EMAIL PROTECTED]> writes:
>> >>>>> "MD" == Mark Dedlow <[EMAIL PROTECTED]> writes:
>>
MD> Event on my Redhat 8.0 linux system loses (doesn't get?) SIGCHLD's
MD> that arrive too quickly. I have a test script that works
MD> correctly on Solaris, but not on Linux, so I'm guessing it's OS
MD> specific? Is this a known issue?
>>
>> some OS's merge multiple duplicate signals into one delivery. you should
>> always do all the possible work you can when you get such a signal. that
>> means when you get a SIGCHLD, you try to reap all child procs until you
>> get no more. use a non-blocking waitpid option and a loop. i bet you are
>> reaping one child per signal you get.
MD> I am counting $e->hits in my signal watcher, i.e. I do understand
MD> that with rapidly arriving signals, there could be more than one signal
MD> recevied per watcher callback. I am also using non-blocking waitpid,
MD> although I think the _arrival_ of signals is independent of waitpid'ing
MD> on them. In other words, I shouldn't need to waitpid at all, no?
MD> sub reaper {
MD> my $e = shift;
MD> $reaped += $e->hits;
MD> my $pid = waitpid(-1,&WNOHANG);
MD> printf STDERR "reaped %d on this callabck, %d total\n", $e->hits, $reaped;
MD> }
MD> --------------------------------------------------
that is the problem. you only reap one child per sigchld delivery. i
said you have to make it a loop and reap all you can. your process may
not get more than one signal so event.pm can't help you there.
MD> Are you suggesting I should wiatpid in a loop, even though $e->hits
MD> suggests there's only one signal in the queue?
as i have said, it is an OS problem and not event.pm's. you do need to
make a loop there. just keep going until it returns no child to reap.
below is the handler i wrote for stem. rip out the object and
trace stuff but the rest should be clean enough for use by you.
uri
sub sig_chld_handler {
while ( 1 ) {
my $child_pid = waitpid( -1, WNOHANG ) ;
return if $child_pid == 0 || $child_pid == -1 ;
my $proc_status = $? ;
my ( $exit_code, $exit_signal ) ;
if ( WIFEXITED( $proc_status ) ) {
$exit_code = WEXITSTATUS( $proc_status ) ;
TraceStatus "EXIT: $exit_code" ;
}
else {
$exit_signal = WTERMSIG( $proc_status ) ;
TraceStatus "EXIT signal: $exit_signal" ;
}
if ( my $self = $pid_to_obj{ $child_pid } ) {
$self->{'exit_code'} = $exit_code ;
$self->{'exit_signal'} = $exit_signal ;
if ( defined( $exit_code ) &&
$exit_code == EXEC_ERROR ) {
print <<ERR ;
Stem::Proc exec failed on path '$self->{'path'}'
ERR
}
$self->exited() ;
}
else {
#### ERROR
print "reaped unknown process pid $child_pid\n"
}
}
}
--
Uri Guttman ------ [EMAIL PROTECTED] -------- http://www.stemsystems.com
----- Stem and Perl Development, Systems Architecture, Design and Coding ----
Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org
Damian Conway Perl Classes - January 2003 -- http://www.stemsystems.com/class