>>>>> "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

Reply via email to