httpd-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Marc Slemko <ma...@znep.com>
Subject [PATCH] revised death wish on HUP patch
Date Fri, 14 Feb 1997 07:19:20 GMT
Happy with this one?  

I'm not happy about the unconditional sleep(2), but the only other option
is to block until the child exits but that is what we are trying to avoid.
A timeout in the waitpid() would be better, but I don't think it is
practical right now.

I have tested this patch, but not on a server that has the problem.  I
will probably do that tomorrow.

Index: http_main.c
===================================================================
RCS file: /export/home/cvs/apache/src/http_main.c,v
retrieving revision 1.118
diff -c -r1.118 http_main.c
*** http_main.c	1997/02/10 21:22:20	1.118
--- http_main.c	1997/02/14 07:12:16
***************
*** 1011,1025 ****
  
  void reclaim_child_processes ()
  {
!     int i, status;
      int my_pid = getpid();
  
      sync_scoreboard_image();
-     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);
      }
  }
  
--- 1011,1081 ----
  
  void reclaim_child_processes ()
  {
!     int i, status, childhung = 1, tries = 0;
      int my_pid = getpid();
+     int waitret;
  
      sync_scoreboard_image();
  
!     /* need short pause to have some hope that the child processes
!      * have had a chance to exit.  Unfortunate because it slows
!      * down all HUPs a small bit, but while blocking while waiting
!      * for the child to die avoids this, it can cause hangs.
!      */
!     sleep(2);
! 
!     /* sometimes child processes don't get the SIGHUP.  We need to be 
!      * sure that we don't block waiting for the child to die of
!      * natural causes; first try nicely to kill it, then get
!      * nasty and do everything we can to make it die.
!      */
!     while (childhung && tries <=4) {
! 	childhung = 0;
! 	for (i = 0; i < HARD_SERVER_LIMIT; ++i) {
! 	    int pid = scoreboard_image->servers[i].pid;
! 
! 	    if (pid != my_pid && pid != 0) {
! 		waitret = waitpid(pid, &status, WNOHANG);
! 		if (waitret == 0) {
! 		    childhung++;
! 		    switch (tries) {
! 		    case 0:
! 			/* first time through, we assume it is just slow */
! 			log_printf(server_conf, "child process %d did not exit (just slow?), will try again",
pid);
! 			break;
! 		    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;
! 		    }
! 		} else {
! 		    /* child gone, delete from scoreboard so 
! 		     * we don't worry about it any more */
! 		    update_child_status(i,SERVER_DEAD,NULL);
! 		}
! 	    }
! 	}
! 	if (childhung) sleep(3);
! 	tries++;
      }
  }


Mime
View raw message