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/20 20:36:25 UTC

[PATCH] AcceptMutex and SingleListen runtime

Below is the patch to implement AcceptMutex and SingleListen as
runtime parameters. There is still a little lint to work through, but
this is the implementation (eg: it would be nice to print/log the
settings).

Comments are welcome... I'd like to commit the patch this week. At
that point, we port to 2.0, which already has a lot of the
work done (just need to do the default stuff and handle SingleListen)

Cheers!

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/20 18:19:42
@@ -179,10 +179,10 @@
 #define NO_KILLPG
 #undef NO_SETSID
 #define bzero(a,b) memset(a,0,b)
-#if !defined(USE_SYSVSEM_SERIALIZED_ACCEPT) && \
-    !defined(USE_PTHREAD_SERIALIZED_ACCEPT)
+#define USE_SYSVSEM_SERIALIZED_ACCEPT
+#define USE_PTHREAD_SERIALIZED_ACCEPT
 #define USE_FCNTL_SERIALIZED_ACCEPT
-#endif
+#define DEFAULT_SERIALIZED_ACCEPT_METHOD fcntl
 #define NEED_UNION_SEMUN
 #define HAVE_MMAP 1
 #define USE_MMAP_SCOREBOARD
@@ -433,6 +433,9 @@
 #define JMP_BUF jmp_buf
 #define USE_LONGJMP
 #define USE_FLOCK_SERIALIZED_ACCEPT
+#define USE_FCNTL_SERIALIZED_ACCEPT
+#define USE_NONE_SERIALIZED_ACCEPT
+#define DEFAULT_SERIALIZED_ACCEPT_METHOD flock
 #define SINGLE_LISTEN_UNSERIALIZED_ACCEPT
 
 #elif defined(LINUX)
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/20 18:19:42
@@ -130,6 +130,11 @@
 
 void setup_signal_names(char *prefix);
 
+/* functions for determination and setting of accept() mutexing */
+char *default_mutex_method(void);
+char *init_mutex_method(char *t);
+char *init_single_listen(int flag);
+
 #ifndef NO_OTHER_CHILD
 /*
  * register an other_child -- a child which the main loop keeps track of
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/20 18:19:51
@@ -1135,6 +1135,14 @@
     }
     return NULL;
 }
+static const char *set_accept_mutex(cmd_parms *cmd, void *dummy, char *arg)
+{
+	return init_mutex_method(arg);
+}
+static const char *set_single_listen(cmd_parms *cmd, void *dummy, int flag)
+{
+	return init_single_listen(flag ? 1 : 0);
+}
 
 static const char *set_document_root(cmd_parms *cmd, void *dummy, char *arg)
 {
@@ -3215,6 +3223,37 @@
   (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 USE_FCNTL_SERIALIZED_ACCEPT
+	"'fcntl' "
+#endif
+#ifdef USE_FLOCK_SERIALIZED_ACCEPT
+	"'flock' "
+#endif
+#ifdef USE_USLOCK_SERIALIZED_ACCEPT
+	"'uslock "
+#endif
+#ifdef USE_SYSVSEM_SERIALIZED_ACCEPT
+	"'sysvsem' "
+#endif      
+#ifdef USE_PTHREAD_SERIALIZED_ACCEPT
+	"'pthread' "
+#endif
+#ifdef USE_OS2SEM_SERIALIZED_ACCEPT
+	"'os2sem' "
+#endif  
+#ifdef USE_TPF_CORE_SERIALIZED_ACCEPT
+	"'tpfcore' "
+#endif    
+#ifdef USE_NONE_SERIALIZED_ACCEPT
+	"'none' "
+#endif 
+	"are compiled in"
+},
+{ "SingleListen",set_single_listen,NULL,RSRC_CONF,FLAG,
+	"On - to serialize accept and Off  to unserialize accept"
+},
 
 /* 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/20 18:20:05
@@ -258,6 +258,17 @@
 time_t ap_restart_time=0;
 API_VAR_EXPORT int ap_suexec_enabled = 0;
 int ap_listenbacklog=0;
+/* 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
+ * multiple Listen statements.  Define SINGLE_LISTEN_UNSERIALIZED_ACCEPT
+ * when it's safe in the single Listen case.
+ */
+#ifdef SINGLE_LISTEN_UNSERIALIZED_ACCEPT
+int ap_single_listen = 1;
+#else
+int ap_single_listen = 0;
+#endif
+
 #ifdef SO_ACCEPTFILTER
 int ap_acceptfilter =
 #ifdef AP_ACCEPTFILTER_OFF
@@ -513,14 +524,12 @@
 #endif
 
 #if defined (USE_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 +560,7 @@
     }
 }
 
-static void accept_mutex_on(void)
+static void accept_mutex_on_uslock(void)
 {
     switch (ussetlock(uslock)) {
     case 1:
@@ -566,15 +575,16 @@
     }
 }
 
-static void accept_mutex_off(void)
+static void accept_mutex_off_uslock(void)
 {
     if (usunsetlock(uslock) == -1) {
 	perror("usunsetlock");
 	clean_child_exit(APEXIT_CHILDFATAL);
     }
 }
+#endif
 
