You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@httpd.apache.org by Jim Jagielski <ji...@jaguNET.com> on 2001/08/30 21:54:24 UTC
[PATCH] Final version of AcceptMutex
Here's the final version of the patch to implement AcceptMutex. You'll
notice that SingleListen is removed. You'll also notice that I decided
to do some error handling if someone does something stupid like
AcceptMutex BiteMe. Instead of dieing, Apache will continue with the
default method. This implied that ap_default_mutex_method() needed
to bail if things were weird.
Enjoy...
Index: src/CHANGES
===================================================================
RCS file: /home/cvs/apache-1.3/src/CHANGES,v
retrieving revision 1.1701
diff -u -r1.1701 CHANGES
--- src/CHANGES 2001/08/29 13:32:06 1.1701
+++ src/CHANGES 2001/08/30 19:41:54
@@ -1,5 +1,15 @@
Changes with Apache 1.3.21
+ *) Addition of the AcceptMutex runtime directive. The accept mutex
+ method is now runtime controllable. The suite of available methods
+ per platform is defined at compile time (with HAVE_FOO_SERIALIZED_ACCEPT
+ noting that the method is available and works, and
+ USE_FOO_SERIALIZED_ACCEPT noting that it should be the default
+ method in absense of any AcceptMutex line, or via AcceptMutex default)
+ and selectable at runtime. The full (current) suite is uslock,
+ pthread, sysvsem, fcntl, flock, os2sem, tpfcore and none, but
+ not all platforms accept all methods. [Jim Jagielski]
+
*) Parallel to a change in Apache-2.0, the manual directory was
moved out of the DocumentRoot tree to simplify the separation
of private content&configuration from server's on-line
Index: src/PORTING
===================================================================
RCS file: /home/cvs/apache-1.3/src/PORTING,v
retrieving revision 1.34
diff -u -r1.34 PORTING
--- src/PORTING 1999/12/07 12:19:48 1.34
+++ src/PORTING 2001/08/30 19:41:54
@@ -244,13 +244,20 @@
USE_MMAP_FILES:
Enable the use of mmap() for sending static files. If HAVE_MMAP
is not #defined, this will automatically be unset.
+--
USE_*_SERIALIZED_ACCEPT:
See htdocs/manual/misc/perf-tuning.html for an in-depth discussion of
- why these are required. These are choices for implementing a semaphore
- between children entering accept(). A complete port should define one
- of these, many may work and it's worthwhile timing them. Without these
- the server will not implement multiple Listen directives reliably.
+ why these are required. These are choices for implementing a mutex
+ between children entering accept(). A complete port should define at
+ least one of these, many may work and it's worthwhile timing them.
+ Without these the server will not implement multiple Listen directives
+ reliably. Please note that as of 1.3.21, we can set the method at runtime.
+ To so do, we specify which methods are available at compile time
+ with the HAVE_FOO_SERIALIZED_ACCEPT #defines. The USE_FOO_SERIALIZED_ACCEPT
+ is used to pick the default version of all those available. These are
+ set at compile time usually in include/ap_config.h but can also be
+ done at the compile command line.
USE_FCNTL_SERIALIZED_ACCEPT:
Use fcntl() to implement the semaphore.
Index: src/include/ap_config.h
===================================================================
RCS file: /home/cvs/apache-1.3/src/include/ap_config.h,v
retrieving revision 1.309
diff -u -r1.309 ap_config.h
--- src/include/ap_config.h 2001/06/22 12:43:53 1.309
+++ src/include/ap_config.h 2001/08/30 19:41:57
@@ -118,7 +118,7 @@
typedef int rlim_t;
#define JMP_BUF sigjmp_buf
#define NO_LONG_DOUBLE
-#define USE_FLOCK_SERIALIZED_ACCEPT
+#define HAVE_FLOCK_SERIALIZED_ACCEPT
#define _BSD_SOURCE
#define EAGAIN EWOULDBLOCK
int initgroups (char *, int);
@@ -154,7 +154,7 @@
#define S_IREAD S_IRUSR
#define S_IWRITE S_IWUSR
#define PF_INET AF_INET
-#define USE_FCNTL_SERIALIZED_ACCEPT
+#define HAVE_FCNTL_SERIALIZED_ACCEPT
#elif defined(SUNOS4)
#define HAVE_GMTOFF 1
@@ -170,7 +170,7 @@
typedef int rlim_t;
#define memmove(a,b,c) bcopy(b,a,c)
#define NO_LINGCLOSE
-#define USE_FLOCK_SERIALIZED_ACCEPT
+#define HAVE_FLOCK_SERIALIZED_ACCEPT
#define NEED_DIFFTIME
#define HAVE_SYSLOG 1
@@ -179,6 +179,8 @@
#define NO_KILLPG
#undef NO_SETSID
#define bzero(a,b) memset(a,0,b)
+#define HAVE_SYSVSEM_SERIALIZED_ACCEPT
+#define HAVE_FCNTL_SERIALIZED_ACCEPT
#if !defined(USE_SYSVSEM_SERIALIZED_ACCEPT) && \
!defined(USE_PTHREAD_SERIALIZED_ACCEPT)
#define USE_FCNTL_SERIALIZED_ACCEPT
@@ -197,6 +199,10 @@
* there's some weird conflict with non-BSD signals */
#define NO_KILLPG
#undef NO_SETSID
+#define HAVE_FLOCK_SERIALIZED_ACCEPT
+#define HAVE_FCNTL_SERIALIZED_ACCEPT
+#define HAVE_USLOCK_SERIALIZED_ACCEPT
+#define HAVE_SYSVSEM_SERIALIZED_ACCEPT
#if !defined(USE_FLOCK_SERIALIZED_ACCEPT) && \
!defined(USE_USLOCK_SERIALIZED_ACCEPT) && \
!defined(USE_SYSVSEM_SERIALIZED_ACCEPT)
@@ -226,7 +232,7 @@
#undef HAVE_GMTOFF
#define NO_KILLPG
#undef NO_SETSID
-#define USE_FCNTL_SERIALIZED_ACCEPT
+#define HAVE_FCNTL_SERIALIZED_ACCEPT
#ifndef _HPUX_SOURCE
#define _HPUX_SOURCE
#endif
@@ -245,12 +251,12 @@
#define HAVE_SHMGET
#define USE_SHMGET_SCOREBOARD
#undef HAVE_GMTOFF
-#define USE_FCNTL_SERIALIZED_ACCEPT
+#define HAVE_FCNTL_SERIALIZED_ACCEPT
/* feeling brave? want to try using POSIX mutexes? */
/* #define HAVE_MMAP */
/* #define USE_MMAP_SCOREBOARD */
/* #define USE_MMAP_FILES */
-/* #define USE_PTHREAD_SERIALIZED_ACCEPT */
+/* #define HAVE_PTHREAD_SERIALIZED_ACCEPT */
#define NO_KILLPG
#undef NO_SETSID
#define HAVE_SYSLOG
@@ -274,6 +280,7 @@
#ifdef NEED_RLIM_T
typedef int rlim_t;
#endif
+#define HAVE_FCNTL_SERIALIZED_ACCEPT
#if !defined(USE_PTHREAD_SERIALIZED_ACCEPT)
#define USE_FCNTL_SERIALIZED_ACCEPT
#endif
@@ -307,7 +314,7 @@
#define USE_MMAP_FILES
#define NO_LONG_DOUBLE
#define HAVE_SYSLOG 1
-#define USE_FLOCK_SERIALIZED_ACCEPT
+#define HAVE_FLOCK_SERIALIZED_ACCEPT
#define SINGLE_LISTEN_UNSERIALIZED_ACCEPT
#elif defined(PARAGON)
@@ -329,7 +336,7 @@
#define HAVE_SYSLOG 1
#define USE_MMAP_FILES 1
#define USE_MMAP_SCOREBOARD 1
-#define USE_FCNTL_SERIALIZED_ACCEPT 1
+#define HAVE_FCNTL_SERIALIZED_ACCEPT 1
#define JMP_BUF sigjmp_buf
#undef NO_SETSID
#if SEQUENT < 40
@@ -432,6 +439,8 @@
#define HAVE_SNPRINTF
#define JMP_BUF jmp_buf
#define USE_LONGJMP
+#define HAVE_FLOCK_SERIALIZED_ACCEPT
+#define HAVE_FCNTL_SERIALIZED_ACCEPT
#define USE_FLOCK_SERIALIZED_ACCEPT
#define SINGLE_LISTEN_UNSERIALIZED_ACCEPT
@@ -475,7 +484,8 @@
* in new-httpd archives for performance numbers indicating these
* are the right choices for linux 2.2.x and later
*/
-#define USE_SYSVSEM_SERIALIZED_ACCEPT
+#define HAVE_SYSVSEM_SERIALIZED_ACCEPT
+#define HAVE_FCNTL_SERIALIZED_ACCEPT
#define SINGLE_LISTEN_UNSERIALIZED_ACCEPT
#include <sys/sem.h>
#if _SEM_SEMUN_UNDEFINED
@@ -515,7 +525,7 @@
#elif defined(SCO5)
-#define USE_FCNTL_SERIALIZED_ACCEPT
+#define HAVE_FCNTL_SERIALIZED_ACCEPT
#define HAVE_MMAP 1
#define USE_MMAP_SCOREBOARD
#define USE_MMAP_FILES
@@ -547,7 +557,7 @@
#undef NO_SETSID
#define NEED_STRDUP
/* fcntl() locking is expensive with NFS */
-#define USE_FLOCK_SERIALIZED_ACCEPT
+#define HAVE_FLOCK_SERIALIZED_ACCEPT
#define SINGLE_LISTEN_UNSERIALIZED_ACCEPT
#define HAVE_SHMGET 1
#define USE_SHMGET_SCOREBOARD
@@ -576,6 +586,7 @@
#endif /* MPRAS */
#define bzero(a,b) memset(a,0,b)
/* A lot of SVR4 systems need this */
+#define HAVE_FCNTL_SERIALIZED_ACCEPT
#ifndef USE_SYSVSEM_SERIALIZED_ACCEPT
#define USE_FCNTL_SERIALIZED_ACCEPT
#endif
@@ -593,7 +604,7 @@
#elif defined(UW)
#if UW < 700
-#define USE_FCNTL_SERIALIZED_ACCEPT
+#define HAVE_FCNTL_SERIALIZED_ACCEPT
#define NO_LINGCLOSE
#define NO_KILLPG
#endif
@@ -627,7 +638,7 @@
#endif
#define bzero(a,b) memset(a,0,b)
/* A lot of SVR4 systems need this */
-#define USE_FCNTL_SERIALIZED_ACCEPT
+#define HAVE_FCNTL_SERIALIZED_ACCEPT
#define ap_inet_addr inet_network
#define HAVE_SYSLOG 1
@@ -646,7 +657,7 @@
#define HAVE_MMAP 1
#define USE_MMAP_SCOREBOARD
#define USE_MMAP_FILES
-#define USE_FLOCK_SERIALIZED_ACCEPT
+#define HAVE_FLOCK_SERIALIZED_ACCEPT
#define SINGLE_LISTEN_UNSERIALIZED_ACCEPT
#elif defined(UTS21)
@@ -700,7 +711,7 @@
(defined(__FreeBSD_version) && (__FreeBSD_version < 220000))
typedef quad_t rlim_t;
#endif
-#define USE_FLOCK_SERIALIZED_ACCEPT
+#define HAVE_FLOCK_SERIALIZED_ACCEPT
#define SINGLE_LISTEN_UNSERIALIZED_ACCEPT
#define HAVE_SYSLOG 1
#define SYS_SIGLIST sys_siglist
@@ -726,7 +737,7 @@
#include <unix.h>
#define HAVE_MMAP 1
#define USE_POSIX_SCOREBOARD
-#define USE_FLOCK_SERIALIZED_ACCEPT
+#define HAVE_FLOCK_SERIALIZED_ACCEPT
#define SINGLE_LISTEN_UNSERIALIZED_ACCEPT
#define HAVE_SYSLOG 1
@@ -734,8 +745,9 @@
#undef HAVE_GMTOFF
#undef USE_MMAP_SCOREBOARD
#undef USE_SHMGET_SCOREBOARD
-#undef USE_FCNTL_SERIALIZED_ACCEPT
-#undef USE_FLOCK_SERIALIZED_ACCEPT
+#undef HAVE_FCNTL_SERIALIZED_ACCEPT
+#undef HAVE_FLOCK_SERIALIZED_ACCEPT
+#define HAVE_NONE_SERIALIZED_ACCEPT
#define USE_LONGJMP
#undef NO_KILLPG
#undef NO_SETSID
@@ -753,7 +765,7 @@
#define NO_KILLPG
#undef NO_SETSID
#define bzero(a,b) memset(a,0,b)
-#define USE_FCNTL_SERIALIZED_ACCEPT
+#define HAVE_FCNTL_SERIALIZED_ACCEPT
#define HAVE_MMAP 1
#define USE_MMAP_SCOREBOARD
#define USE_MMAP_FILES
@@ -774,7 +786,7 @@
#define MAXSOCKETS 2048
#define USE_OS2_SCOREBOARD
#define NO_RELIABLE_PIPED_LOGS
-#define USE_OS2SEM_SERIALIZED_ACCEPT
+#define HAVE_OS2SEM_SERIALIZED_ACCEPT
#define SINGLE_LISTEN_UNSERIALIZED_ACCEPT
#define NO_SLACK
#define FOPEN_REQUIRES_T
@@ -788,7 +800,7 @@
#ifndef __MACHTEN_68K__
#define __MACHTEN_68K__
#endif
-#define USE_FLOCK_SERIALIZED_ACCEPT
+#define HAVE_FLOCK_SERIALIZED_ACCEPT
#define NO_USE_SIGACTION
#define JMP_BUF sigjmp_buf
#define USE_LONGJMP
@@ -796,7 +808,7 @@
#else
#define HAVE_SHMGET 1
#define USE_SHMGET_SCOREBOARD
-#define USE_FCNTL_SERIALIZED_ACCEPT
+#define HAVE_FCNTL_SERIALIZED_ACCEPT
#endif
/* Convex OS v11 */
@@ -821,7 +833,7 @@
#undef NO_SETSID
#define HAVE_SHMGET 1
#define USE_SHMGET_SCOREBOARD
-#define USE_FCNTL_SERIALIZED_ACCEPT
+#define HAVE_FCNTL_SERIALIZED_ACCEPT
#define HAVE_SYSLOG 1
#elif defined(NEWSOS)
@@ -909,7 +921,7 @@
#define USE_SHMGET_SCOREBOARD
/*#define USE_TPF_SCOREBOARD*/
#define USE_TPF_ACCEPT
-#define USE_TPF_CORE_SERIALIZED_ACCEPT
+#define HAVE_TPF_CORE_SERIALIZED_ACCEPT
#define USE_TPF_SELECT
#define S_IREAD S_IRUSR
#define S_IWRITE S_IWUSR
@@ -931,7 +943,7 @@
#define USE_SHMGET_SCOREBOARD
#define USE_MMAP_FILES
#define NEED_UNION_SEMUN
-#define USE_SYSVSEM_SERIALIZED_ACCEPT
+#define HAVE_SYSVSEM_SERIALIZED_ACCEPT
#define _POSIX_SOURCE
#include <signal.h>
#ifdef SIGDUMP /* SIGDUMP is not defined by OS/390 v1r2 */
@@ -1157,6 +1169,32 @@
#if defined(USE_SHMGET_SCOREBOARD) && (defined(NO_SHMGET) || !defined(HAVE_SHMGET))
#undef USE_SHMGET_SCOREBOARD
+#endif
+
+/* A USE_FOO_SERIALIZED_ACCEPT implies a HAVE_FOO_SERIALIZED_ACCEPT */
+#if defined(USE_USLOCK_SERIALIZED_ACCEPT) && !defined(HAVE_USLOCK_SERIALIZED_ACCEPT)
+#define HAVE_USLOCK_SERIALIZED_ACCEPT
+#endif
+#if defined(USE_PTHREAD_SERIALIZED_ACCEPT) && !defined(HAVE_PTHREAD_SERIALIZED_ACCEPT)
+#define HAVE_PTHREAD_SERIALIZED_ACCEPT
+#endif
+#if defined(USE_SYSVSEM_SERIALIZED_ACCEPT) && !defined(HAVE_SYSVSEM_SERIALIZED_ACCEPT)
+#define HAVE_SYSVSEM_SERIALIZED_ACCEPT
+#endif
+#if defined(USE_FCNTL_SERIALIZED_ACCEPT) && !defined(HAVE_FCNTL_SERIALIZED_ACCEPT)
+#define HAVE_FCNTL_SERIALIZED_ACCEPT
+#endif
+#if defined(USE_FLOCK_SERIALIZED_ACCEPT) && !defined(HAVE_FLOCK_SERIALIZED_ACCEPT)
+#define HAVE_FLOCK_SERIALIZED_ACCEPT
+#endif
+#if defined(USE_OS2SEM_SERIALIZED_ACCEPT) && !defined(HAVE_OS2SEM_SERIALIZED_ACCEPT)
+#define HAVE_OS2SEM_SERIALIZED_ACCEPT
+#endif
+#if defined(USE_TPF_CORE_SERIALIZED_ACCEPT) && !defined(HAVE_TPF_CORE_SERIALIZED_ACCEPT)
+#define HAVE_TPF_CORE_SERIALIZED_ACCEPT
+#endif
+#if defined(USE_NONE_SERIALIZED_ACCEPT) && !defined(HAVE_NONE_SERIALIZED_ACCEPT)
+#define HAVE_NONE_SERIALIZED_ACCEPT
#endif
#ifndef LOGNAME_MAX
Index: src/include/http_main.h
===================================================================
RCS file: /home/cvs/apache-1.3/src/include/http_main.h,v
retrieving revision 1.36
diff -u -r1.36 http_main.h
--- src/include/http_main.h 2001/01/15 17:04:34 1.36
+++ src/include/http_main.h 2001/08/30 19:41:58
@@ -130,6 +130,10 @@
void setup_signal_names(char *prefix);
+/* functions for determination and setting of accept() mutexing */
+char *ap_default_mutex_method(void);
+char *ap_init_mutex_method(char *t);
+
#ifndef NO_OTHER_CHILD
/*
* register an other_child -- a child which the main loop keeps track of
Index: src/lib/sdbm/sdbm_lock.c
===================================================================
RCS file: /home/cvs/apache-1.3/src/lib/sdbm/sdbm_lock.c,v
retrieving revision 1.1
diff -u -r1.1 sdbm_lock.c
--- src/lib/sdbm/sdbm_lock.c 2000/09/21 13:06:14 1.1
+++ src/lib/sdbm/sdbm_lock.c 2001/08/30 19:41:58
@@ -9,12 +9,13 @@
/* The locking support:
* Try to determine whether we should use fcntl() or flock().
* Would be better ap_config.h could provide this... :-(
+ * Small monkey business to ensure that fcntl is preferred,
+ * unless we specified USE_FLOCK_SERIALIZED_ACCEPT during compile.
*/
-#if defined(USE_FCNTL_SERIALIZED_ACCEPT)
+#if defined(HAVE_FCNTL_SERIALIZED_ACCEPT) && !defined(USE_FLOCK_SERIALIZED_ACCEPT)
#define USE_FCNTL 1
#include <fcntl.h>
-#endif
-#if defined(USE_FLOCK_SERIALIZED_ACCEPT)
+#elif defined(HAVE_FLOCK_SERIALIZED_ACCEPT)
#define USE_FLOCK 1
#include <sys/file.h>
#endif
Index: src/main/http_core.c
===================================================================
RCS file: /home/cvs/apache-1.3/src/main/http_core.c,v
retrieving revision 1.296
diff -u -r1.296 http_core.c
--- src/main/http_core.c 2001/07/13 07:32:44 1.296
+++ src/main/http_core.c 2001/08/30 19:42:06
@@ -1135,6 +1135,10 @@
}
return NULL;
}
+static const char *set_accept_mutex(cmd_parms *cmd, void *dummy, char *arg)
+{
+ return ap_init_mutex_method(arg);
+}
static const char *set_document_root(cmd_parms *cmd, void *dummy, char *arg)
{
@@ -3215,6 +3219,34 @@
(void*)XtOffsetOf(core_dir_config, limit_req_body),
OR_ALL, TAKE1,
"Limit (in bytes) on maximum size of request message body" },
+{ "AcceptMutex", set_accept_mutex, NULL, RSRC_CONF, TAKE1,
+ "Serialized Accept Mutex; the methods "
+#ifdef HAVE_USLOCK_SERIALIZED_ACCEPT
+ "'uslock' "
+#endif
+#ifdef HAVE_PTHREAD_SERIALIZED_ACCEPT
+ "'pthread' "
+#endif
+#ifdef HAVE_SYSVSEM_SERIALIZED_ACCEPT
+ "'sysvsem' "
+#endif
+#ifdef HAVE_FCNTL_SERIALIZED_ACCEPT
+ "'fcntl' "
+#endif
+#ifdef HAVE_FLOCK_SERIALIZED_ACCEPT
+ "'flock' "
+#endif
+#ifdef HAVE_OS2SEM_SERIALIZED_ACCEPT
+ "'os2sem' "
+#endif
+#ifdef HAVE_TPF_CORE_SERIALIZED_ACCEPT
+ "'tpfcore' "
+#endif
+#ifdef HAVE_NONE_SERIALIZED_ACCEPT
+ "'none' "
+#endif
+ "are compiled in"
+},
/* EBCDIC Conversion directives: */
#ifdef CHARSET_EBCDIC
Index: src/main/http_main.c
===================================================================
RCS file: /home/cvs/apache-1.3/src/main/http_main.c,v
retrieving revision 1.546
diff -u -r1.546 http_main.c
--- src/main/http_main.c 2001/08/10 01:14:29 1.546
+++ src/main/http_main.c 2001/08/30 19:42:21
@@ -258,6 +258,17 @@
time_t ap_restart_time=0;
API_VAR_EXPORT int ap_suexec_enabled = 0;
int ap_listenbacklog=0;
+
+struct accept_mutex_methods_s {
+ void (*child_init)(pool *p);
+ void (*init)(pool *p);
+ void (*on)(void);
+ void (*off)(void);
+ char *name;
+};
+typedef struct accept_mutex_methods_s accept_mutex_methods_s;
+accept_mutex_methods_s *amutex;
+
#ifdef SO_ACCEPTFILTER
int ap_acceptfilter =
#ifdef AP_ACCEPTFILTER_OFF
@@ -503,7 +514,20 @@
exit(code);
}
-#if defined(USE_FCNTL_SERIALIZED_ACCEPT) || defined(USE_FLOCK_SERIALIZED_ACCEPT)
+/*
+ * Start of accept() mutex fluff:
+ * Concept: Each method has it's own distinct set of mutex functions,
+ * which it shoves in a nice struct for us. We then pick
+ * which struct to use. We tell Apache which methods we
+ * support via HAVE_FOO_SERIALIZED_ACCEPT. We can
+ * specify the default via USE_FOO_SERIALIZED_ACCEPT
+ * (this pre-1.3.21 builds which use that at the command-
+ * line during builds work as expected). Without a set
+ * method, we pick the 1st from the following order:
+ * uslock, pthread, sysvsem, fcntl, flock, os2sem, tpfcore and none.
+ */
+
+#if defined(HAVE_FCNTL_SERIALIZED_ACCEPT) || defined(HAVE_FLOCK_SERIALIZED_ACCEPT)
static void expand_lock_fname(pool *p)
{
/* XXXX possibly bogus cast */
@@ -511,16 +535,14 @@
ap_server_root_relative(p, ap_lock_fname), (unsigned long)getpid());
}
#endif
-
-#if defined (USE_USLOCK_SERIALIZED_ACCEPT)
+#if defined (HAVE_USLOCK_SERIALIZED_ACCEPT)
#include <ulocks.h>
-
static ulock_t uslock = NULL;
-#define accept_mutex_child_init(x)
+#define accept_mutex_child_init_uslock(x)
-static void accept_mutex_init(pool *p)
+static void accept_mutex_init_uslock(pool *p)
{
ptrdiff_t old;
usptr_t *us;
@@ -551,7 +573,7 @@
}
}
-static void accept_mutex_on(void)
+static void accept_mutex_on_uslock(void)
{
switch (ussetlock(uslock)) {
case 1:
@@ -566,15 +588,24 @@
}
}
-static void accept_mutex_off(void)
+static void accept_mutex_off_uslock(void)
{
if (usunsetlock(uslock) == -1) {
perror("usunsetlock");
clean_child_exit(APEXIT_CHILDFATAL);
}
}
+
+accept_mutex_methods_s accept_mutex_uslock_s = {
+ NULL,
+ accept_mutex_init_uslock,
+ accept_mutex_on_uslock,
+ accept_mutex_off_uslock,
+ "uslock"
+};
+#endif
-#elif defined (USE_PTHREAD_SERIALIZED_ACCEPT)
+#if defined (HAVE_PTHREAD_SERIALIZED_ACCEPT)
/* This code probably only works on Solaris ... but it works really fast
* on Solaris. Note that pthread mutexes are *NOT* released when a task
@@ -589,7 +620,7 @@
static sigset_t accept_block_mask;
static sigset_t accept_previous_mask;
-static void accept_mutex_child_cleanup(void *foo)
+static void accept_mutex_child_cleanup_pthread(void *foo)
{
if (accept_mutex != (void *)(caddr_t)-1
&& have_accept_mutex) {
@@ -597,12 +628,12 @@
}
}
-static void accept_mutex_child_init(pool *p)
+static void accept_mutex_child_init_pthread(pool *p)
{
- ap_register_cleanup(p, NULL, accept_mutex_child_cleanup, ap_null_cleanup);
+ ap_register_cleanup(p, NULL, accept_mutex_child_cleanup_pthread, ap_null_cleanup);
}
-static void accept_mutex_cleanup(void *foo)
+static void accept_mutex_cleanup_pthread(void *foo)
{
if (accept_mutex != (void *)(caddr_t)-1
&& munmap((caddr_t) accept_mutex, sizeof(*accept_mutex))) {
@@ -611,7 +642,7 @@
accept_mutex = (void *)(caddr_t)-1;
}
-static void accept_mutex_init(pool *p)
+static void accept_mutex_init_pthread(pool *p)
{
pthread_mutexattr_t mattr;
int fd;
@@ -645,10 +676,10 @@
sigdelset(&accept_block_mask, SIGHUP);
sigdelset(&accept_block_mask, SIGTERM);
sigdelset(&accept_block_mask, SIGUSR1);
- ap_register_cleanup(p, NULL, accept_mutex_cleanup, ap_null_cleanup);
+ ap_register_cleanup(p, NULL, accept_mutex_cleanup_pthread, ap_null_cleanup);
}
-static void accept_mutex_on(void)
+static void accept_mutex_on_pthread(void)
{
int err;
@@ -670,7 +701,7 @@
ap_unblock_alarms();
}
-static void accept_mutex_off(void)
+static void accept_mutex_off_pthread(void)
{
int err;
@@ -691,8 +722,17 @@
clean_child_exit(1);
}
}
+
+accept_mutex_methods_s accept_mutex_pthread_s = {
+ accept_mutex_child_init_pthread,
+ accept_mutex_init_pthread,
+ accept_mutex_on_pthread,
+ accept_mutex_off_pthread,
+ "pthread"
+};
+#endif
-#elif defined (USE_SYSVSEM_SERIALIZED_ACCEPT)
+#if defined (HAVE_SYSVSEM_SERIALIZED_ACCEPT)
#include <sys/types.h>
#include <sys/ipc.h>
@@ -716,7 +756,7 @@
* means we have to be sure to clean this up or else we'll leak
* semaphores.
*/
-static void accept_mutex_cleanup(void *foo)
+static void accept_mutex_cleanup_sysvsem(void *foo)
{
union semun ick;
@@ -727,9 +767,9 @@
semctl(sem_id, 0, IPC_RMID, ick);
}
-#define accept_mutex_child_init(x)
+#define accept_mutex_child_init_sysvsem(x)
-static void accept_mutex_init(pool *p)
+static void accept_mutex_init_sysvsem(pool *p)
{
union semun ick;
struct semid_ds buf;
@@ -758,7 +798,7 @@
exit(APEXIT_INIT);
}
}
- ap_register_cleanup(p, NULL, accept_mutex_cleanup, ap_null_cleanup);
+ ap_register_cleanup(p, NULL, accept_mutex_cleanup_sysvsem, ap_null_cleanup);
/* pre-initialize these */
op_on.sem_num = 0;
@@ -769,7 +809,7 @@
op_off.sem_flg = SEM_UNDO;
}
-static void accept_mutex_on(void)
+static void accept_mutex_on_sysvsem(void)
{
while (semop(sem_id, &op_on, 1) < 0) {
if (errno != EINTR) {
@@ -779,7 +819,7 @@
}
}
-static void accept_mutex_off(void)
+static void accept_mutex_off_sysvsem(void)
{
while (semop(sem_id, &op_off, 1) < 0) {
if (errno != EINTR) {
@@ -788,20 +828,29 @@
}
}
}
+
+accept_mutex_methods_s accept_mutex_sysvsem_s = {
+ NULL,
+ accept_mutex_init_sysvsem,
+ accept_mutex_on_sysvsem,
+ accept_mutex_off_sysvsem,
+ "sysvsem"
+};
+#endif
-#elif defined(USE_FCNTL_SERIALIZED_ACCEPT)
+#if defined(HAVE_FCNTL_SERIALIZED_ACCEPT)
static struct flock lock_it;
static struct flock unlock_it;
static int lock_fd = -1;
-#define accept_mutex_child_init(x)
+#define accept_mutex_child_init_fcntl(x)
/*
* Initialize mutex lock.
* Must be safe to call this on a restart.
*/
-static void accept_mutex_init(pool *p)
+static void accept_mutex_init_fcntl(pool *p)
{
lock_it.l_whence = SEEK_SET; /* from current point */
@@ -825,7 +874,7 @@
unlink(ap_lock_fname);
}
-static void accept_mutex_on(void)
+static void accept_mutex_on_fcntl(void)
{
int ret;
@@ -842,7 +891,7 @@
}
}
-static void accept_mutex_off(void)
+static void accept_mutex_off_fcntl(void)
{
int ret;
@@ -858,11 +907,20 @@
}
}
-#elif defined(USE_FLOCK_SERIALIZED_ACCEPT)
+accept_mutex_methods_s accept_mutex_fcntl_s = {
+ NULL,
+ accept_mutex_init_fcntl,
+ accept_mutex_on_fcntl,
+ accept_mutex_off_fcntl,
+ "fcntl"
+};
+#endif
-static int lock_fd = -1;
+#if defined(HAVE_FLOCK_SERIALIZED_ACCEPT)
-static void accept_mutex_cleanup(void *foo)
+static int flock_fd = -1;
+
+static void accept_mutex_cleanup_flock(void *foo)
{
unlink(ap_lock_fname);
}
@@ -871,11 +929,11 @@
* Initialize mutex lock.
* Done by each child at it's birth
*/
-static void accept_mutex_child_init(pool *p)
+static void accept_mutex_child_init_flock(pool *p)
{
- lock_fd = ap_popenf(p, ap_lock_fname, O_WRONLY, 0600);
- if (lock_fd == -1) {
+ flock_fd = ap_popenf(p, ap_lock_fname, O_WRONLY, 0600);
+ if (flock_fd == -1) {
ap_log_error(APLOG_MARK, APLOG_EMERG, server_conf,
"Child cannot open lock file: %s", ap_lock_fname);
clean_child_exit(APEXIT_CHILDINIT);
@@ -886,24 +944,24 @@
* Initialize mutex lock.
* Must be safe to call this on a restart.
*/
-static void accept_mutex_init(pool *p)
+static void accept_mutex_init_flock(pool *p)
{
expand_lock_fname(p);
unlink(ap_lock_fname);
- lock_fd = ap_popenf(p, ap_lock_fname, O_CREAT | O_WRONLY | O_EXCL, 0600);
- if (lock_fd == -1) {
+ flock_fd = ap_popenf(p, ap_lock_fname, O_CREAT | O_WRONLY | O_EXCL, 0600);
+ if (flock_fd == -1) {
ap_log_error(APLOG_MARK, APLOG_EMERG, server_conf,
"Parent cannot open lock file: %s", ap_lock_fname);
exit(APEXIT_INIT);
}
- ap_register_cleanup(p, NULL, accept_mutex_cleanup, ap_null_cleanup);
+ ap_register_cleanup(p, NULL, accept_mutex_cleanup_flock, ap_null_cleanup);
}
-static void accept_mutex_on(void)
+static void accept_mutex_on_flock(void)
{
int ret;
- while ((ret = flock(lock_fd, LOCK_EX)) < 0 && errno == EINTR)
+ while ((ret = flock(flock_fd, LOCK_EX)) < 0 && errno == EINTR)
continue;
if (ret < 0) {
@@ -913,20 +971,29 @@
}
}
-static void accept_mutex_off(void)
+static void accept_mutex_off_flock(void)
{
- if (flock(lock_fd, LOCK_UN) < 0) {
+ if (flock(flock_fd, LOCK_UN) < 0) {
ap_log_error(APLOG_MARK, APLOG_EMERG, server_conf,
"flock: LOCK_UN: Error freeing accept lock. Exiting!");
clean_child_exit(APEXIT_CHILDFATAL);
}
}
+
+accept_mutex_methods_s accept_mutex_flock_s = {
+ accept_mutex_child_init_flock,
+ accept_mutex_init_flock,
+ accept_mutex_on_flock,
+ accept_mutex_off_flock,
+ "flock"
+};
+#endif
-#elif defined(USE_OS2SEM_SERIALIZED_ACCEPT)
+#if defined(HAVE_OS2SEM_SERIALIZED_ACCEPT)
static HMTX lock_sem = -1;
-static void accept_mutex_cleanup(void *foo)
+static void accept_mutex_cleanup_os2sem(void *foo)
{
DosReleaseMutexSem(lock_sem);
DosCloseMutexSem(lock_sem);
@@ -936,7 +1003,7 @@
* Initialize mutex lock.
* Done by each child at it's birth
*/
-static void accept_mutex_child_init(pool *p)
+static void accept_mutex_child_init_os2sem(pool *p)
{
int rc = DosOpenMutexSem(NULL, &lock_sem);
@@ -945,7 +1012,7 @@
"Child cannot open lock semaphore, rc=%d", rc);
clean_child_exit(APEXIT_CHILDINIT);
} else {
- ap_register_cleanup(p, NULL, accept_mutex_cleanup, ap_null_cleanup);
+ ap_register_cleanup(p, NULL, accept_mutex_cleanup_os2sem, ap_null_cleanup);
}
}
@@ -953,7 +1020,7 @@
* Initialize mutex lock.
* Must be safe to call this on a restart.
*/
-static void accept_mutex_init(pool *p)
+static void accept_mutex_init_os2sem(pool *p)
{
int rc = DosCreateMutexSem(NULL, &lock_sem, DC_SEM_SHARED, FALSE);
@@ -963,10 +1030,10 @@
exit(APEXIT_INIT);
}
- ap_register_cleanup(p, NULL, accept_mutex_cleanup, ap_null_cleanup);
+ ap_register_cleanup(p, NULL, accept_mutex_cleanup_os2sem, ap_null_cleanup);
}
-static void accept_mutex_on(void)
+static void accept_mutex_on_os2sem(void)
{
int rc = DosRequestMutexSem(lock_sem, SEM_INDEFINITE_WAIT);
@@ -977,7 +1044,7 @@
}
}
-static void accept_mutex_off(void)
+static void accept_mutex_off_os2sem(void)
{
int rc = DosReleaseMutexSem(lock_sem);
@@ -988,52 +1055,201 @@
}
}
-#elif defined(USE_TPF_CORE_SERIALIZED_ACCEPT)
+accept_mutex_methods_s accept_mutex_os2sem_s = {
+ accept_mutex_child_init_os2sem,
+ accept_mutex_init_os2sem,
+ accept_mutex_on_os2sem,
+ accept_mutex_off_os2sem,
+ "os2sem"
+};
+#endif
+#if defined(HAVE_TPF_CORE_SERIALIZED_ACCEPT)
+
static int tpf_core_held;
-static void accept_mutex_cleanup(void *foo)
+static void accept_mutex_cleanup_tpfcore(void *foo)
{
if(tpf_core_held)
coruc(RESOURCE_KEY);
}
-#define accept_mutex_init(x)
+#define accept_mutex_init_tpfcore(x)
-static void accept_mutex_child_init(pool *p)
+static void accept_mutex_child_init_tpfcore(pool *p)
{
- ap_register_cleanup(p, NULL, accept_mutex_cleanup, ap_null_cleanup);
+ ap_register_cleanup(p, NULL, accept_mutex_cleanup_tpfcore, ap_null_cleanup);
tpf_core_held = 0;
}
-static void accept_mutex_on(void)
+static void accept_mutex_on_tpfcore(void)
{
corhc(RESOURCE_KEY);
tpf_core_held = 1;
ap_check_signals();
}
-static void accept_mutex_off(void)
+static void accept_mutex_off_tpfcore(void)
{
coruc(RESOURCE_KEY);
tpf_core_held = 0;
ap_check_signals();
}
-#else
-/* Default --- no serialization. Other methods *could* go here,
- * as #elifs...
- */
+accept_mutex_methods_s accept_mutex_tpfcore_s = {
+ accept_mutex_child_init_tpfcore,
+ accept_mutex_init_tpfcore,
+ accept_mutex_on_tpfcore,
+ accept_mutex_off_tpfcore,
+ "tpfcore"
+};
+#endif
+
+/* Generally, HAVE_NONE_SERIALIZED_ACCEPT simply won't work but
+ * for testing purposes, here it is... */
+#if defined HAVE_NONE_SERIALIZED_ACCEPT
#if !defined(MULTITHREAD)
/* Multithreaded systems don't complete between processes for
* the sockets. */
#define NO_SERIALIZED_ACCEPT
-#define accept_mutex_child_init(x)
-#define accept_mutex_init(x)
-#define accept_mutex_on()
-#define accept_mutex_off()
+#endif
+
+accept_mutex_methods_s accept_mutex_none_s = {
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ "none"
+};
#endif
+
+#define AP_FPTR1(x,y) { if (x) ((* x)(y)); }
+#define AP_FPTR0(x) { if (x) ((* x)()); }
+
+#define accept_mutex_child_init(x) AP_FPTR1(amutex->child_init,x)
+#define accept_mutex_init(x) AP_FPTR1(amutex->init,x)
+#define accept_mutex_off() AP_FPTR0(amutex->off)
+#define accept_mutex_on() AP_FPTR0(amutex->on)
+
+char *ap_default_mutex_method(void)
+{
+ char *t;
+#if defined USE_USLOCK_SERIALIZED_ACCEPT
+ t = "uslock";
+#elif defined USE_PTHREAD_SERIALIZED_ACCEPT
+ t = "pthread";
+#elif defined USE_SYSVSEM_SERIALIZED_ACCEPT
+ t = "sysvsem";
+#elif defined USE_FCNTL_SERIALIZED_ACCEPT
+ t = "fcntl";
+#elif defined USE_FLOCK_SERIALIZED_ACCEPT
+ t = "flock";
+#elif defined USE_OS2SEM_SERIALIZED_ACCEPT
+ t = "os2sem";
+#elif defined USE_TPF_CORE_SERIALIZED_ACCEPT
+ t = "tpfcore";
+#elif defined USE_NONE_SERIALIZED_ACCEPT
+ t = "none";
+#else
+ t = "default";
#endif
+#if defined HAVE_USLOCK_SERIALIZED_ACCEPT
+ if ((!(strcasecmp(t,"default"))) || (!(strcasecmp(t,"uslock"))))
+ return "uslock";
+#endif
+#if defined HAVE_PTHREAD_SERIALIZED_ACCEPT
+ if ((!(strcasecmp(t,"default"))) || (!(strcasecmp(t,"pthread"))))
+ return "pthread";
+#endif
+#if defined HAVE_SYSVSEM_SERIALIZED_ACCEPT
+ if ((!(strcasecmp(t,"default"))) || (!(strcasecmp(t,"sysvsem"))))
+ return "sysvsem";
+#endif
+#if defined HAVE_FCNTL_SERIALIZED_ACCEPT
+ if ((!(strcasecmp(t,"default"))) || (!(strcasecmp(t,"fcntl"))))
+ return "fcntl";
+#endif
+#if defined HAVE_FLOCK_SERIALIZED_ACCEPT
+ if ((!(strcasecmp(t,"default"))) || (!(strcasecmp(t,"flock"))))
+ return "flock";
+#endif
+#if defined HAVE_OS2SEM_SERIALIZED_ACCEPT
+ if ((!(strcasecmp(t,"default"))) || (!(strcasecmp(t,"os2sem"))))
+ return "os2sem";
+#endif
+#if defined HAVE_TPF_CORE_SERIALIZED_ACCEPT
+ if ((!(strcasecmp(t,"default"))) || (!(strcasecmp(t,"tpfcore"))))
+ return "tpfcore";
+#endif
+#if defined HAVE_NONE_SERIALIZED_ACCEPT
+ if ((!(strcasecmp(t,"default"))) || (!(strcasecmp(t,"none"))))
+ return "none";
+#endif
+
+ fprintf(stderr, "No default accept serialization known!!\n");
+ exit(APEXIT_INIT);
+ /*NOTREACHED */
+ return "unknown";
+}
+
+char *ap_init_mutex_method(char *t)
+{
+ if (!(strcasecmp(t,"default")))
+ t = ap_default_mutex_method();
+
+#if defined HAVE_USLOCK_SERIALIZED_ACCEPT
+ if (!(strcasecmp(t,"uslock"))) {
+ amutex = &accept_mutex_uslock_s;
+ } else
+#endif
+#if defined HAVE_PTHREAD_SERIALIZED_ACCEPT
+ if (!(strcasecmp(t,"pthread"))) {
+ amutex = &accept_mutex_pthread_s;
+ } else
+#endif
+#if defined HAVE_SYSVSEM_SERIALIZED_ACCEPT
+ if (!(strcasecmp(t,"sysvsem"))) {
+ amutex = &accept_mutex_sysvsem_s;
+ } else
+#endif
+#if defined HAVE_FCNTL_SERIALIZED_ACCEPT
+ if (!(strcasecmp(t,"fcntl"))) {
+ amutex = &accept_mutex_fcntl_s;
+ } else
+#endif
+#if defined HAVE_FLOCK_SERIALIZED_ACCEPT
+ if (!(strcasecmp(t,"flock"))) {
+ amutex = &accept_mutex_flock_s;
+ } else
+#endif
+#if defined HAVE_OS2SEM_SERIALIZED_ACCEPT
+ if (!(strcasecmp(t,"os2sem"))) {
+ amutex = &accept_mutex_os2sem_s;
+ } else
+#endif
+#if defined HAVE_TPF_CORE_SERIALIZED_ACCEPT
+ if (!(strcasecmp(t,"tpfcore"))) {
+ amutex = &accept_mutex_tpfcore_s;
+ } else
+#endif
+#if defined HAVE_NONE_SERIALIZED_ACCEPT
+ if (!(strcasecmp(t,"none"))) {
+ amutex = &accept_mutex_none_s;
+ } else
+#endif
+ {
+ if (server_conf) {
+ ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_NOTICE, server_conf,
+ "Requested serialization method '%s' not available",t);
+ ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_NOTICE, server_conf,
+ "Using compiled-in default of '%s'", ap_default_mutex_method());
+ } else {
+ fprintf(stderr, "Requested serialization method '%s' not available;\n", t);
+ fprintf(stderr, "Using compiled-in default of '%s'\n", ap_default_mutex_method());
+ }
+ }
+ return NULL;
+}
/* On some architectures it's safe to do unserialized accept()s in the single
* Listen case. But it's never safe to do it in the case where there's
@@ -3712,22 +3928,31 @@
#endif
#ifdef NO_LINGCLOSE
printf(" -D NO_LINGCLOSE\n");
+#endif
+#ifdef HAVE_FCNTL_SERIALIZED_ACCEPT
+ printf(" -D HAVE_FCNTL_SERIALIZED_ACCEPT\n");
+#endif
+#ifdef HAVE_FLOCK_SERIALIZED_ACCEPT
+ printf(" -D HAVE_FLOCK_SERIALIZED_ACCEPT\n");
#endif
-#ifdef USE_FCNTL_SERIALIZED_ACCEPT
- printf(" -D USE_FCNTL_SERIALIZED_ACCEPT\n");
+#ifdef HAVE_USLOCK_SERIALIZED_ACCEPT
+ printf(" -D HAVE_USLOCK_SERIALIZED_ACCEPT\n");
#endif
-#ifdef USE_FLOCK_SERIALIZED_ACCEPT
- printf(" -D USE_FLOCK_SERIALIZED_ACCEPT\n");
+#ifdef HAVE_SYSVSEM_SERIALIZED_ACCEPT
+ printf(" -D HAVE_SYSVSEM_SERIALIZED_ACCEPT\n");
#endif
-#ifdef USE_USLOCK_SERIALIZED_ACCEPT
- printf(" -D USE_USLOCK_SERIALIZED_ACCEPT\n");
+#ifdef HAVE_PTHREAD_SERIALIZED_ACCEPT
+ printf(" -D HAVE_PTHREAD_SERIALIZED_ACCEPT\n");
#endif
-#ifdef USE_SYSVSEM_SERIALIZED_ACCEPT
- printf(" -D USE_SYSVSEM_SERIALIZED_ACCEPT\n");
+#ifdef HAVE_OS2SEM_SERIALIZED_ACCEPT
+ printf(" -D HAVE_OS2SEM_SERIALIZED_ACCEPT\n");
#endif
-#ifdef USE_PTHREAD_SERIALIZED_ACCEPT
- printf(" -D USE_PTHREAD_SERIALIZED_ACCEPT\n");
+#ifdef HAVE_TPF_CORE_SERIALIZED_ACCEPT
+ printf(" -D HAVE_TPF_CORE_SERIALIZED_ACCEPT\n");
#endif
+#ifdef HAVE_NONE_SERIALIZED_ACCEPT
+ printf(" -D HAVE_NONE_SERIALIZED_ACCEPT\n");
+#endif
#ifdef SINGLE_LISTEN_UNSERIALIZED_ACCEPT
printf(" -D SINGLE_LISTEN_UNSERIALIZED_ACCEPT\n");
#endif
@@ -3884,7 +4109,7 @@
/* needs to be done before we switch UIDs so we have permissions */
reopen_scoreboard(pchild);
- SAFE_ACCEPT(accept_mutex_child_init(pchild));
+ SAFE_ACCEPT((accept_mutex_child_init(pchild)));
set_group_privs();
#ifdef MPE
@@ -3982,7 +4207,7 @@
*/
/* Lock around "accept", if necessary */
- SAFE_ACCEPT(accept_mutex_on());
+ SAFE_ACCEPT((accept_mutex_on()));
for (;;) {
if (ap_listeners->next != ap_listeners) {
@@ -4688,6 +4913,8 @@
ap_clear_pool(pconf);
ptrans = ap_make_sub_pool(pconf);
+ ap_init_mutex_method(ap_default_mutex_method());
+
server_conf = ap_read_config(pconf, ptrans, ap_server_confname);
setup_listeners(pconf);
ap_clear_pool(plog);
@@ -4743,6 +4970,9 @@
}
ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_INFO, server_conf,
"Server built: %s", ap_get_server_built());
+ ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_NOTICE, server_conf,
+ "Accept mutex: %s (Default: %s)",
+ amutex->name, ap_default_mutex_method());
restart_pending = shutdown_pending = 0;
while (!restart_pending && !shutdown_pending) {
Index: src/modules/standard/mod_rewrite.h
===================================================================
RCS file: /home/cvs/apache-1.3/src/modules/standard/mod_rewrite.h,v
retrieving revision 1.80
diff -u -r1.80 mod_rewrite.h
--- src/modules/standard/mod_rewrite.h 2001/05/06 22:00:02 1.80
+++ src/modules/standard/mod_rewrite.h 2001/08/30 19:42:22
@@ -144,12 +144,13 @@
/* The locking support:
* Try to determine whether we should use fcntl() or flock().
* Would be better ap_config.h could provide this... :-(
+ * Small monkey business to ensure that fcntl is preferred,
+ * unless we specified USE_FLOCK_SERIALIZED_ACCEPT during compile.
*/
-#if defined(USE_FCNTL_SERIALIZED_ACCEPT)
+#if defined(HAVE_FCNTL_SERIALIZED_ACCEPT) && !defined(USE_FLOCK_SERIALIZED_ACCEPT)
#define USE_FCNTL 1
#include <fcntl.h>
-#endif
-#if defined(USE_FLOCK_SERIALIZED_ACCEPT)
+#elif defined(HAVE_FLOCK_SERIALIZED_ACCEPT)
#define USE_FLOCK 1
#include <sys/file.h>
#endif
--
===========================================================================
Jim Jagielski [|] jim@jaguNET.com [|] http://www.jaguNET.com/
"A society that will trade a little liberty for a little order
will lose both and deserve neither"
Re: [PATCH] Final version of AcceptMutex
Posted by Jeff Trawick <tr...@attglobal.net>.
Jim Jagielski <ji...@jaguNET.com> writes:
> You'll also notice that I decided
> to do some error handling if someone does something stupid like
> AcceptMutex BiteMe. Instead of dieing, Apache will continue with the
> default method.
That's just too cool. Oh wow... ISTR that I have an uncommitted patch
to 1.3 that makes Apache start up if I misspell the argument to
LogLevel (boy do I have problems with certain spellings). I'll go
ahead and commit that one too.
(You were joking, right?)
--
Jeff Trawick | trawick@attglobal.net | PGP public key at web site:
http://www.geocities.com/SiliconValley/Park/9289/
Born in Roswell... married an alien...