You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by dg...@hyperreal.org on 1997/11/03 11:11:44 UTC
cvs commit: apachen/src/main http_main.c
dgaudet 97/11/03 02:11:44
Modified: src CHANGES
src/main http_main.c
Log:
Fix a mild race condition in unblock_alarms() involving a SIGALRM showing
up after a SIGTERM.
PR: 1211
Reviewed by: Marc Slemko, Martin Kraemer
Revision Changes Path
1.484 +3 -0 apachen/src/CHANGES
Index: CHANGES
===================================================================
RCS file: /export/home/cvs/apachen/src/CHANGES,v
retrieving revision 1.483
retrieving revision 1.484
diff -u -r1.483 -r1.484
--- CHANGES 1997/11/03 04:33:16 1.483
+++ CHANGES 1997/11/03 10:11:39 1.484
@@ -1,5 +1,8 @@
Changes with Apache 1.3b3
+ *) A mild SIGTERM/SIGALRM race condition was eliminated.
+ [Dean Gaudet] PR#1211
+
*) Warn user that default path has changed if /usr/local/etc/httpd
is found on the system. [Lars Eilebrecht]
1.243 +28 -27 apachen/src/main/http_main.c
Index: http_main.c
===================================================================
RCS file: /export/home/cvs/apachen/src/main/http_main.c,v
retrieving revision 1.242
retrieving revision 1.243
diff -u -r1.242 -r1.243
--- http_main.c 1997/11/01 22:15:59 1.242
+++ http_main.c 1997/11/03 10:11:42 1.243
@@ -678,6 +678,14 @@
}
#endif
+/* a clean exit from a child with proper cleanup */
+static void __attribute__((noreturn)) clean_child_exit(int code)
+{
+ child_exit_modules(pconf, server_conf);
+ destroy_pool(pconf);
+ exit(code);
+}
+
void timeout(int sig)
{ /* Also called on SIGPIPE */
char errstr[MAX_STRING_LEN];
@@ -688,6 +696,9 @@
alarm_pending = 1;
return;
}
+ if (exit_after_unblock) {
+ clean_child_exit(0);
+ }
if (!current_conn) {
ap_longjmp(jmpbuffer, 1);
@@ -760,10 +771,16 @@
--alarms_blocked;
if (alarms_blocked == 0) {
if (exit_after_unblock) {
+ /* We have a couple race conditions to deal with here, we can't
+ * allow a timeout that comes in this small interval to allow
+ * the child to jump back to the main loop. Instead we block
+ * alarms again, and then note that exit_after_unblock is
+ * being dealt with. We choose this way to solve this so that
+ * the common path through unblock_alarms() is really short.
+ */
+ ++alarms_blocked;
exit_after_unblock = 0;
- child_exit_modules(pconf, server_conf);
- destroy_pool(pconf);
- exit(0);
+ clean_child_exit(0);
}
if (alarm_pending) {
alarm_pending = 0;
@@ -1964,9 +1981,7 @@
exit_after_unblock = 1;
}
else {
- child_exit_modules(pconf, server_conf);
- destroy_pool(pconf);
- exit(0);
+ clean_child_exit(0);
}
}
@@ -2668,16 +2683,12 @@
sync_scoreboard_image();
if (scoreboard_image->global.exit_generation >= generation) {
- child_exit_modules(pconf, server_conf);
- destroy_pool(pconf);
- exit(0);
+ clean_child_exit(0);
}
if ((max_requests_per_child > 0
&& ++requests_this_child >= max_requests_per_child)) {
- child_exit_modules(pconf, server_conf);
- destroy_pool(pconf);
- exit(0);
+ clean_child_exit(0);
}
(void) update_child_status(my_child_num, SERVER_READY, (request_rec *) NULL);
@@ -2700,9 +2711,7 @@
if (errno == EFAULT) {
aplog_error(APLOG_MARK, APLOG_ERR, server_conf,
"select: (listen) fatal, child exiting");
- child_exit_modules(pconf, server_conf);
- destroy_pool(pconf);
- exit(1);
+ clean_child_exit(1);
}
#endif
aplog_error(APLOG_MARK, APLOG_ERR, server_conf, "select: (listen)");
@@ -2733,9 +2742,7 @@
break;
if (deferred_die) {
/* we didn't get a socket, and we were told to die */
- child_exit_modules(pconf, server_conf);
- destroy_pool(pconf);
- exit(0);
+ clean_child_exit(0);
}
}
@@ -2758,18 +2765,14 @@
usr1_just_die = 1;
if (deferred_die) {
/* ok maybe not, see ya later */
- child_exit_modules(pconf, server_conf);
- destroy_pool(pconf);
- exit(0);
+ clean_child_exit(0);
}
/* or maybe we missed a signal, you never know on systems
* without reliable signals
*/
sync_scoreboard_image();
if (scoreboard_image->global.exit_generation >= generation) {
- child_exit_modules(pconf, server_conf);
- destroy_pool(pconf);
- exit(0);
+ clean_child_exit(0);
}
}
@@ -2855,9 +2858,7 @@
sync_scoreboard_image();
if (scoreboard_image->global.exit_generation >= generation) {
bclose(conn_io);
- child_exit_modules(pconf, server_conf);
- destroy_pool(pconf);
- exit(0);
+ clean_child_exit(0);
}
/* In case we get a graceful restart while we're blocked