-#elif defined (USE_PTHREAD_SERIALIZED_ACCEPT)
+#if defined (USE_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 +599,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 +607,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 +621,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 +655,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 +680,7 @@
     ap_unblock_alarms();
 }
 
-static void accept_mutex_off(void)
+static void accept_mutex_off_pthread(void)
 {
     int err;
 
@@ -691,8 +701,9 @@
 	clean_child_exit(1);
     }
 }
+#endif
 
-#elif defined (USE_SYSVSEM_SERIALIZED_ACCEPT)
+#if defined (USE_SYSVSEM_SERIALIZED_ACCEPT)
 
 #include <sys/types.h>
 #include <sys/ipc.h>
@@ -716,7 +727,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 +738,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 +769,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 +780,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 +790,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 +799,21 @@
 	}
     }
 }
+#endif
 
-#elif defined(USE_FCNTL_SERIALIZED_ACCEPT)
+#if defined(USE_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 +837,7 @@
     unlink(ap_lock_fname);
 }
 
-static void accept_mutex_on(void)
+static void accept_mutex_on_fcntl(void)
 {
     int ret;
 
@@ -842,7 +854,7 @@
     }
 }
 
-static void accept_mutex_off(void)
+static void accept_mutex_off_fcntl(void)
 {
     int ret;
 
@@ -857,12 +869,13 @@
 	clean_child_exit(APEXIT_CHILDFATAL);
     }
 }
+#endif
 
-#elif defined(USE_FLOCK_SERIALIZED_ACCEPT)
+#if defined(USE_FLOCK_SERIALIZED_ACCEPT)
 
-static int lock_fd = -1;
+static int flock_fd = -1;
 
-static void accept_mutex_cleanup(void *foo)
+static void accept_mutex_cleanup_flock(void *foo)
 {
     unlink(ap_lock_fname);
 }
@@ -871,11 +884,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 +899,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 +926,21 @@
     }
 }
 
-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);
     }
 }
+#endif
 
-#elif defined(USE_OS2SEM_SERIALIZED_ACCEPT)
+#if defined(USE_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 +950,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 +959,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 +967,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 +977,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 +991,7 @@
     }
 }
 
-static void accept_mutex_off(void)
+static void accept_mutex_off_os2sem(void)
 {
     int rc = DosReleaseMutexSem(lock_sem);
     
@@ -987,65 +1001,204 @@
 	clean_child_exit(APEXIT_CHILDFATAL);
     }
 }
+#endif
 
-#elif defined(USE_TPF_CORE_SERIALIZED_ACCEPT)
+#if defined(USE_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();
 }
+#endif
 
-#else
-/* Default --- no serialization.  Other methods *could* go here,
- * as #elifs...
- */
 #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()
