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/06 11:47:03 UTC
cvs commit: apachen/src/main conf.h http_main.c
dgaudet 97/11/06 02:47:03
Modified: src CHANGES
src/main conf.h http_main.c
Log:
Papa Roy said I could commit this. Fix USE_PTHREAD_SERIALIZED_ACCEPT, I
totally didn't do it right the first time.
Reviewed by: Roy Fielding
Revision Changes Path
1.488 +3 -6 apachen/src/CHANGES
Index: CHANGES
===================================================================
RCS file: /export/home/cvs/apachen/src/CHANGES,v
retrieving revision 1.487
retrieving revision 1.488
diff -u -r1.487 -r1.488
--- CHANGES 1997/11/06 03:03:08 1.487
+++ CHANGES 1997/11/06 10:46:58 1.488
@@ -1,10 +1,7 @@
Changes with Apache 1.3b3
-
- *) Restored USE_FCNTL_SERIALIZED_ACCEPT as the default for Solaris2,
- since the PTHREAD mechanism was losing locks on Solaris 2.5.0.
- You can now set -DUSE_SYSVSEM_SERIALIZED_ACCEPT or
- -DUSE_PTHREAD_SERIALIZED_ACCEPT in Configuration if you want to
- test the other two methods. [Roy Fielding]
+
+ *) Solaris >= 2.5 was totally broken due to a mess up using pthread
+ mutexes. [Roy Fielding, Dean Gaudet]
*) OS/2 Port updated; it should be possible to build OS/2 from the same
sources as Unix now. [Brian Havard <br...@kheldar.apana.org.au>]
1.153 +2 -2 apachen/src/main/conf.h
Index: conf.h
===================================================================
RCS file: /export/home/cvs/apachen/src/main/conf.h,v
retrieving revision 1.152
retrieving revision 1.153
diff -u -r1.152 -r1.153
--- conf.h 1997/11/06 02:57:23 1.152
+++ conf.h 1997/11/06 10:47:00 1.153
@@ -125,8 +125,8 @@
#define HAVE_SYS_RESOURCE_H
#define bzero(a,b) memset(a,0,b)
#if !defined(USE_SYSVSEM_SERIALIZED_ACCEPT) && \
- !defined(USE_PTHREAD_SERIALIZED_ACCEPT)
-#define USE_FCNTL_SERIALIZED_ACCEPT
+ !defined(USE_FCNTL_SERIALIZED_ACCEPT)
+#define USE_PTHREAD_SERIALIZED_ACCEPT
#endif
#define NEED_UNION_SEMUN
#define HAVE_MMAP
1.245 +47 -3 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.244
retrieving revision 1.245
diff -u -r1.244 -r1.245
--- http_main.c 1997/11/05 12:48:17 1.244
+++ http_main.c 1997/11/06 10:47:01 1.245
@@ -333,18 +333,33 @@
#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 int have_accept_mutex;
+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
+ && have_accept_mutex) {
+ 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,14 +391,25 @@
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);
}
+ have_accept_mutex = 1;
}
static void accept_mutex_off()
@@ -391,6 +417,24 @@
if (pthread_mutex_unlock(accept_mutex)) {
perror("pthread_mutex_unlock");
exit(1);
+ }
+ /* There is a slight race condition right here... if we were to die right
+ * now, we'd do another pthread_mutex_unlock. Now, doing that would let
+ * another process into the mutex. pthread mutexes are designed to be
+ * fast, as such they don't have protection for things like testing if the
+ * thread owning a mutex is actually unlocking it (or even any way of
+ * testing who owns the mutex).
+ *
+ * If we were to unset have_accept_mutex prior to releasing the mutex
+ * then the race could result in the server unable to serve hits. Doing
+ * it this way means that the server can continue, but an additional
+ * child might be in the critical section ... at least it's still serving
+ * hits.
+ */
+ have_accept_mutex = 0;
+ if (sigprocmask(SIG_SETMASK, &accept_previous_mask, NULL)) {
+ perror("sigprocmask(SIG_SETMASK)");
+ exit (1);
}
}