You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@httpd.apache.org by Dean Gaudet <dg...@arctic.org> on 1997/11/04 09:54:37 UTC

[PATCH] night of the dead apache

Roy, this seems to fix the bug for me.  I did a bunch of trussing against
the children and tried a bunch of signals and this seems to deal with all
of them except SIGKILL, as expected. 

Note it's kind of a hack using a register_cleanup against pconf.  Well,
no, it's actually a nice way to do things.  But I'm not sure why we're
doing a destroy_pool(pconf) in the httpd children.  There's a few fuzy
areas here that should be looked at for 2.0. 

Dean

Index: main/http_main.c
===================================================================
RCS file: /export/home/cvs/apachen/src/main/http_main.c,v
retrieving revision 1.243
diff -u -r1.243 http_main.c
--- http_main.c	1997/11/03 10:11:42	1.243
+++ http_main.c	1997/11/04 08:51:07
@@ -333,18 +333,31 @@
 #elif defined (USE_PTHREAD_SERIALIZED_ACCEPT)
 
 /* This code probably only works on Solaris ... but it works really fast
- * on Solaris
+ * on Solaris.  Note that pthread mutexes are *NOT* released when a task
+ * dies ... the task has to free it itself.  So we block signals and
+ * try to be nice about releasing the mutex.
  */
 
 #include <pthread.h>
 
-static pthread_mutex_t *accept_mutex;
+static pthread_mutex_t *accept_mutex = (void *)(caddr_t) -1;
+static sigset_t accept_block_mask;
+static sigset_t accept_previous_mask;
+
+static void accept_mutex_child_cleanup(void *data)
+{
+    if (accept_mutex != (void *)(caddr_t)-1) {
+	pthread_mutex_unlock(accept_mutex);
+    }
+}
 
 static void accept_mutex_cleanup(void)
 {
-    if (munmap((caddr_t) accept_mutex, sizeof(*accept_mutex))) {
+    if (accept_mutex != (void *)(caddr_t)-1
+	&& munmap((caddr_t) accept_mutex, sizeof(*accept_mutex))) {
 	perror("munmap");
     }
+    accept_mutex = (void *)(caddr_t)-1;
 }
 
 static void accept_mutex_init(pool *p)
@@ -376,10 +389,20 @@
 	perror("pthread_mutex_init");
 	exit(1);
     }
+    sigfillset(&accept_block_mask);
+    sigdelset(&accept_block_mask, SIGHUP);
+    sigdelset(&accept_block_mask, SIGTERM);
+    sigdelset(&accept_block_mask, SIGUSR1);
+    register_cleanup(pconf, NULL, accept_mutex_child_cleanup,
+	accept_mutex_child_cleanup);
 }
 
 static void accept_mutex_on()
 {
+    if (sigprocmask(SIG_BLOCK, &accept_block_mask, &accept_previous_mask)) {
+	perror("sigprocmask(SIG_BLOCK)");
+	exit (1);
+    }
     if (pthread_mutex_lock(accept_mutex)) {
 	perror("pthread_mutex_lock");
 	exit(1);
@@ -391,6 +414,10 @@
     if (pthread_mutex_unlock(accept_mutex)) {
 	perror("pthread_mutex_unlock");
 	exit(1);
+    }
+    if (sigprocmask(SIG_SETMASK, &accept_previous_mask, NULL)) {
+	perror("sigprocmask(SIG_SETMASK)");
+	exit (1);
     }
 }