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 };