Diff for /loncom/loncnew between versions 1.62 and 1.64

version 1.62, 2004/10/04 10:30:50 version 1.64, 2004/10/05 10:10:31
Line 302  sub SocketTimeout { Line 302  sub SocketTimeout {
     }      }
   
 }  }
   #
   #   This function should be called by the child in all cases where it must
   #   exit.  If the child process is running with the DieWhenIdle turned on
   #   it must create a lock file for the AF_UNIX socket in order to prevent
   #   connection requests from lonnet in the time between process exit
   #   and the parent picking up the listen again.
   # Parameters:
   #     exit_code           - Exit status value, however see the next parameter.
   #     message             - If this optional parameter is supplied, the exit
   #                           is via a die with this message.
   #
   sub child_exit {
       my ($exit_code, $message) = @_;
   
       # Regardless of how we exit, we may need to do the lock thing:
   
       if($DieWhenIdle) {
    #
    #  Create a lock file since there will be a time window
    #  between our exit and the parent's picking up the listen
    #  during which no listens will be done on the
    #  lonnet client socket.
    #
    my $lock_file = GetLoncSocketPath().".lock";
    open(LOCK,">$lock_file");
    print LOCK "Contents not important";
    close(LOCK);
   
    exit(0);
       }
       #  Now figure out how we exit:
   
       if($message) {
    die $message;
       } else {
    exit($exit_code);
       }
   }
 #----------------------------- Timer management ------------------------  #----------------------------- Timer management ------------------------
   
 =pod  =pod
Line 332  sub Tick { Line 370  sub Tick {
     $IdleSeconds = 0; # Otherwise all connections get trimmed to fast.      $IdleSeconds = 0; # Otherwise all connections get trimmed to fast.
     UpdateStatus();      UpdateStatus();
     if(($ConnectionCount == 0) && $DieWhenIdle) {      if(($ConnectionCount == 0) && $DieWhenIdle) {
  #   &child_exit(0);
  #  Create a lock file since there will be a time window  
  #  between our exit and the parent's picking up the listen  
  #  during which no listens will be done on the  
  #  lonnet client socket.  
  #  
  my $lock_file = GetLoncSocketPath().".lock";  
  open(LOCK,">$lock_file");  
  print LOCK "Contents not important";  
  close(LOCK);  
   
  exit(0);  
     }      }
  }   }
     } else {      } else {
Line 1177  sub MakeLondConnection { Line 1205  sub MakeLondConnection {
  #   #
  my $Socket = $Connection->GetSocket();   my $Socket = $Connection->GetSocket();
  if($Socket eq undef) {   if($Socket eq undef) {
     die "did not get a socket from the connection";      &child_exit(-1, "did not get a socket from the connection");
  } else {   } else {
     &Debug(9,"MakeLondConnection got socket: ".$Socket);      &Debug(9,"MakeLondConnection got socket: ".$Socket);
  }   }
Line 1491  sub SetupLoncListener { Line 1519  sub SetupLoncListener {
     unless ($socket =IO::Socket::UNIX->new(Local  => $SocketName,      unless ($socket =IO::Socket::UNIX->new(Local  => $SocketName,
     Listen => 250,       Listen => 250, 
     Type   => SOCK_STREAM)) {      Type   => SOCK_STREAM)) {
  die "Failed to create a lonc listner socket";   if($I_am_child) {
       &child_exit(-1, "Failed to create a lonc listener socket");
    } else {
       die "Failed to create a lonc listner socket";
    }
     }      }
     return $socket;      return $socket;
 }  }
Line 1621  sub ChildProcess { Line 1653  sub ChildProcess {
  undef         $parent_dispatchers{$listener};   undef         $parent_dispatchers{$listener};
   
     }      }
     $I_am_child    = 1; # Seems like in spite of it all I'm still getting      $I_am_child    = 1; # Seems like in spite of it all I may still getting
                                 # parent event dispatches.                                   # parent event dispatches.. flag I'm a child.
   
   
     #      #
Line 1679  sub ChildProcess { Line 1711  sub ChildProcess {
     my $ret = Event::loop(); #  Start the main event loop.      my $ret = Event::loop(); #  Start the main event loop.
           
           
     die "Main event loop exited!!!";      &child_exit (-1,"Main event loop exited!!!");
 }  }
   
 #  Create a new child for host passed in:  #  Create a new child for host passed in:
Line 1716  sub CreateChild { Line 1748  sub CreateChild {
 #    a connection request arrives.  We must:  #    a connection request arrives.  We must:
 #     Start a child process to accept the connection request.  #     Start a child process to accept the connection request.
 #     Kill our listen on the socket.  #     Kill our listen on the socket.
 #     Setup an event to handle the child process exit. (SIGCHLD).  
 # Parameter:  # Parameter:
 #    event       - The event object that was created to monitor this socket.  #    event       - The event object that was created to monitor this socket.
 #                  event->w->fd is the socket.  #                  event->w->fd is the socket.
Line 1821  sub listen_on_all_unix_sockets { Line 1852  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:  #  Parent process logic pass 1:
 #   For each entry in the hosts table, we will  #   For each entry in the hosts table, we will
Line 1893  ShowStatus("Parent keeping the flock"); Line 1957  ShowStatus("Parent keeping the flock");
   
   
 if ($DieWhenIdle) {  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;      $Event::DebugLevel = $DebugLevel;
     Debug(9, "Parent entering event loop");      Debug(9, "Parent entering event loop");
     my $ret = Event::loop();      my $ret = Event::loop();

Removed from v.1.62  
changed lines
  Added in v.1.64


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>