You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by mc...@apache.org on 2006/02/28 17:38:11 UTC

svn commit: r381696 - in /httpd/httpd/branches/1.3.x/src: include/ap_alloc.h main/buff.c main/http_main.c os/tpf/os.c os/tpf/os.h

Author: mccreedy
Date: Tue Feb 28 08:38:08 2006
New Revision: 381696

URL: http://svn.apache.org/viewcvs?rev=381696&view=rev
Log:
TPF platform-specific changes:
   Ensure children close their sockets upon shutdown.
   Fix KeepAliveTimeOut and TimeOut processing.
   Implement SIGUSR1 (graceful restart) and SIGHUP (restart now).

Modified:
    httpd/httpd/branches/1.3.x/src/include/ap_alloc.h
    httpd/httpd/branches/1.3.x/src/main/buff.c
    httpd/httpd/branches/1.3.x/src/main/http_main.c
    httpd/httpd/branches/1.3.x/src/os/tpf/os.c
    httpd/httpd/branches/1.3.x/src/os/tpf/os.h

Modified: httpd/httpd/branches/1.3.x/src/include/ap_alloc.h
URL: http://svn.apache.org/viewcvs/httpd/httpd/branches/1.3.x/src/include/ap_alloc.h?rev=381696&r1=381695&r2=381696&view=diff
==============================================================================
--- httpd/httpd/branches/1.3.x/src/include/ap_alloc.h (original)
+++ httpd/httpd/branches/1.3.x/src/include/ap_alloc.h Tue Feb 28 08:38:08 2006
@@ -279,13 +279,8 @@
  * up with timeout handling in general...
  */
 
-#ifdef TPF
-#define ap_block_alarms() (0)
-#define ap_unblock_alarms() (0)
-#else
 API_EXPORT(void) ap_block_alarms(void);
 API_EXPORT(void) ap_unblock_alarms(void);
-#endif /* TPF */
 
 /* Common cases which want utility support..
  * the note_cleanups_for_foo routines are for 

Modified: httpd/httpd/branches/1.3.x/src/main/buff.c
URL: http://svn.apache.org/viewcvs/httpd/httpd/branches/1.3.x/src/main/buff.c?rev=381696&r1=381695&r2=381696&view=diff
==============================================================================
--- httpd/httpd/branches/1.3.x/src/main/buff.c (original)
+++ httpd/httpd/branches/1.3.x/src/main/buff.c Tue Feb 28 08:38:08 2006
@@ -282,7 +282,10 @@
         FD_SET(fb->fd_in, &fds);
         tv.tv_sec = 1;
         tv.tv_usec = 0;
-        rv = ap_select(fb->fd_in + 1, &fds, NULL, NULL, &tv);
+        do {
+           rv = ap_select(fb->fd_in + 1, &fds, NULL, NULL, &tv);
+           ap_check_signals();
+        } while((rv == 0) && ap_check_alarm());
         if (rv > 0)
             rv = ap_read(fb, buf, nbyte);
     }

Modified: httpd/httpd/branches/1.3.x/src/main/http_main.c
URL: http://svn.apache.org/viewcvs/httpd/httpd/branches/1.3.x/src/main/http_main.c?rev=381696&r1=381695&r2=381696&view=diff
==============================================================================
--- httpd/httpd/branches/1.3.x/src/main/http_main.c (original)
+++ httpd/httpd/branches/1.3.x/src/main/http_main.c Tue Feb 28 08:38:08 2006
@@ -479,6 +479,13 @@
 static void clean_child_exit(int code) __attribute__ ((noreturn));
 static void clean_child_exit(int code)
 {
+#ifdef TPF
+    /* run ptrans cleanups since TPF's sockets don't close upon exit */
+    if (ptrans) { 
+       ap_clear_pool(ptrans);
+    }
+#endif /* TPF */
+
     if (pchild) {
         /* make sure the accept mutex is released before calling child
          * exit hooks and cleanups...  otherwise, modules can segfault
@@ -1557,7 +1564,6 @@
 }
 
 
-#ifndef TPF
 /*
  * These two called from alloc.c to protect its critical sections...
  * Note that they can nest (as when destroying the sub_pools of a pool
@@ -1597,7 +1603,6 @@
 	}
     }
 }
-#endif /* TPF */
 
 #ifndef NETWARE
 static APACHE_TLS void (*volatile alarm_fn) (int) = NULL;
@@ -1609,6 +1614,9 @@
 #if !defined(WIN32)  && !defined(NETWARE)
 static void alrm_handler(int sig)
 {
+#ifdef TPF41
+    signal(sig, exit);
+#endif
     if (alarm_fn) {
 	(*alarm_fn) (sig);
     }
@@ -1687,7 +1695,26 @@
 }
 #endif /* WIN32 */
 
+#ifdef TPF
+API_EXPORT(int) ap_check_alarm(void)
+{
+   int i;
+
+#ifdef OPTIMIZE_TIMEOUTS
+   /* just pull the timeout from the scoreboard */
+   ap_sync_scoreboard_image();
+   i = ap_scoreboard_image->servers[my_child_num].timeout_len;
+#else
+   i = ap_set_callback_and_alarm(alarm_fn, 3); /* determine time left */
+   /* the 3 seconds is just an arbitrary amount of time to keep the alarm
+      from expiring before it is reset on this next line: */
+   ap_set_callback_and_alarm(alarm_fn, i); /* restore time left */
+#endif
+
+   return i;                               /* return the time left */
+}
 
+#endif /* TPF */
 
 /* reset_timeout (request_rec *) resets the timeout in effect,
  * as long as it hasn't expired already.
@@ -2814,6 +2841,9 @@
 		break;
 	    }
 	}
+#ifdef TPF
+        AP_OS_RECLAIM_LOOP_ADJUSTMENTS
+#endif
 #ifndef NO_OTHER_CHILD
 	for (ocr = other_children; ocr; ocr = nocr) {
 	    nocr = ocr->next;
@@ -4671,11 +4701,6 @@
 	}
 
 	SAFE_ACCEPT(accept_mutex_off());	/* unlock after "accept" */
-
-#ifdef TPF
-	if (csd == 0)                       /* 0 is invalid socket for TPF */
-	    continue;
-#endif
 
 	/* We've got a socket, let's at least process one request off the
 	 * socket before we accept a graceful restart request.

Modified: httpd/httpd/branches/1.3.x/src/os/tpf/os.c
URL: http://svn.apache.org/viewcvs/httpd/httpd/branches/1.3.x/src/os/tpf/os.c?rev=381696&r1=381695&r2=381696&view=diff
==============================================================================
--- httpd/httpd/branches/1.3.x/src/os/tpf/os.c (original)
+++ httpd/httpd/branches/1.3.x/src/os/tpf/os.c Tue Feb 28 08:38:08 2006
@@ -110,18 +110,38 @@
 
 int tpf_accept(int sockfd, struct sockaddr *peer, int *paddrlen)
 {
+    extern pid_t tpf_parent_pid;
     int socks[1];
     int rv;
 
-    ap_check_signals();
     socks[0] = sockfd;
-    rv = select(socks, 1, 0, 0, TPF_ACCEPT_SECS_TO_BLOCK * 1000);
-    errno = sock_errno();
+    rv = select(socks, 1, 0, 0, 1 * 1000);
+    ap_check_signals();
+    if ((rv == 0) && (errno == 0)) {
+       /* select timed out */
+       errno = EINTR; /* make errno look like accept was interruped */
+       /* now's a good time to make sure our parent didn't abnormally exit */
+       if (getppid() == 1) {
+          /* our parent is gone... close the socket so Apache can restart
+             (it shouldn't still be open but we're taking no chances) */
+          closesocket(sockfd);
+          ap_log_error(APLOG_MARK, APLOG_ALERT|APLOG_NOERRNO, NULL,
+                       "child %d closing the socket because getppid()"
+                       " returned 1 instead of parent pid %d",
+                       getpid(), tpf_parent_pid);
+          errno = 0;
+       }
+       return -1;
+    }
+    /* paranoid check for rv == 0 and errno != 0, should never happen */
+    if (rv == 0) {
+       rv = -1;
+    }
+
     if(rv>0) {
         rv = accept(sockfd, peer, paddrlen);
         errno = sock_errno();
     }    
