Re: Event losing signals
[email protected] (Uri Guttman) Tue, 04 Feb 2003 23:26:59 -0500
| Newsgroups | perl.loop |
|---|---|
| Message-ID | <[email protected]> |
>>>>> "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