[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();