--- loncom/loncnew	2004/06/17 22:37:06	1.49
+++ loncom/loncnew	2004/08/30 11:01:04	1.52
@@ -2,7 +2,7 @@
 # The LearningOnline Network with CAPA
 # lonc maintains the connections to remote computers
 #
-# $Id: loncnew,v 1.49 2004/06/17 22:37:06 foxr Exp $
+# $Id: loncnew,v 1.52 2004/08/30 11:01:04 foxr Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -82,7 +82,7 @@ my $ClientConnection = 0;	# Uniquifier f
 
 my $DebugLevel = 0;
 my $NextDebugLevel= 2;		# So Sigint can toggle this.
-my $IdleTimeout= 3600;		# Wait an hour before pruning connections.
+my $IdleTimeout= 600;		# Wait 10 minutes before pruning connections.
 
 my $LogTransactions = 0;	# When True, all transactions/replies get logged.
 
@@ -265,7 +265,7 @@ sub ShowStatus {
 sub SocketTimeout {
     my $Socket = shift;
     Log("WARNING", "A socket timeout was detected");
-    Debug(0, " SocketTimeout called: ");
+    Debug(5, " SocketTimeout called: ");
     $Socket->Dump(0);
     if(exists($ActiveTransactions{$Socket})) {
 	FailTransaction($ActiveTransactions{$Socket});
@@ -274,7 +274,7 @@ sub SocketTimeout {
                                 # a connection failure:
     $ConnectionRetriesLeft--;
     if($ConnectionRetriesLeft <= 0) {
-	Log("CRITICAL", "Host marked dead: ".GetServerHost());
+	Log("CRITICAL", "Host marked DEAD: ".GetServerHost());
     }
 
 }
@@ -290,6 +290,9 @@ Invoked  each timer tick.
 
 
 sub Tick {
+    my ($Event)       = @_;
+    my $clock_watcher = $Event->w;
+
     my $client;
     if($ConnectionRetriesLeft > 0) {
 	ShowStatus(GetServerHost()." Connection count: ".$ConnectionCount
@@ -351,6 +354,7 @@ sub Tick {
     }
     if ($ConnectionCount == 0) {
 	$KeyMode = ""; 
+	$clock_watcher->cancel();
     }
 }
 
@@ -472,7 +476,7 @@ sub ClientWritable {
 	    } else {		# Partial string sent.
 		$Watcher->data(substr($Data, $result));
 		if($result == 0) {    # client hung up on us!!
-		    Log("INFO", "lonc pipe client hung up on us!");
+		    # Log("INFO", "lonc pipe client hung up on us!");
 		    $Watcher->cancel;
 		    $Socket->shutdown(2);
 		    $Socket->close();
@@ -600,7 +604,13 @@ Parameters:
 
 sub FailTransaction {
     my $transaction = shift;
-    Log("WARNING", "Failing transaction ".$transaction->getRequest());
+    
+    #  If the socket is dead, that's already logged.
+
+    if ($ConnectionRetriesLeft > 0) {
+	Log("WARNING", "Failing transaction "
+	    .$transaction->getRequest());
+    }
     Debug(1, "Failing transaction: ".$transaction->getRequest());
     if (!$transaction->isDeferred()) { # If the transaction is deferred we'll get to it.
 	my $client  = $transaction->getClient();
@@ -1134,7 +1144,9 @@ sub MakeLondConnection {
 			   data     => $Connection,
 			   desc => 'Connection to lond server');
 	$ActiveConnections{$Connection} = $event;
-	
+	if ($ConnectionCount == 0) {
+	    &SetupTimer;	# Need to handle timeouts with connections...
+	}
 	$ConnectionCount++;
 	Debug(4, "Connection count = ".$ConnectionCount);
 	if($ConnectionCount == 1) { # First Connection:
@@ -1521,7 +1533,6 @@ sub ChildProcess {
 		  cb       => \&ToggleDebug,
 		  data     => "INT");
 
-    SetupTimer();
     
     SetupLoncListener();
     
@@ -1544,9 +1555,10 @@ sub ChildProcess {
 #  Create a new child for host passed in:
 
 sub CreateChild {
+    my $host = shift;
+
     my $sigset = POSIX::SigSet->new(SIGINT);
     sigprocmask(SIG_BLOCK, $sigset);
-    my $host = shift;
     $RemoteHost = $host;
     Log("CRITICAL", "Forking server for ".$host);
     my $pid          = fork;
@@ -1817,17 +1829,33 @@ sub KillThemAll {
     local($SIG{CHLD}) = 'IGNORE';      # Our children >will< die.
     foreach my $pid (keys %ChildHash) {
 	my $serving = $ChildHash{$pid};
-	Debug(2, "Killing lonc for $serving pid = $pid");
-	ShowStatus("Killing lonc for $serving pid = $pid");
-	Log("CRITICAL", "Killing lonc for $serving pid = $pid");
+	ShowStatus("Nicely Killing lonc for $serving pid = $pid");
+	Log("CRITICAL", "Nicely Killing lonc for $serving pid = $pid");
 	kill 'QUIT' => $pid;
-	delete($ChildHash{$pid});
     }
-    my $execdir = $perlvar{'lonDaemons'};
-    unlink("$execdir/logs/lonc.pid");
+
 
 }
 
+
+#
+#  Kill all children via KILL.  Just in case the
+#  first shot didn't get them.
+
+sub really_kill_them_all_dammit
+{
+    Debug(2, "Kill them all Dammit");
+    local($SIG{CHLD} = 'IGNORE'); # In case some purist reenabled them.
+    foreach my $pid (keys %ChildHash) {
+	my $serving = $ChildHash{$pid};
+	&ShowStatus("Nastily killing lonc for $serving pid = $pid");
+	Log("CRITICAL", "Nastily killing lonc for $serving pid = $pid");
+	kill 'KILL' => $pid;
+	delete($ChildHash{$pid});
+	my $execdir = $perlvar{'lonDaemons'};
+	unlink("$execdir/logs/lonc.pid");
+    }
+}
 =pod
 
 =head1 Terminate
@@ -1837,7 +1865,15 @@ Terminate the system.
 =cut
 
 sub Terminate {
-    KillThemAll;
+    &Log("CRITICAL", "Asked to kill children.. first be nice...");
+    &KillThemAll;
+    #
+    #  By now they really should all be dead.. but just in case 
+    #  send them all SIGKILL's after a bit of waiting:
+
+    sleep(4);
+    &Log("CRITICAL", "Now kill children nasty");
+    &really_kill_them_all_dammit;
     Log("CRITICAL","Master process exiting");
     exit 0;