+#define USE_NONE_CORE_SERIALIZED_ACCEPT
+/* The below are actually not-needed, but are here for completeness.
+ * We take care of this in USE_NONE_CORE_SERIALIZED_ACCEPT */
+#define accept_mutex_child_init_none(x)
+#define accept_mutex_init_none(x)
+#define accept_mutex_on_none()
+#define accept_mutex_off_none()
+#endif
+
+void (*accept_mutex_child_init_fptr)(pool *);
+void (*accept_mutex_init_fptr)(pool *);
+void (*accept_mutex_off_fptr)(void);
+void (*accept_mutex_on_fptr)(void);
+
+#define AP_FPTR1(x,y)	{ if (x) ((* x)(y)); }
+#define AP_FPTR0(x)	{ if (x) ((* x)()); }
+
+#define accept_mutex_child_init(x) 	AP_FPTR1(accept_mutex_child_init_fptr,x)
+#define accept_mutex_init(x) 		AP_FPTR1(accept_mutex_init_fptr,x)
+#define accept_mutex_off() 		AP_FPTR0(accept_mutex_off_fptr)
+#define accept_mutex_on() 		AP_FPTR0(accept_mutex_on_fptr)
+
+char *default_mutex_method(void)
+{
+	char *t;
+#if defined DEFAULT_SERIALIZED_ACCEPT_METHOD
+	t = "DEFAULT_SERIALIZED_ACCEPT_METHOD";
+#else
+	t = "default";
 #endif
+#if defined USE_USLOCK_SERIALIZED_ACCEPT
+	if ((!(strcasecmp(t,"default"))) || (!(strcasecmp(t,"uslock")))) {
+		return "uslock";
+	} else 
+#endif
+#if defined USE_PTHREAD_SERIALIZED_ACCEPT
+	if ((!(strcasecmp(t,"default"))) || (!(strcasecmp(t,"pthread")))) {
+		return "pthread";
+	} else 
+#endif
+#if defined USE_SYSVSEM_SERIALIZED_ACCEPT
+	if ((!(strcasecmp(t,"default"))) || (!(strcasecmp(t,"sysvsem")))) {
+		return "sysvmem";
+	} else 
+#endif
+#if defined USE_FCNTL_SERIALIZED_ACCEPT
+	if ((!(strcasecmp(t,"default"))) || (!(strcasecmp(t,"fcntl")))) {
+		return "fcntl";
+	} else
+#endif
+#if defined USE_FLOCK_SERIALIZED_ACCEPT
+	if ((!(strcasecmp(t,"default"))) || (!(strcasecmp(t,"flock")))) {
+		return "flock";
+	} else
+#endif
+#if defined USE_OS2SEM_SERIALIZED_ACCEPT
+	if ((!(strcasecmp(t,"default"))) || (!(strcasecmp(t,"os2sem")))) {
+		return "os2sem";
+	} else 
+#endif
+#if defined USE_TPF_CORE_SERIALIZED_ACCEPT
+	if ((!(strcasecmp(t,"default"))) || (!(strcasecmp(t,"tpfcore")))) {
+		return "tpfcore";
+	} else 
+#endif
+#if defined USE_NONE_CORE_SERIALIZED_ACCEPT
+	if ((!(strcasecmp(t,"default"))) || (!(strcasecmp(t,"none")))) {
+		return "none";
+	} else
 #endif
+		return "Request serialized accept method not available";
+	
+	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
- * multiple Listen statements.  Define SINGLE_LISTEN_UNSERIALIZED_ACCEPT
- * when it's safe in the single Listen case.
- */
+char *init_mutex_method(char *t)
+{
+#if defined USE_USLOCK_SERIALIZED_ACCEPT
+	if (!(strcasecmp(t,"uslock"))) {
+		accept_mutex_child_init_fptr = 	NULL;
+		accept_mutex_init_fptr = 	&accept_mutex_init_uslock;
+		accept_mutex_off_fptr = 	&accept_mutex_off_uslock;
+		accept_mutex_on_fptr = 		&accept_mutex_on_uslock;
+	} else 
+#endif
+#if defined USE_PTHREAD_SERIALIZED_ACCEPT
+	if (!(strcasecmp(t,"pthread"))) {
+		accept_mutex_child_init_fptr = &accept_mutex_child_init_pthread;
+		accept_mutex_init_fptr = 	&accept_mutex_init_pthread;
+		accept_mutex_off_fptr = 	&accept_mutex_off_pthread;
+		accept_mutex_on_fptr = 		&accept_mutex_on_pthread;
+	} else 
+#endif
+#if defined USE_SYSVSEM_SERIALIZED_ACCEPT
+	if (!(strcasecmp(t,"sysvsem"))) {
+		accept_mutex_child_init_fptr =  NULL;
+		accept_mutex_init_fptr = 	&accept_mutex_init_sysvsem;
+		accept_mutex_off_fptr = 	&accept_mutex_off_sysvsem;
+		accept_mutex_on_fptr = 		&accept_mutex_on_sysvsem;
+	} else 
+#endif
+#if defined USE_FCNTL_SERIALIZED_ACCEPT
+	if (!(strcasecmp(t,"fcntl"))) {
+		accept_mutex_child_init_fptr =  NULL;
+		accept_mutex_init_fptr = 	&accept_mutex_init_fcntl;
+		accept_mutex_off_fptr = 	&accept_mutex_off_fcntl;
+		accept_mutex_on_fptr = 		&accept_mutex_on_fcntl;
+	} else
+#endif
+#if defined USE_FLOCK_SERIALIZED_ACCEPT
+	if (!(strcasecmp(t,"flock"))) {
+		accept_mutex_child_init_fptr = &accept_mutex_child_init_flock;
+		accept_mutex_init_fptr = 	&accept_mutex_init_flock;
+		accept_mutex_off_fptr = 	&accept_mutex_off_flock;
+		accept_mutex_on_fptr = 		&accept_mutex_on_flock;
+	} else 
+#endif
+#if defined USE_OS2SEM_SERIALIZED_ACCEPT
+	if (!(strcasecmp(t,"os2sem"))) {
+		accept_mutex_child_init_fptr = &accept_mutex_child_init_os2sem;
+		accept_mutex_init_fptr = 	&accept_mutex_init_os2sem;
+		accept_mutex_off_fptr = 	&accept_mutex_off_os2sem;
+		accept_mutex_on_fptr = 		&accept_mutex_on_os2sem;
+	} else 
+#endif
+#if defined USE_TPF_CORE_SERIALIZED_ACCEPT
+	if (!(strcasecmp(t,"tpfcore"))) {
+		accept_mutex_child_init_fptr =  &accept_mutex_child_init_tpfcore;
+		accept_mutex_init_fptr = 	NULLL;
+		accept_mutex_off_fptr = 	&accept_mutex_off_tpfcore;
+		accept_mutex_on_fptr = 		&accept_mutex_on_tpfcore;
+	} else 
+#endif
+#if defined USE_NONE_CORE_SERIALIZED_ACCEPT
+	if (!(strcasecmp(t,"none"))) {
+		accept_mutex_child_init_fptr =  NULL;
+		accept_mutex_init_fptr = 	NULL;
+		accept_mutex_off_fptr = 	NULL;
+		accept_mutex_on_fptr = 		NULL;
+	} else
+#endif
+		return "Request serialized accept method not available";
+	
+	return NULL;
+}
+
+char * init_single_listen( int flag ) 
+{
+	ap_single_listen = flag;
 #ifdef SINGLE_LISTEN_UNSERIALIZED_ACCEPT
-#define SAFE_ACCEPT(stmt) do {if(ap_listeners->next != ap_listeners) {stmt;}} while(0)
+	return NULL;
 #else
-#define SAFE_ACCEPT(stmt) do {stmt;} while(0)
+	return "Single Unserialized listen not compiled in - use with caution";
 #endif
+}
 
+#define SAFE_ACCEPT(stmt)  \
+	do {if(ap_listeners->next != ap_listeners || !ap_single_listen) {stmt;}} while(0);
+
 static void usage(char *bin)
 {
     char pad[MAX_STRING_LEN];
@@ -3728,6 +3881,15 @@
 #ifdef USE_PTHREAD_SERIALIZED_ACCEPT
     printf(" -D USE_PTHREAD_SERIALIZED_ACCEPT\n");
 #endif
+#ifdef USE_OS2SEM_SERIALIZED_ACCEPT
+    printf(" -D USE_OS2SEM_SERIALIZED_ACCEPT\n");
+#endif
+#ifdef USE_TPF_CORE_SERIALIZED_ACCEPT
+    printf(" -D USE_TPF_CORE_SERIALIZED_ACCEPT\n");
+#endif
+#ifdef USE_NONE_SERIALIZED_ACCEPT
+    printf(" -D USE_NONE_SERIALIZED_ACCEPT\n");
+#endif
 #ifdef SINGLE_LISTEN_UNSERIALIZED_ACCEPT
     printf(" -D SINGLE_LISTEN_UNSERIALIZED_ACCEPT\n");
 #endif
@@ -3884,7 +4046,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 +4144,7 @@
 	 */
 
 	/* Lock around "accept", if necessary */
-	SAFE_ACCEPT(accept_mutex_on());
+	SAFE_ACCEPT((accept_mutex_on()));
 
 	for (;;) {
 	    if (ap_listeners->next != ap_listeners) {
@@ -4687,6 +4849,9 @@
 #endif
 	ap_clear_pool(pconf);
 	ptrans = ap_make_sub_pool(pconf);
+
+	init_single_listen(ap_single_listen);
+	init_mutex_method(default_mutex_method());
 
 	server_conf = ap_read_config(pconf, ptrans, ap_server_confname);
 	setup_listeners(pconf);
-- 
===========================================================================
   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] AcceptMutex and SingleListen runtime

Posted by Bill Stoddard <bi...@wstoddard.com>.
Why the SingleListen directive? If I read the code right, you cannot enable singlelisten
on a system that does not support it. That would mean that there are cases where you want
to turn SingleListen off on systems that support it. Have you observed problems with
singlelisten?

Bill

> Below is the patch to implement AcceptMutex and SingleListen as
> runtime parameters. There is still a little lint to work through, but
> this is the implementation (eg: it would be nice to print/log the
> settings).



Re: [PATCH] AcceptMutex and SingleListen runtime

Posted by Bill Stoddard <bi...@wstoddard.com>.
Definitely +1 on concept. Need to spend some time reviewing the patch.

Bill


> Below is the patch to implement AcceptMutex and SingleListen as
> runtime parameters. 


Re: [PATCH] AcceptMutex and SingleListen runtime

Posted by Jeff Trawick <tr...@attglobal.net>.
Jim Jagielski <ji...@jaguNET.com> writes:

> Comments are welcome... I'd like to commit the patch this week. At
> that point, we port to 2.0, which already has a lot of the
> work done (just need to do the default stuff and handle SingleListen)

which "default stuff" is needed in 2.0?

why is SingleListen needed?

> 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/20 18:19:42
> @@ -179,10 +179,10 @@
>  #define NO_KILLPG
>  #undef NO_SETSID
>  #define bzero(a,b) memset(a,0,b)
> -#if !defined(USE_SYSVSEM_SERIALIZED_ACCEPT) && \
> -    !defined(USE_PTHREAD_SERIALIZED_ACCEPT)
> +#define USE_SYSVSEM_SERIALIZED_ACCEPT
> +#define USE_PTHREAD_SERIALIZED_ACCEPT

Doesn't HAVE_foo_SERIALIZED_ACCEPT make more sense than
USE_foo_SERIALIZED_ACCEPT?  I guess changing the meaning of
USE_foo_SERIALIZED_ACCEPT helps minimize the changes.


>  #define USE_FCNTL_SERIALIZED_ACCEPT
> -#endif
> +#define DEFAULT_SERIALIZED_ACCEPT_METHOD fcntl

I guess we only have to set DEFAULT_SERIALIZED_ACCEPT_METHOD on
systems where there is more than one choice?

>  #define NEED_UNION_SEMUN
>  #define HAVE_MMAP 1
>  #define USE_MMAP_SCOREBOARD
> @@ -433,6 +433,9 @@
>  #define JMP_BUF jmp_buf
>  #define USE_LONGJMP
>  #define USE_FLOCK_SERIALIZED_ACCEPT
> +#define USE_FCNTL_SERIALIZED_ACCEPT
> +#define USE_NONE_SERIALIZED_ACCEPT
> +#define DEFAULT_SERIALIZED_ACCEPT_METHOD flock
>  #define SINGLE_LISTEN_UNSERIALIZED_ACCEPT

So what decides when "USE_NONE_SERIALIZED_ACCEPT" is a choice?  I'd
think that if you allow it anywhere you'd allow it everywhere, and
that there'd be no need to define anything in ap_config.h.

>  #elif defined(LINUX)

I guess we need more defines here, and on various platforms.  What is
the philosophy?  We could do some test compiles or just leave it like
this, and anybody that gives a s%^& can add #define USE_foo for their
favorite platforms to make foo available.

> 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/20 18:19:42
> @@ -130,6 +130,11 @@
>  
>  void setup_signal_names(char *prefix);
>  
> +/* functions for determination and setting of accept() mutexing */
> +char *default_mutex_method(void);
> +char *init_mutex_method(char *t);
> +char *init_single_listen(int flag);

prefix with "ap_"...  yeah, not everything in 1.3 is
namespace-protected, but it is trivial for new functions.

> 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/20 18:19:51
> @@ -1135,6 +1135,14 @@
>      }
>      return NULL;
>  }
> +static const char *set_accept_mutex(cmd_parms *cmd, void *dummy, char *arg)
> +{
> +	return init_mutex_method(arg);
> +}
> +static const char *set_single_listen(cmd_parms *cmd, void *dummy, int flag)
> +{
> +	return init_single_listen(flag ? 1 : 0);
> +}
>  
>  static const char *set_document_root(cmd_parms *cmd, void *dummy, char *arg)
>  {
> @@ -3215,6 +3223,37 @@
>    (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 USE_FCNTL_SERIALIZED_ACCEPT
> +	"'fcntl' "
> +#endif
> +#ifdef USE_FLOCK_SERIALIZED_ACCEPT
> +	"'flock' "
> +#endif
> +#ifdef USE_USLOCK_SERIALIZED_ACCEPT
> +	"'uslock "
> +#endif
> +#ifdef USE_SYSVSEM_SERIALIZED_ACCEPT
> +	"'sysvsem' "
> +#endif      
> +#ifdef USE_PTHREAD_SERIALIZED_ACCEPT
> +	"'pthread' "
> +#endif
> +#ifdef USE_OS2SEM_SERIALIZED_ACCEPT
> +	"'os2sem' "
> +#endif  
> +#ifdef USE_TPF_CORE_SERIALIZED_ACCEPT
> +	"'tpfcore' "
> +#endif    
> +#ifdef USE_NONE_SERIALIZED_ACCEPT
> +	"'none' "
> +#endif 
> +	"are compiled in"
> +},
> +{ "SingleListen",set_single_listen,NULL,RSRC_CONF,FLAG,
> +	"On - to serialize accept and Off  to unserialize accept"
> +},
>  
>  /* 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/20 18:20:05
> @@ -258,6 +258,17 @@
>  time_t ap_restart_time=0;
>  API_VAR_EXPORT int ap_suexec_enabled = 0;
>  int ap_listenbacklog=0;
> +/* 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
> + * multiple Listen statements.  Define SINGLE_LISTEN_UNSERIALIZED_ACCEPT
> + * when it's safe in the single Listen case.
> + */
> +#ifdef SINGLE_LISTEN_UNSERIALIZED_ACCEPT
> +int ap_single_listen = 1;
> +#else
> +int ap_single_listen = 0;
> +#endif
> +
>  #ifdef SO_ACCEPTFILTER
>  int ap_acceptfilter =
>  #ifdef AP_ACCEPTFILTER_OFF
> @@ -513,14 +524,12 @@
>  #endif
>  
>  #if defined (USE_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 +560,7 @@
>      }
>  }
>  
> -static void accept_mutex_on(void)
> +static void accept_mutex_on_uslock(void)
>  {
>      switch (ussetlock(uslock)) {
>      case 1:
> @@ -566,15 +575,16 @@
>      }
>  }
>  
> -static void accept_mutex_off(void)
> +static void accept_mutex_off_uslock(void)
>  {
>      if (usunsetlock(uslock) == -1) {
>  	perror("usunsetlock");
>  	clean_child_exit(APEXIT_CHILDFATAL);
>      }
>  }
> +#endif
>  
> -#elif defined (USE_PTHREAD_SERIALIZED_ACCEPT)
> +#if defined (USE_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 +599,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 +607,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 +621,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 +655,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 +680,7 @@
>      ap_unblock_alarms();
>  }
>  
> -static void accept_mutex_off(void)
> +static void accept_mutex_off_pthread(void)
>  {
>      int err;
>  
> @@ -691,8 +701,9 @@
>  	clean_child_exit(1);
>      }
>  }
> +#endif
>  
> -#elif defined (USE_SYSVSEM_SERIALIZED_ACCEPT)
> +#if defined (USE_SYSVSEM_SERIALIZED_ACCEPT)
>  
>  #include <sys/types.h>
>  #include <sys/ipc.h>
> @@ -716,7 +727,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 +738,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 +769,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 +780,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 +790,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 +799,21 @@
>  	}
>      }
>  }
> +#endif
>  
> -#elif defined(USE_FCNTL_SERIALIZED_ACCEPT)
> +#if defined(USE_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 +837,7 @@
>      unlink(ap_lock_fname);
>  }
>  
> -static void accept_mutex_on(void)
> +static void accept_mutex_on_fcntl(void)
>  {
>      int ret;
>  
> @@ -842,7 +854,7 @@
>      }
>  }
>  
> -static void accept_mutex_off(void)
> +static void accept_mutex_off_fcntl(void)
>  {
>      int ret;
>  
> @@ -857,12 +869,13 @@
>  	clean_child_exit(APEXIT_CHILDFATAL);
>      }
>  }
> +#endif
>  
> -#elif defined(USE_FLOCK_SERIALIZED_ACCEPT)
> +#if defined(USE_FLOCK_SERIALIZED_ACCEPT)
>  
> -static int lock_fd = -1;
> +static int flock_fd = -1;
>  
> -static void accept_mutex_cleanup(void *foo)
> +static void accept_mutex_cleanup_flock(void *foo)
>  {
>      unlink(ap_lock_fname);
>  }
> @@ -871,11 +884,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 +899,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 +926,21 @@
>      }
>  }
>  
> -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);
>      }
>  }
> +#endif
>  
> -#elif defined(USE_OS2SEM_SERIALIZED_ACCEPT)
> +#if defined(USE_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 +950,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 +959,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 +967,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 +977,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 +991,7 @@
>      }
>  }
>  
> -static void accept_mutex_off(void)
> +static void accept_mutex_off_os2sem(void)
>  {
>      int rc = DosReleaseMutexSem(lock_sem);
>      
> @@ -987,65 +1001,204 @@
>  	clean_child_exit(APEXIT_CHILDFATAL);
>      }
>  }
> +#endif
>  
> -#elif defined(USE_TPF_CORE_SERIALIZED_ACCEPT)
> +#if defined(USE_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();
>  }
> +#endif
>  
> -#else
> -/* Default --- no serialization.  Other methods *could* go here,
> - * as #elifs...
> - */
>  #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()
> +#define USE_NONE_CORE_SERIALIZED_ACCEPT
> +/* The below are actually not-needed, but are here for completeness.
> + * We take care of this in USE_NONE_CORE_SERIALIZED_ACCEPT */
> +#define accept_mutex_child_init_none(x)
> +#define accept_mutex_init_none(x)
> +#define accept_mutex_on_none()
> +#define accept_mutex_off_none()
> +#endif
> +
> +void (*accept_mutex_child_init_fptr)(pool *);
> +void (*accept_mutex_init_fptr)(pool *);
> +void (*accept_mutex_off_fptr)(void);
> +void (*accept_mutex_on_fptr)(void);
> +
> +#define AP_FPTR1(x,y)	{ if (x) ((* x)(y)); }
> +#define AP_FPTR0(x)	{ if (x) ((* x)()); }
> +
> +#define accept_mutex_child_init(x) 	AP_FPTR1(accept_mutex_child_init_fptr,x)
> +#define accept_mutex_init(x) 		AP_FPTR1(accept_mutex_init_fptr,x)
> +#define accept_mutex_off() 		AP_FPTR0(accept_mutex_off_fptr)
> +#define accept_mutex_on() 		AP_FPTR0(accept_mutex_on_fptr)
> +
> +char *default_mutex_method(void)
> +{
> +	char *t;
> +#if defined DEFAULT_SERIALIZED_ACCEPT_METHOD
> +	t = "DEFAULT_SERIALIZED_ACCEPT_METHOD";

Don't you want something like #DEFAULT_SERIALIZED_ACCEPT_METHOD (or
maybe with "##" instead of "#" to convert the value into a string?

> +#else
> +	t = "default";
>  #endif
> +#if defined USE_USLOCK_SERIALIZED_ACCEPT
> +	if ((!(strcasecmp(t,"default"))) || (!(strcasecmp(t,"uslock")))) {
> +		return "uslock";
> +	} else 

I'm confused.  How do we know that if t is "default" we should use
uslock?  Is it the order of the checks?  I guess it is a code error to
define more than one USE_foo_SERIALIZED_ACCEPT for the platform but
not define which one is the default?  Should we catch that here rather
than selecting the first match?

> +		return "Request serialized accept method not available";

"Requested", not "Request"

> +		return "Request serialized accept method not available";

same as previous comment, but I'd think one of these should never
fail... how about ap_assert() in one of them instead of returning an
error that we shouldn't have logic to check for?

-- 
Jeff Trawick | trawick@attglobal.net | PGP public key at web site:
       http://www.geocities.com/SiliconValley/Park/9289/
             Born in Roswell... married an alien...

Re: [PATCH] AcceptMutex and SingleListen runtime

Posted by dean gaudet <dg...@arctic.org>.
On Tue, 21 Aug 2001, Martin Kraemer wrote:

> I don't know whether Dean Gaudet is still lurking, maybe he knows
> whether there are reasons which forbid the use of the
> -DNO_SEM_UNDO alternative in apache itself. I was under the
> impression that nobody implemented it yet, but it would be useful.

it's been years since i looked at that... no idea anymore.

-dean


Re: [PATCH] AcceptMutex and SingleListen runtime

Posted by Martin Kraemer <Ma...@Fujitsu-Siemens.com>.
On Mon, Aug 20, 2001 at 02:36:25PM -0400, Jim Jagielski wrote:
> Below is the patch to implement AcceptMutex and SingleListen as
> runtime parameters. There is still a little lint to work through, but
> this is the implementation (eg: it would be nice to print/log the
> settings).

Great!!!! Yet untested, but that's something I always wanted.
One thing: in the test/ directory, we have the time-sem.c
tool which also has
 -DUSE_SYSVSEM_SERIALIZED_ACCEPT -DNO_SEM_UNDO
The NO_SEM_UNDO is a very important parameter on SVR4, without it
you will quickly hit a system-defined (tuneable but usually low,
around 60) limit of maximum undo structures in the kernel.

When apache hits that limit, it simply exits. No recovery, no restart,
simply exit. I had customers complain bitterly.....

I don't know whether Dean Gaudet is still lurking, maybe he knows
whether there are reasons which forbid the use of the
-DNO_SEM_UNDO alternative in apache itself. I was under the
impression that nobody implemented it yet, but it would be useful.

Could it be added to the patch?

> +		accept_mutex_init_fptr = 	&accept_mutex_init_flock;

In ansi C you don't need the '&' to make a function pointer.

Thanks!

   Martin
-- 
<Ma...@Fujitsu-Siemens.com>    |       Fujitsu Siemens
       <ma...@apache.org>              |   81730  Munich,  Germany

Re: [PATCH] AcceptMutex and SingleListen runtime

Posted by Bill Stoddard <bi...@wstoddard.com>.
> Below is the patch to implement AcceptMutex and SingleListen as
> runtime parameters. There is still a little lint to work through, but
> this is the implementation (eg: it would be nice to print/log the
> settings).
>
> Comments are welcome

> +
> +char *default_mutex_method(void)
> +{
> + char *t;
> +#if defined DEFAULT_SERIALIZED_ACCEPT_METHOD
> + t = "DEFAULT_SERIALIZED_ACCEPT_METHOD";

Doesn't this set t to the string "DEFAULT_SERIALIZED_ACCEPT_METHOD", rather than the value
of the DEFAULT_SERIALIZED_ACCEPT_METHOD #define?

> +#else
> + t = "default";
>  #endif
> +#if defined USE_USLOCK_SERIALIZED_ACCEPT
> + if ((!(strcasecmp(t,"default"))) || (!(strcasecmp(t,"uslock")))) {
> + return "uslock";
> + } else
> +#endif

So if DEFAULT_SERIALIZES_ACCEPT_METHOD is not defined, the default is uslock? Probably
should be fcntl.

> +#if defined USE_PTHREAD_SERIALIZED_ACCEPT
> + if ((!(strcasecmp(t,"default"))) || (!(strcasecmp(t,"pthread")))) {
> + return "pthread";
> + } else
> +#endif
> +#if defined USE_SYSVSEM_SERIALIZED_ACCEPT
> + if ((!(strcasecmp(t,"default"))) || (!(strcasecmp(t,"sysvsem")))) {
> + return "sysvmem";
> + } else
> +#endif
> +#if defined USE_FCNTL_SERIALIZED_ACCEPT
> + if ((!(strcasecmp(t,"default"))) || (!(strcasecmp(t,"fcntl")))) {
> + return "fcntl";
> + } else
> +#endif
> +#if defined USE_FLOCK_SERIALIZED_ACCEPT
> + if ((!(strcasecmp(t,"default"))) || (!(strcasecmp(t,"flock")))) {
> + return "flock";
> + } else
> +#endif
> +#if defined USE_OS2SEM_SERIALIZED_ACCEPT
> + if ((!(strcasecmp(t,"default"))) || (!(strcasecmp(t,"os2sem")))) {
> + return "os2sem";
> + } else
> +#endif
> +#if defined USE_TPF_CORE_SERIALIZED_ACCEPT
> + if ((!(strcasecmp(t,"default"))) || (!(strcasecmp(t,"tpfcore")))) {
> + return "tpfcore";
> + } else
> +#endif
> +#if defined USE_NONE_CORE_SERIALIZED_ACCEPT
> + if ((!(strcasecmp(t,"default"))) || (!(strcasecmp(t,"none")))) {
> + return "none";
> + } else
>  #endif
> + return "Request serialized accept method not available";
> +
> + return NULL;
> +}



Re: [PATCH] AcceptMutex and SingleListen runtime

Posted by Martin Kraemer <Ma...@Fujitsu-Siemens.com>.
On Thu, Aug 23, 2001 at 10:29:46AM -0400, Jim Jagielski wrote:
> 
> If the above changes are implemented, anyone foresee a -1 ??

Show us what the patch looks like, after incorporating the suggestions.


> >What happens to the char * init_single_listen() return value? errors?


This question is still open.... Will config errors go by unnoticed?
init_single_listen() returns a char* but the function is simply
invoked like a (void) init_single_listen();

   Martin
-- 
<Ma...@Fujitsu-Siemens.com>    |       Fujitsu Siemens
       <ma...@apache.org>              |   81730  Munich,  Germany

Re: [PATCH] AcceptMutex and SingleListen runtime

Posted by Jim Jagielski <ji...@jaguNET.com>.
Thanks for the feedback...
At 10:29 AM +0200 8/23/01, Martin Kraemer wrote:
>
>Shouldn't these be
>> +#define DEFAULT_SERIALIZED_ACCEPT_METHOD "fcntl"
>> +#define DEFAULT_SERIALIZED_ACCEPT_METHOD "flock"
>then?
>

The reason I have them as such is so that the actual C code takes
care of the quotes. I like to avoid situations where people need
to escape quotes at the command-line when compiling... But either
way works for me :)

