httpd-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Marc Slemko <ma...@znep.com>
Subject [PATCH] murderous HUP
Date Tue, 18 Feb 1997 02:52:12 GMT
Ok, how about this one?

It adds very very little extra delay if child processes exit normally.
Note that this one reverts back to waiting for each one instead of
waiting after each try because it gets messy trying to mess around
with doing a waitpid on a group of not-yet-exited child processes; if
we are doing a minimal wait, we can really only do it on one child
at a time without getting messy.  I don't see this as being a 
problem; if that many child processes are hanging around you need
help.

Index: http_main.c
===================================================================
RCS file: /export/home/cvs/apache/src/http_main.c,v
retrieving revision 1.122
diff -c -r1.122 http_main.c
*** http_main.c	1997/02/17 11:05:02	1.122
--- http_main.c	1997/02/18 02:44:47
***************
*** 1030,1037 ****
      for (i = 0; i < HARD_SERVER_LIMIT; ++i) {
  	int pid = scoreboard_image->servers[i].pid;
  
! 	if (pid != my_pid && pid != 0)
! 	    waitpid (scoreboard_image->servers[i].pid, &status, 0);
      }
  }
  
--- 1030,1086 ----
      for (i = 0; i < HARD_SERVER_LIMIT; ++i) {
  	int pid = scoreboard_image->servers[i].pid;
  
! 	if (pid != my_pid && pid != 0) { 
! 	    int waitret = 0,
! 		tries = 1;
! 
! 	    while (waitret == 0 && tries <= 4) {
! 		int waittime = 1; /* in usecs */
! 		struct timeval tv;
! 	    
! 		/* don't want to hold up progress any more than 
! 		 * necessary, so keep checking to see if the child
! 		 * has exited with an exponential backoff.
! 		 * Currently set for a maximum wait of a bit over
! 		 * four seconds.
! 		 */
! 		while (((waitret = waitpid(pid, &status, WNOHANG)) == 0) &&
! 			 waittime < 3000000) {
! 		       tv.tv_sec = waittime / 1000000;
! 		       tv.tv_usec = waittime % 1000000;
! 		       waittime = waittime * 2;
! 		       select(0, NULL, NULL, NULL, &tv);
! 		}
! 		if (waitret == 0) {
! 		    switch (tries) {
! 		    case 1:
! 			/* perhaps it missed the SIGHUP, lets try again */
! 			log_printf(server_conf, "child process %d did not exit, sending another SIGHUP", pid);
! 			kill(pid, SIGHUP);
! 			break;
! 		    case 2:
! 			/* ok, now it's being annoying */
! 			log_printf(server_conf, "child process %d still did not exit, sending a SIGTERM", pid);
! 			kill(pid, SIGTERM);
! 			break;
! 		    case 3:
! 			/* die child scum */
! 			log_printf(server_conf, "child process %d still did not exit, sending a SIGKILL", pid);
! 			kill(pid, SIGKILL);
! 			break;
! 		    case 4:
! 			/* gave it our best shot, but alas...  If this really 
! 			 * is a child we are trying to kill and it really hasn't
! 			 * exited, we will likely fail to bind to the port
! 			 * after the restart.
! 			 */
! 			log_printf(server_conf, "could not make child process %d exit, attempting to continue
anyway", pid);
! 			break;
! 		    }
! 		}
! 		tries++;
! 	    }
! 	}
      }
  }
  


Mime
View raw message