--- loncom/loncnew 2004/10/04 10:30:50 1.62 +++ loncom/loncnew 2004/10/04 11:30:45 1.63 @@ -2,7 +2,7 @@ # The LearningOnline Network with CAPA # lonc maintains the connections to remote computers # -# $Id: loncnew,v 1.62 2004/10/04 10:30:50 foxr Exp $ +# $Id: loncnew,v 1.63 2004/10/04 11:30:45 foxr Exp $ # # Copyright Michigan State University Board of Trustees # @@ -1716,7 +1716,6 @@ sub CreateChild { # a connection request arrives. We must: # Start a child process to accept the connection request. # Kill our listen on the socket. -# Setup an event to handle the child process exit. (SIGCHLD). # Parameter: # event - The event object that was created to monitor this socket. # event->w->fd is the socket. @@ -1821,6 +1820,39 @@ sub listen_on_all_unix_sockets { } } +# server_died is called whenever a child process exits. +# Since this is dispatched via a signal, we must process all +# dead children until there are no more left. The action +# is to: +# - Remove the child from the bookeeping hashes +# - Re-establish a listen on the unix domain socket associated +# with that host. +# Parameters: +# The event, but we don't actually care about it. +sub server_died { + &Debug(9, "server_died called..."); + + while(1) { # Loop until waitpid nowait fails. + my $pid = waitpid(-1, WNOHANG); + if($pid <= 0) { + return; # Nothing left to wait for. + } + # need the host to restart: + + my $host = $ChildHash{$pid}; + if($host) { # It's for real... + &Debug(9, "Caught sigchild for $host"); + delete($ChildHash{$pid}); + delete($HostToPid{$host}); + &parent_listen($host); + + } else { + &Debug(5, "Caught sigchild for pid not in hosts hash: $pid"); + } + } + +} + # # Parent process logic pass 1: # For each entry in the hosts table, we will @@ -1893,6 +1925,14 @@ ShowStatus("Parent keeping the flock"); if ($DieWhenIdle) { + # We need to setup a SIGChild event to handle the exit (natural or otherwise) + # of the children. + + Event->signal(cb => \&server_died, + desc => "Child exit handler", + signal => "CHLD"); + + $Event::DebugLevel = $DebugLevel; Debug(9, "Parent entering event loop"); my $ret = Event::loop();