>
>Can these 4 pointers be put into a structure? Then it is easier
>to assign either a pointer to an initialized structure, or
>assign the whole initialized structure en bloc. And it's better
>for encapsulation and object orientation.
>
> >  #ifdef USE_XXXXX_SERIALIZED_ACCEPT
>>      printf(" -D USE_XXXXX_SERIALIZED_ACCEPT\n");
>>  #endif

Yeah... I looking into using the apr method, which stores these in
pointers and then dereferences them as needed. The only reason I didn't
was to avoid all the extra "stuff" required to define the struct and
then change all the others calls to use it... But yes, I agree that
it's most likely worth it.

>And I'd also recommend the name change from USE_* to HAVE_*
>although I think we need some way of backward compatibility layer,
>because it has been an established and documented interface.
>
>> 	ptrans = ap_make_sub_pool(pconf);
>> +
>> +	init_single_listen(ap_single_listen);

Yeah... that's why I kept the USE_ stuff... Making a name change
would break current custom compiles (which could break anyway, but
at least it keeps things consistant).

Or maybe you're suggesting we keep USE_ to define the *default*
method and then create HAVE_ which lists the available methods.
So basically we would replace all USE_XXXXX_SERIALIZED_ACCEPT with
HAVE_XXXXX_SERIALIZED_ACCEPT, and the have USE_ set the default.
Hmmmm... I think I like that :)

