dgaudet 97/08/01 23:49:36
Modified: src http_main.c CHANGES
Log:
- exponential spawning and SIGUSR1 were interacting a bit badly with each
other (while 1; kill -USR1 would quickly fill the scoreboard)
- reduce the need to call signal() for SIGUSR1, SIGPIPE, and SIGALRM
- properly mark all the signal related variables as volatile
Revision Changes Path
1.193 +46 -26 apache/src/http_main.c
Index: http_main.c
===================================================================
RCS file: /export/home/cvs/apache/src/http_main.c,v
retrieving revision 1.192
retrieving revision 1.193
diff -u -r1.192 -r1.193
--- http_main.c 1997/08/02 00:58:27 1.192
+++ http_main.c 1997/08/02 06:49:32 1.193
@@ -375,12 +375,12 @@
* one timeout in progress at a time...
*/
-static APACHE_TLS conn_rec * current_conn;
-static APACHE_TLS request_rec *timeout_req;
-static APACHE_TLS const char *timeout_name = NULL;
-static APACHE_TLS int alarms_blocked = 0;
-static APACHE_TLS int alarm_pending = 0;
-static APACHE_TLS int exit_after_unblock = 0;
+static APACHE_TLS conn_rec * volatile current_conn;
+static APACHE_TLS request_rec * volatile timeout_req;
+static APACHE_TLS const char * volatile timeout_name = NULL;
+static APACHE_TLS int volatile alarms_blocked = 0;
+static APACHE_TLS int volatile alarm_pending = 0;
+static APACHE_TLS int volatile exit_after_unblock = 0;
#ifndef NO_USE_SIGACTION
/*
@@ -414,7 +414,7 @@
alarm_pending = 1;
return;
}
-
+
if (!current_conn) {
ap_longjmp (jmpbuffer, 1);
}
@@ -487,11 +487,20 @@
}
-static APACHE_TLS void (*alarm_fn)(int) = NULL;
+static APACHE_TLS void (* volatile alarm_fn)(int) = NULL;
#ifdef WIN32
static APACHE_TLS unsigned int alarm_expiry_time = 0;
#endif /* WIN32 */
+#ifndef WIN32
+static void alrm_handler (int sig)
+{
+ if (alarm_fn) {
+ (*alarm_fn)(sig);
+ }
+}
+#endif
+
unsigned int
set_callback_and_alarm(void (*fn)(int), int x)
{
@@ -512,10 +521,8 @@
alarm_expiry_time = time(NULL) + x;
}
#else
- if(x)
+ if(x) {
alarm_fn = fn;
- if (alarm_fn != fn) {
- signal(SIGALRM, fn);
}
old = alarm(x);
#endif
@@ -1500,17 +1507,21 @@
}
}
-static int deferred_die;
+static int volatile usr1_just_die = 1;
+static int volatile deferred_die;
-static void deferred_die_handler (int sig)
+static void usr1_handler (int sig)
{
+ if (usr1_just_die) {
+ just_die (sig);
+ }
deferred_die = 1;
}
/* volatile just in case */
-static volatile int restart_pending;
-static volatile int is_graceful;
-static volatile int generation;
+static int volatile restart_pending;
+static int volatile is_graceful;
+static int volatile generation;
static void restart (int sig)
{
@@ -2205,6 +2216,8 @@
#ifndef __EMX__
signal(SIGURG, timeout);
#endif
+ signal(SIGPIPE, timeout);
+ signal(SIGALRM, alrm_handler);
while (1) {
BUFF *conn_io;
@@ -2214,7 +2227,8 @@
* we can exit cleanly. Since we're between connections right
* now it's the right time to exit, but we might be blocked in a
* system call when the graceful restart request is made. */
- signal (SIGUSR1, just_die);
+ usr1_just_die = 1;
+ signal (SIGUSR1, usr1_handler);
/*
* (Re)initialize this child to a pre-connection state.
@@ -2223,7 +2237,6 @@
alarm(0); /* Cancel any outstanding alarms. */
timeout_req = NULL; /* No request in progress */
current_conn = NULL;
- signal(SIGPIPE, timeout);
clear_pool (ptrans);
@@ -2269,7 +2282,7 @@
* defer the exit
*/
deferred_die = 0;
- signal (SIGUSR1, deferred_die_handler);
+ usr1_just_die = 0;
for (;;) {
clen = sizeof(sa_client);
csd = accept(sd, &sa_client, &clen);
@@ -2295,7 +2308,7 @@
}
/* go around again, safe to die */
- signal (SIGUSR1, just_die);
+ usr1_just_die = 1;
if (deferred_die) {
/* ok maybe not, see ya later */
child_exit_modules(pconf, server_conf);
@@ -2367,10 +2380,9 @@
while ((r = read_request(current_conn)) != NULL) {
- /* ok we've read the request... it's a little too late
- * to do a graceful restart, so ignore them for now.
+ /* read_request_line has already done a
+ * signal (SIGUSR1, SIG_IGN);
*/
- signal (SIGUSR1, SIG_IGN);
(void)update_child_status(child_num, SERVER_BUSY_WRITE, r);
@@ -2406,7 +2418,8 @@
* connections to close before receiving a response because
* of network latencies and server timeouts.
*/
- signal (SIGUSR1, just_die);
+ usr1_just_die = 1;
+ signal (SIGUSR1, usr1_handler);
}
/*
@@ -2520,6 +2533,7 @@
#ifndef MAX_SPAWN_RATE
#define MAX_SPAWN_RATE (32)
#endif
+static int hold_off_on_exponential_spawning;
static void perform_idle_server_maintenance (void)
{
@@ -2596,9 +2610,11 @@
++i;
}
/* the next time around we want to spawn twice as many if this
- * wasn't good enough
+ * wasn't good enough, but not if we've just done a graceful
*/
- if (idle_spawn_rate < MAX_SPAWN_RATE) {
+ if (hold_off_on_exponential_spawning) {
+ --hold_off_on_exponential_spawning;
+ } else if (idle_spawn_rate < MAX_SPAWN_RATE) {
idle_spawn_rate *= 2;
}
}
@@ -2680,6 +2696,10 @@
if (!is_graceful) {
startup_children (remaining_children_to_start);
remaining_children_to_start = 0;
+ } else {
+ /* give the system some time to recover before kicking into
+ * exponential mode */
+ hold_off_on_exponential_spawning = 10;
}
log_error ("Server configured -- resuming normal operations",
1.380 +2 -2 apache/src/CHANGES
Index: CHANGES
===================================================================
RCS file: /export/home/cvs/apache/src/CHANGES,v
retrieving revision 1.379
retrieving revision 1.380
diff -u -r1.379 -r1.380
--- CHANGES 1997/08/02 00:58:24 1.379
+++ CHANGES 1997/08/02 06:49:33 1.380
@@ -6,8 +6,8 @@
was a bug where the client socket was being close()d twice due a still
registered cleanup. [Dean Gaudet]
- *) A few cleanups were made to reduce unneeded time() and getpid()
- calls. [Dean Gaudet]
+ *) A few cleanups were made to reduce time(), getpid(), and signal() calls.
+ [Dean Gaudet]
*) PORT: AIX >= 4.2 requires -lm due to libc changes.
[Jason Venner <[EMAIL PROTECTED]>] PR#667