[LON-CAPA-cvs] cvs: loncom / loncnew

foxr lon-capa-cvs@mail.lon-capa.org
Mon, 04 Oct 2004 11:30:45 -0000


foxr		Mon Oct  4 07:30:45 2004 EDT

  Modified files:              
    /loncom	loncnew 
  Log:
  Add child exit handling to server trim branch of the develoment.  Note:
  The other signals are still not appropriately handled.  Therefore do not
  yet set DieWhenIdle true unless you are just playing around... and certainly 
  not in production servers.
  
  
Index: loncom/loncnew
diff -u loncom/loncnew:1.62 loncom/loncnew:1.63
--- loncom/loncnew:1.62	Mon Oct  4 06:30:50 2004
+++ loncom/loncnew	Mon Oct  4 07:30:45 2004
@@ -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 @@
 #    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 @@
     }
 }
 
+#   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 @@
 
 
 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();