-    ap_check_signals();
     return rv;
 }
    
@@ -339,14 +359,6 @@
     int count;
     listen_rec *lr;
 
-    fflush(stdin);
-    if (dup2(fileno(sock_fp), STDIN_FILENO) == -1)
-        ap_log_error(APLOG_MARK, APLOG_CRIT, s,
-        "unable to replace stdin with sock device driver");
-    fflush(stdout);
-    if (dup2(fileno(sock_fp), STDOUT_FILENO) == -1)
-        ap_log_error(APLOG_MARK, APLOG_CRIT, s,
-        "unable to replace stdout with sock device driver");
     input_parms.generation = ap_my_generation;
 #ifdef USE_SHMGET_SCOREBOARD
     input_parms.scoreboard_heap = ap_scoreboard_image;
@@ -424,22 +436,23 @@
 
     ap_check_signals();
 
-    /* check that the program activation number hasn't changed */
-        current_acn = (int *)cinfc_fast(CINFC_CMMACNUM);
-        if (ecbp2()->ce2acn != *current_acn) {
-        return 1;  /* shutdown */
-        }
-
     /* check our InetD status */
     if (inetd_getServerStatus(server) != INETD_SERVER_STATUS_ACTIVE) {
         return 1;  /* shutdown */
     }
 
-    /* if DAEMON model, make sure parent is still around */
+    /* if DAEMON model, make sure CLTZ parent is still around */
     if (zinet_model == INETD_IDCF_MODEL_DAEMON) {
         if (getppid() == 1) {
             return 1;  /* shutdown */
         }
+    } else {
+        /* this is the NOLISTEN model (INETD_IDCF_MODEL_NOLISTEN) */
+        /* check that the program activation number hasn't changed */
+        current_acn = (int *)cinfc_fast(CINFC_CMMACNUM);
+        if (ecbp2()->ce2acn != *current_acn) {
+           return 1;  /* shutdown */
+        }
     }
 
     return 0;  /* keep on running... */