My main goal was to have a small enough patch that added the
functionality without so many changes that people rejected it,
hence the limited general changes ;)

If the above changes are implemented, anyone foresee a -1 ??


>What happens to the char * init_single_listen() return value? errors?
>
>   Martin
>--
><Ma...@Fujitsu-Siemens.com>    |       Fujitsu Siemens
>       <ma...@apache.org>              |   81730  Munich,  Germany


-- 
===========================================================================
   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] AcceptMutex and SingleListen runtime

Posted by Martin Kraemer <Ma...@Fujitsu-Siemens.com>.
On Mon, Aug 20, 2001 at 02:36:25PM -0400, Jim Jagielski wrote:
> +#define DEFAULT_SERIALIZED_ACCEPT_METHOD fcntl
> ...
> +#define DEFAULT_SERIALIZED_ACCEPT_METHOD flock

Shouldn't these be 
> +#define DEFAULT_SERIALIZED_ACCEPT_METHOD "fcntl"
> +#define DEFAULT_SERIALIZED_ACCEPT_METHOD "flock"
then?

> +char *default_mutex_method(void)
> +{
> +	char *t;
> +#if defined DEFAULT_SERIALIZED_ACCEPT_METHOD
> +	t = "DEFAULT_SERIALIZED_ACCEPT_METHOD";
as already said, here without the quotes:
> +	t = DEFAULT_SERIALIZED_ACCEPT_METHOD;
> +#else
> +	t = "default";
>  #endif

> +char *init_mutex_method(char *t)
> +{
> +#if defined USE_USLOCK_SERIALIZED_ACCEPT
> +	if (!(strcasecmp(t,"uslock"))) {
> +		accept_mutex_child_init_fptr = 	NULL;
> +		accept_mutex_init_fptr = 	&accept_mutex_init_uslock;
> +		accept_mutex_off_fptr = 	&accept_mutex_off_uslock;
> +		accept_mutex_on_fptr = 		&accept_mutex_on_uslock;
> +	} else 
> +#endif
> +#if defined USE_PTHREAD_SERIALIZED_ACCEPT
> +	if (!(strcasecmp(t,"pthread"))) {
> +		accept_mutex_child_init_fptr = &accept_mutex_child_init_pthread;
> +		accept_mutex_init_fptr = 	&accept_mutex_init_pthread;
> +		accept_mutex_off_fptr = 	&accept_mutex_off_pthread;
> +		accept_mutex_on_fptr = 		&accept_mutex_on_pthread;
> +	} else 
> +#endif

Can these 4 pointers be put into a structure? Then it is easier
to assign either a pointer to an initialized structure, or
assign the whole initialized structure en bloc. And it's better
for encapsulation and object orientation.

>  #ifdef USE_XXXXX_SERIALIZED_ACCEPT
>      printf(" -D USE_XXXXX_SERIALIZED_ACCEPT\n");
>  #endif

And I'd also recommend the name change from USE_* to HAVE_*
although I think we need some way of backward compatibility layer,
because it has been an established and documented interface.

>  	ptrans = ap_make_sub_pool(pconf);
> +
> +	init_single_listen(ap_single_listen);

What happens to the char * init_single_listen() return value? errors?

   Martin
-- 
<Ma...@Fujitsu-Siemens.com>    |       Fujitsu Siemens
       <ma...@apache.org>              |   81730  Munich,  Germany