@@ -451,8 +464,8 @@
        will close socket in case we happen to abend. */
     sprintf(sockfilename, "/dev/tpf.socket.file/%.8X", sd);
     sock_fp = fopen(sockfilename, "r+");
-    /* arrange to close on exec or restart */
-    ap_note_cleanups_for_file_ex(p, sock_fp, 1);
+    /* we don't want the children to inherit this fd */
+    fcntl(fileno(sock_fp), F_SETFD, FD_CLOEXEC);
     sock_sd = sd;
 }
 
@@ -744,6 +757,8 @@
 */
 int killpg(pid_t pgrp, int sig)
 {
+    struct ev0bk evnblock;
+    struct timeval tv;
     int i;
 
     ap_sync_scoreboard_image();
@@ -755,11 +770,27 @@
             kill(pid, sig);
         }
     }
-    /* allow time for the signals to get to the children */
-    sleep(1);
-    /* get idle children's attention by closing the socket */
-    closesocket(sock_sd);
-    sleep(1);
+    /* Allow time for the signals to get to the children.
+       Note that ap_select is signal interruptable,
+       so we use evnwc instead. */
+    i = TPF_SHUTDOWN_SIGNAL_DELAY;
+    evnblock.evnpstinf.evnbkc1 = 1; /* nbr of posts needed */
+    evntc(&evnblock, EVENT_CNT, 'N', i, EVNTC_1052);
+    evnwc(&evnblock, EVENT_CNT);
+
+    if (sig == SIGTERM) {
+       /* get idle children's attention by closing the socket */
+       closesocket(sock_sd);
+       /* and close the /dev/tpf.socket.file special file */
+       fclose(sock_fp);
+       /* Allow the children some more time.
+          Note that ap_select is signal interruptable,
+          so we use evnwc instead. */
+    i = TPF_SHUTDOWN_CLOSING_DELAY;
+    evnblock.evnpstinf.evnbkc1 = 1; /* nbr of posts needed */
+    evntc(&evnblock, EVENT_CNT, 'N', i, EVNTC_1052);
+    evnwc(&evnblock, EVENT_CNT);
+    }
 
     return(0);
 }
@@ -809,7 +840,6 @@
     printf(" -D HAVE_SYSLOG\n");
 #endif
 
-    printf(" -D TPF_ACCEPT_SECS_TO_BLOCK=%i\n", TPF_ACCEPT_SECS_TO_BLOCK);
     /* round SCOREBOARD_MAINTENANCE_INTERVAL up to seconds */
     i = (SCOREBOARD_MAINTENANCE_INTERVAL + 999999) / 1000000;
     if (i == 1) {

Modified: httpd/httpd/branches/1.3.x/src/os/tpf/os.h
URL: http://svn.apache.org/viewcvs/httpd/httpd/branches/1.3.x/src/os/tpf/os.h?rev=381696&r1=381695&r2=381696&view=diff
==============================================================================
--- httpd/httpd/branches/1.3.x/src/os/tpf/os.h (original)
+++ httpd/httpd/branches/1.3.x/src/os/tpf/os.h Tue Feb 28 08:38:08 2006
@@ -179,12 +179,6 @@
 
 #include "ap_config.h"
 
-/* TPF_ACCEPT_SECS_TO_BLOCK is the number of seconds to block while
-   waiting to accept a new request in the ap_accept/tpf_accept function */
-#ifndef TPF_ACCEPT_SECS_TO_BLOCK
-#define TPF_ACCEPT_SECS_TO_BLOCK 1
-#endif
-
 #if !defined(INLINE) && defined(USE_GNU_INLINE)
 /* Compiler supports inline, so include the inlineable functions as
  * part of the header
@@ -244,6 +238,29 @@
  
 /* definitions for the file descriptor inheritance table */
 #define TPF_FD_LIST_SIZE 4000
+
+/* seconds to delay after shutdown/restart signals have been sent */
+#ifndef TPF_SHUTDOWN_SIGNAL_DELAY
+#define TPF_SHUTDOWN_SIGNAL_DELAY 2
+#endif
+
+/* seconds to delay after closing the port as part of shutdown */
+#ifndef TPF_SHUTDOWN_CLOSING_DELAY
+#define TPF_SHUTDOWN_CLOSING_DELAY 3
+#endif
+
+#ifndef AP_OS_RECLAIM_LOOP_ADJUSTMENTS
+/* expedite shutdown/restart in http_main.c's reclaim_child_processes
+   function by skipping some of the loop iterations                  */
+#define AP_OS_RECLAIM_LOOP_ADJUSTMENTS                                \
+        if (tries == 4) {                                             \
+           tries += 1; /* skip try #5 */                              \
+        } else {                                                      \
+           if (tries == 8) {                                          \
+              tries += 3; /* skip try #9, #10, & #11 */               \
+           }                                                          \
+        }
+#endif /* AP_OS_RECLAIM_LOOP_ADJUSTMENTS */
 
 enum FILE_TYPE { PIPE_OUT = 1, PIPE_IN, PIPE_ERR };