stoddard 99/03/05 08:45:57
Modified: pthreads/src/main Makefile.tmpl http_main.c Added: pthreads/src/main acceptlock.c pthreads/src/include acceptlock.h Log: Pull some of the accept logic out of http_main.c and put it in acceptlock.c. Obtained from: Ryan Bloom, Bill Stoddard Revision Changes Path 1.6 +15 -6 apache-apr/pthreads/src/main/Makefile.tmpl Index: Makefile.tmpl =================================================================== RCS file: /export/home/cvs/apache-apr/pthreads/src/main/Makefile.tmpl,v retrieving revision 1.5 retrieving revision 1.6 diff -u -r1.5 -r1.6 --- Makefile.tmpl 1999/02/15 15:45:17 1.5 +++ Makefile.tmpl 1999/03/05 16:45:55 1.6 @@ -11,7 +11,7 @@ http_config.o http_core.o http_log.o \ http_main.o http_protocol.o http_request.o http_vhost.o \ util.o util_date.o util_script.o util_uri.o util_md5.o \ - scoreboard.o rfc1413.o fdqueue.o + scoreboard.o rfc1413.o fdqueue.o acceptlock.o .c.o: $(CC) -c $(INCLUDES) $(CFLAGS) $< @@ -58,6 +58,15 @@ $(OBJS): Makefile # DO NOT REMOVE +acceptlock.o: acceptlock.c $(INCDIR)/httpd.h $(INCDIR)/ap_config.h \ + $(INCDIR)/ap_mmn.h $(INCDIR)/ap_config_auto.h $(OSDIR)/os.h \ + $(OSDIR)/os-inline.c $(INCDIR)/ap_ctype.h $(INCDIR)/hsregex.h \ + $(INCDIR)/alloc.h $(INCDIR)/buff.h $(INCDIR)/ap.h $(INCDIR)/apr.h \ + $(INCDIR)/util_uri.h $(INCDIR)/http_main.h $(INCDIR)/http_log.h \ + $(INCDIR)/http_config.h $(INCDIR)/http_protocol.h \ + $(INCDIR)/http_request.h $(INCDIR)/http_conf_globals.h \ + $(INCDIR)/http_core.h $(INCDIR)/http_vhost.h \ + $(INCDIR)/util_script.h $(INCDIR)/fdqueue.h $(INCDIR)/acceptlock.h alloc.o: alloc.c $(INCDIR)/httpd.h $(INCDIR)/ap_config.h \ $(INCDIR)/ap_mmn.h $(INCDIR)/ap_config_auto.h $(OSDIR)/os.h \ $(OSDIR)/os-inline.c $(INCDIR)/ap_ctype.h $(INCDIR)/hsregex.h \ @@ -98,7 +107,7 @@ $(INCDIR)/http_conf_globals.h $(INCDIR)/http_vhost.h \ $(INCDIR)/http_main.h $(INCDIR)/http_log.h $(INCDIR)/rfc1413.h \ $(INCDIR)/util_md5.h $(INCDIR)/ap_md5.h $(INCDIR)/scoreboard.h \ - /usr/include/pthread.h $(INCDIR)/fnmatch.h + $(INCDIR)/fnmatch.h http_log.o: http_log.c $(INCDIR)/httpd.h $(INCDIR)/ap_config.h \ $(INCDIR)/ap_mmn.h $(INCDIR)/ap_config_auto.h $(OSDIR)/os.h \ $(OSDIR)/os-inline.c $(INCDIR)/ap_ctype.h $(INCDIR)/hsregex.h \ @@ -115,7 +124,8 @@ $(INCDIR)/http_request.h $(INCDIR)/http_conf_globals.h \ $(INCDIR)/http_core.h $(INCDIR)/http_vhost.h \ $(INCDIR)/util_script.h $(INCDIR)/scoreboard.h \ - /usr/include/pthread.h $(INCDIR)/fdqueue.h $(INCDIR)/explain.h + $(INCDIR)/fdqueue.h \ + $(INCDIR)/acceptlock.h $(INCDIR)/explain.h http_protocol.o: http_protocol.c $(INCDIR)/httpd.h \ $(INCDIR)/ap_config.h $(INCDIR)/ap_mmn.h \ $(INCDIR)/ap_config_auto.h $(OSDIR)/os.h $(OSDIR)/os-inline.c \ @@ -135,7 +145,7 @@ $(INCDIR)/http_request.h $(INCDIR)/http_core.h \ $(INCDIR)/http_protocol.h $(INCDIR)/http_conf_globals.h \ $(INCDIR)/http_log.h $(INCDIR)/http_main.h $(INCDIR)/scoreboard.h \ - /usr/include/pthread.h $(INCDIR)/fnmatch.h + $(INCDIR)/fnmatch.h http_vhost.o: http_vhost.c $(INCDIR)/httpd.h $(INCDIR)/ap_config.h \ $(INCDIR)/ap_mmn.h $(INCDIR)/ap_config_auto.h $(OSDIR)/os.h \ $(OSDIR)/os-inline.c $(INCDIR)/ap_ctype.h $(INCDIR)/hsregex.h \ @@ -155,8 +165,7 @@ $(INCDIR)/alloc.h $(INCDIR)/buff.h $(INCDIR)/ap.h $(INCDIR)/apr.h \ $(INCDIR)/util_uri.h $(INCDIR)/http_log.h $(INCDIR)/http_main.h \ $(INCDIR)/http_core.h $(INCDIR)/http_conf_globals.h \ - $(INCDIR)/scoreboard.h /usr/include/pthread.h \ - $(INCDIR)/multithread.h + $(INCDIR)/scoreboard.h $(INCDIR)/multithread.h util.o: util.c $(INCDIR)/httpd.h $(INCDIR)/ap_config.h \ $(INCDIR)/ap_mmn.h $(INCDIR)/ap_config_auto.h $(OSDIR)/os.h \ $(OSDIR)/os-inline.c $(INCDIR)/ap_ctype.h $(INCDIR)/hsregex.h \ 1.57 +21 -588 apache-apr/pthreads/src/main/http_main.c Index: http_main.c =================================================================== RCS file: /export/home/cvs/apache-apr/pthreads/src/main/http_main.c,v retrieving revision 1.56 retrieving revision 1.57 diff -u -r1.56 -r1.57 --- http_main.c 1999/03/03 16:02:45 1.56 +++ http_main.c 1999/03/05 16:45:55 1.57 @@ -93,6 +93,7 @@ #include "util_uri.h" #include "scoreboard.h" #include "fdqueue.h" +#include "acceptlock.h" #include <poll.h> #include <netinet/tcp.h> #include <stdio.h> @@ -353,11 +354,12 @@ return max_daemons_limit; } -API_EXPORT(server_rec *) get_server_conf(void) +API_EXPORT(const server_rec *) ap_get_server_conf(void) { - return server_conf; + return (server_conf); } + /* * This routine adds the real server base identity to the version string, * and then locks out changes until the next reconfig. @@ -390,7 +392,7 @@ /* a clean exit from a child with proper cleanup static void clean_child_exit(int code) __attribute__ ((noreturn)); */ -static void clean_child_exit(int code) +void clean_child_exit(int code) { int child_num = find_child_by_pid(getpid()); int i; @@ -435,576 +437,6 @@ } } -/****** ZZZ this should probably be abstracted to it's own file. ****/ - -#if defined(USE_FCNTL_SERIALIZED_ACCEPT) || defined(USE_FLOCK_SERIALIZED_ACCEPT) -char * expand_lock_fname(pool *p, int i) -{ - char *fname; - /* XXXX possibly bogus cast */ - fname = ap_psprintf(p, "%s.%d", - ap_server_root_relative(p, ap_lock_fname), i, (unsigned long)getpid()); - return fname; -} -#endif - -#if defined (USE_USLOCK_SERIALIZED_ACCEPT) - -#include <ulocks.h> - -static ulock_t *uslock = NULL; - -#define accept_mutex_child_init(x) - -static void accept_mutex_init(pool *p) -{ - ptrdiff_t old; - usptr_t *us; - int i; - - uslock = (ulock_t *)ap_palloc(p, ap_acceptors_per_child * sizeof(ulock_t)); - - for (i = 0; i < ap_acceptors_per_child; i++) { - /* default is 8, allocate enough for all the children plus the parent */ - if ((old = usconfig(CONF_INITUSERS, HARD_SERVER_LIMIT + 1)) == -1) { - perror("usconfig(CONF_INITUSERS)"); - exit(-1); - } - - if ((old = usconfig(CONF_LOCKTYPE, US_NODEBUG)) == -1) { - perror("usconfig(CONF_LOCKTYPE)"); - exit(-1); - } - if ((old = usconfig(CONF_ARENATYPE, US_SHAREDONLY)) == -1) { - perror("usconfig(CONF_ARENATYPE)"); - exit(-1); - } - if ((us = usinit("/dev/zero")) == NULL) { - perror("usinit"); - exit(-1); - } - - if ((uslock[i] = usnewlock(us)) == NULL) { - perror("usnewlock"); - exit(-1); - } - } -} - -static void accept_mutex_on(int locknum) -{ - switch (ussetlock(uslock[locknum])) { - case 1: - /* got lock */ - break; - case 0: - fprintf(stderr, "didn't get lock\n"); - clean_child_exit(APEXIT_CHILDFATAL); - case -1: - perror("ussetlock"); - clean_child_exit(APEXIT_CHILDFATAL); - } -} - -static void accept_mutex_off(int locknum) -{ - if (usunsetlock(uslock[locknum]) == -1) { - perror("usunsetlock"); - clean_child_exit(APEXIT_CHILDFATAL); - } -} - -#elif 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 - * 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 = (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 *foo) -{ - int i; - - for (i = 0; i < ap_acceptors_per_child; i++) { - if (accept_mutex[i] != (void *)(caddr_t)-1 - && have_accept_mutex[i]) { - pthread_mutex_unlock(accept_mutex[i]); - } - } -} -static void accept_mutex_child_init(pool *p) -{ - ap_register_cleanup(p, NULL, accept_mutex_child_cleanup, ap_null_cleanup); -} - -static void accept_mutex_cleanup(void *foo) -{ - int i; - - for (i = 0; i < ap_acceptors_per_child; i++) { - if (accept_mutex[i] != (void *)(caddr_t)-1 - && munmap((caddr_t) accept_mutex[i], sizeof(pthread_mutex_t))) { - perror("munmap"); - } - accept_mutex[i] = (void *)(caddr_t)-1; - } -} - -static void accept_mutex_init(pool *p) -{ - pthread_mutexattr_t mattr; - int fd; - int i; - - accept_mutex = (pthread_mutex_t *)ap_palloc(p, - ap_acceptors_per_child * sizeof(pthread_mutex_t *)); - have_accept_mutex = (int *)ap_palloc(p, - ap_acceptors_per_child * sizeof(int)); - - - for (i = 0; i < ap_acceptors_per_child; i++) { - fd = open("/dev/zero", O_RDWR); - if (fd == -1) { - perror("open(/dev/zero)"); - exit(APEXIT_INIT); - } - accept_mutex[i] = (pthread_mutex_t *) mmap((caddr_t) 0, - sizeof(*accept_mutex), - PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); - if (accept_mutex[i] == (void *) (caddr_t) - 1) { - perror("mmap"); - exit(APEXIT_INIT); - } - close(fd); - if ((errno = pthread_mutexattr_init(&mattr))) { - perror("pthread_mutexattr_init"); - exit(APEXIT_INIT); - } - if ((errno = pthread_mutexattr_setpshared(&mattr, - PTHREAD_PROCESS_SHARED))) { - perror("pthread_mutexattr_setpshared"); - exit(APEXIT_INIT); - } - if ((errno = pthread_mutex_init(accept_mutex, &mattr))) { - perror("pthread_mutex_init"); - exit(APEXIT_INIT); - } - sigfillset(&accept_block_mask); - sigdelset(&accept_block_mask, SIGHUP); - sigdelset(&accept_block_mask, SIGTERM); - sigdelset(&accept_block_mask, SIGWINCH); - ap_register_cleanup(p, NULL, accept_mutex_cleanup, ap_null_cleanup); - } -} - -static void accept_mutex_on(int locknum) -{ - int err; - - if (sigprocmask(SIG_BLOCK, &accept_block_mask, &accept_previous_mask)) { - perror("sigprocmask(SIG_BLOCK)"); - clean_child_exit(APEXIT_CHILDFATAL); - } - if ((err = pthread_mutex_lock(accept_mutex[locknum]))) { - errno = err; - perror("pthread_mutex_lock"); - clean_child_exit(APEXIT_CHILDFATAL); - } - have_accept_mutex[locknum] = 1; -} - -static void accept_mutex_off(int locknum) -{ - int err; - - if ((err = pthread_mutex_unlock(accept_mutex[locknum]))) { - errno = err; - perror("pthread_mutex_unlock"); - clean_child_exit(APEXIT_CHILDFATAL); - } - /* 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[locknum] = 0; - if (sigprocmask(SIG_SETMASK, &accept_previous_mask, NULL)) { - perror("sigprocmask(SIG_SETMASK)"); - clean_child_exit(1); - } -} - -#elif defined (USE_SYSVSEM_SERIALIZED_ACCEPT) - -#include <sys/types.h> -#include <sys/ipc.h> -#include <sys/sem.h> - -#ifdef NEED_UNION_SEMUN -/* it makes no sense, but this isn't defined on solaris */ -union semun { - long val; - struct semid_ds *buf; - ushort *array; -}; - -#endif - -static int *sem_id = NULL; -static struct sembuf op_on; -static struct sembuf op_off; - -/* We get a random semaphore ... the lame sysv semaphore interface - * means we have to be sure to clean this up or else we'll leak - * semaphores. - */ -static void accept_mutex_cleanup(void *foo) -{ - union semun ick; - int i; - - for (i = 0; i < ap_acceptors_per_child; i++) { - if (sem_id[i] < 0) - return; - /* this is ignored anyhow */ - ick.val = 0; - semctl(sem_id[i], 0, IPC_RMID, ick); - } -} - -#define accept_mutex_child_init(x) - -static void accept_mutex_init(pool *p) -{ - union semun ick; - struct semid_ds buf; - int i; - - sem_id = (int *)ap_palloc(p, ap_acceptors_per_child * sizeof(int)); - - for (i = 0; i < ap_acceptors_per_child; i++) { - /* acquire the semaphore */ - sem_id[i] = semget(IPC_PRIVATE, 1, IPC_CREAT | 0600); - if (sem_id[i] < 0) { - perror("semget"); - exit(APEXIT_INIT); - } - ick.val = 1; - if (semctl(sem_id[i], 0, SETVAL, ick) < 0) { - perror("semctl(SETVAL)"); - exit(APEXIT_INIT); - } - if (!getuid()) { - /* restrict it to use only by the appropriate user_id ... not that this - * stops CGIs from acquiring it and dinking around with it. - */ - buf.sem_perm.uid = ap_user_id; - buf.sem_perm.gid = ap_group_id; - buf.sem_perm.mode = 0600; - ick.buf = &buf; - if (semctl(sem_id[i], 0, IPC_SET, ick) < 0) { - perror("semctl(IPC_SET)"); - exit(APEXIT_INIT); - } - } - ap_register_cleanup(p, NULL, accept_mutex_cleanup, ap_null_cleanup); - - /* pre-initialize these */ - op_on.sem_num = 0; - op_on.sem_op = -1; - op_on.sem_flg = SEM_UNDO; - op_off.sem_num = 0; - op_off.sem_op = 1; - op_off.sem_flg = SEM_UNDO; - } -} - -static void accept_mutex_on(int locknum) -{ - if (semop(sem_id[locknum], &op_on, 1) < 0) { - perror("accept_mutex_on"); - clean_child_exit(APEXIT_CHILDFATAL); - } -} - -static void accept_mutex_off(int locknum) -{ - if (semop(sem_id[locknum], &op_off, 1) < 0) { - perror("accept_mutex_off"); - clean_child_exit(APEXIT_CHILDFATAL); - } -} - -#elif defined(USE_FCNTL_SERIALIZED_ACCEPT) -static struct flock lock_it; -static struct flock unlock_it; - -static int *lock_fd = NULL; - -#define accept_mutex_child_init(x) - -/* - * Initialize mutex lock. - * Must be safe to call this on a restart. - */ -static void accept_mutex_init(pool *p) -{ - int i; - char * lock_fname; - lock_fd = (int *)ap_palloc(p, ap_acceptors_per_child * sizeof(int *)); - - lock_it.l_whence = SEEK_SET; /* from current point */ - lock_it.l_start = 0; /* -"- */ - lock_it.l_len = 0; /* until end of file */ - lock_it.l_type = F_WRLCK; /* set exclusive/write lock */ - lock_it.l_pid = 0; /* pid not actually interesting */ - unlock_it.l_whence = SEEK_SET; /* from current point */ - unlock_it.l_start = 0; /* -"- */ - unlock_it.l_len = 0; /* until end of file */ - unlock_it.l_type = F_UNLCK; /* set exclusive/write lock */ - unlock_it.l_pid = 0; /* pid not actually interesting */ - - for (i = 0; i < ap_acceptors_per_child; i++) { - lock_fname = expand_lock_fname(p, i); - lock_fd[i] = ap_popenf(p, lock_fname, - O_CREAT | O_WRONLY | O_EXCL, 0644); - if (lock_fd[i] == -1) { - perror("open"); - fprintf(stderr, "Cannot open lock file: %s\n", lock_fname); - exit(APEXIT_INIT); - } - unlink(lock_fname); - } -} - -static void accept_mutex_on(int locknum) -{ - int ret; - - while ((ret = fcntl(lock_fd[locknum], F_SETLKW, &lock_it)) < 0 && - errno != EINTR) { - /* nop */ - } - - if (ret < 0 && errno != EINTR) { - ap_log_error(APLOG_MARK, APLOG_EMERG, server_conf, - "fcntl: F_SETLKW: Error getting accept lock, exiting! " - "Perhaps you need to use the LockFile directive to place " - "your lock file on a local disk!"); - clean_child_exit(APEXIT_CHILDFATAL); - } -} - -static void accept_mutex_off(int locknum) -{ - int ret; - - while ((ret = fcntl(lock_fd[locknum], F_SETLKW, &unlock_it)) < 0 - && errno != EINTR) { - /* nop */ - } - if (ret < 0 && errno != EINTR) { - ap_log_error(APLOG_MARK, APLOG_EMERG, server_conf, - "fcntl: F_SETLKW: Error freeing accept lock, exiting! " - "Perhaps you need to use the LockFile directive to place " - "your lock file on a local disk!"); - clean_child_exit(APEXIT_CHILDFATAL); - } -} - -#elif defined(USE_FLOCK_SERIALIZED_ACCEPT) - -static int *lock_fd = NULL; - -static void accept_mutex_cleanup(void *foo) -{ - int i; - - char * lock_fname; - for (i = 0; i < ap_acceptors_per_child; i++) { - lock_fname = expand_lock_fname(foo, i); - unlink(lock_fname); - } -} - -/* - * Initialize mutex lock. - * Done by each child at it's birth - */ -static void accept_mutex_child_init(pool *p) -{ - int i; - - for (i = 0; i < ap_acceptors_per_child; i++) { - char *lock_fname = expand_lock_fname(p, i); - - lock_fd[i] = ap_popenf(p, lock_fname, O_WRONLY, 0600); - if (lock_fd[i] == -1) { - ap_log_error(APLOG_MARK, APLOG_EMERG, server_conf, - "Child cannot open lock file: %s", lock_fname); - clean_child_exit(APEXIT_CHILDINIT); - } - } -} - -/* - * Initialize mutex lock. - * Must be safe to call this on a restart. - */ -static void accept_mutex_init(pool *p) -{ - int i; - char * lock_fname; - lock_fd = (int *)ap_palloc(p, ap_acceptors_per_child * sizeof(int *)); - - for (i = 0; i < ap_acceptors_per_child; i++) { - lock_fname = expand_lock_fname(p, i); - unlink(lock_fname); - lock_fd[i] = ap_popenf(p, lock_fname, - O_CREAT | O_WRONLY | O_EXCL, 0600); - if (lock_fd[i] == -1) { - ap_log_error(APLOG_MARK, APLOG_EMERG, server_conf, - "Parent cannot open lock file: %s", lock_fname); - exit(APEXIT_INIT); - } - ap_register_cleanup(p, p, accept_mutex_cleanup, ap_null_cleanup); - } -} - -static void accept_mutex_on(int locknum) -{ - int ret; - - while ((ret = flock(lock_fd[locknum], LOCK_EX)) < 0 && errno != EINTR) - continue; - - if (ret < 0 && errno != EINTR) { - ap_log_error(APLOG_MARK, APLOG_EMERG, server_conf, - "flock: LOCK_EX: Error getting accept lock. Exiting!"); - clean_child_exit(APEXIT_CHILDFATAL); - } -} - -static void accept_mutex_off(int locknum) -{ - if (flock(lock_fd[locknum], LOCK_UN) < 0 && errno != EINTR) { - ap_log_error(APLOG_MARK, APLOG_EMERG, server_conf, - "flock: LOCK_UN: Error freeing accept lock. Exiting!"); - clean_child_exit(APEXIT_CHILDFATAL); - } -} - -#elif defined(USE_OS2SEM_SERIALIZED_ACCEPT) - -static HMTX *lock_sem = NULL; - -static void accept_mutex_cleanup(void *foo) -{ - int i; - - for (i = 0; i < ap_acceptors_per_child; i++) { - DosReleaseMutexSem(lock_sem[i]); - DosCloseMutexSem(lock_sem[i]); - } -} - -/* - * Initialize mutex lock. - * Done by each child at it's birth - */ -static void accept_mutex_child_init(pool *p) -{ - int i; - - for(i = 0; i < ap_acceptors_per_child; i++) { - int rc = DosOpenMutexSem(NULL, &lock_sem[locknum]); - - if (rc != 0) { - ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_EMERG, server_conf, - "Child cannot open lock semaphore, rc=%d", rc); - clean_child_exit(APEXIT_CHILDINIT); - } - } -} -/* - * Initialize mutex lock. - * Must be safe to call this on a restart. - */ -static void accept_mutex_init(pool *p) -{ - int rc; - int i; - - lock_fd = (int *)ap_palloc(p, ap_acceptors_per_child * sizeof(int *)); - - for (i = 0; i < ap_acceptors_per_child; i++) { - rc = DosCreateMutexSem(NULL, &lock_sem[i], DC_SEM_SHARED, FALSE); - - if (rc != 0) { - ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_EMERG, server_conf, - "Parent cannot create lock semaphore, rc=%d", rc); - exit(APEXIT_INIT); - } - - ap_register_cleanup(p, NULL, accept_mutex_cleanup, ap_null_cleanup); - } -} - -static void accept_mutex_on(int locknum) -{ - int rc = DosRequestMutexSem(lock_sem[locknum], SEM_INDEFINITE_WAIT); - - if (rc != 0) { - ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_EMERG, server_conf, - "OS2SEM: Error %d getting accept lock. Exiting!", rc); - clean_child_exit(APEXIT_CHILDFATAL); - } -} - -static void accept_mutex_off(int locknum) -{ - int rc = DosReleaseMutexSem(lock_sem[locknum]); - - if (rc != 0) { - ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_EMERG, server_conf, - "OS2SEM: Error %d freeing accept lock. Exiting!", rc); - clean_child_exit(APEXIT_CHILDFATAL); - } -} - -#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(x) -#define accept_mutex_off(x) -#endif -#endif - -/*** End of accept serialization code. */ - int ap_get_timeout(request_rec *r) { @@ -2280,7 +1712,7 @@ (const struct sockaddr_in *) sa_client, (const struct sockaddr_in *) &sa_server, my_child_num, my_thread_num); - + /* * Read and process each request found on our connection * until no requests are left or we decide to close. @@ -2726,7 +2158,8 @@ /* fork didn't succeed. Fix the scoreboard or else * it will say SERVER_STARTING forever and ever */ - /* (void) ap_update_child_status(slot, SERVER_DEAD, (request_rec *) NULL); We never put SERVER_STARTING in scoreboard */ + /* (void) ap_update_child_status(slot, SERVER_DEAD, (request_rec *) NULL); + We never put SERVER_STARTING in scoreboard */ /* In case system resources are maxxed out, we don't want Apache running away with the CPU trying to fork over and over and over again. */ @@ -2931,16 +2364,16 @@ if (pid >= 0) { child_slot = find_child_by_pid(pid); if (child_slot >= 0) { - /* (void) ap_update_child_status(child_slot, SERVER_DEAD, - (request_rec *) NULL); - LOOK INTO THIS */ - + /*(void) ap_update_child_status(child_slot, SERVER_DEAD, + (request_rec *) NULL); + LOOK INTO THIS */ + if (remaining_children_to_start && child_slot < ap_daemons_limit) { /* we're still doing a 1-for-1 replacement of dead - * children with new children - */ - /* ZZZ abstract out for AP funcs. */ + * children with new children + */ + /* ZZZ abstract out for AP funcs. */ make_child(server_conf, child_slot, time(NULL)); --remaining_children_to_start; } @@ -2959,10 +2392,10 @@ "long lost child came home! (pid %d)", pid); } /* Don't perform idle maintenance when a child dies, - * only do it when there's a timeout. Remember only a - * finite number of children can die, and it's pretty - * pathological for a lot to die suddenly. - */ + * only do it when there's a timeout. Remember only a + * finite number of children can die, and it's pretty + * pathological for a lot to die suddenly. + */ continue; } else if (remaining_children_to_start) { @@ -2980,7 +2413,7 @@ } perform_idle_server_maintenance(); - } + } } static void one_config_cycle(void) @@ -2989,7 +2422,7 @@ copy_listeners(pconf); if (!is_graceful) { - ap_restart_time = time(NULL); /* ZZZZZ */ + ap_restart_time = time(NULL); /* ZZZZZ */ } ap_clear_pool(pconf); ptemp = ap_make_sub_pool(pconf); 1.1 apache-apr/pthreads/src/main/acceptlock.c Index: acceptlock.c =================================================================== /* ==================================================================== * Copyright (c) 1995-1999 The Apache Group. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. All advertising materials mentioning features or use of this * software must display the following acknowledgment: * "This product includes software developed by the Apache Group * for use in the Apache HTTP server project (http://www.apache.org/)." * * 4. The names "Apache Server" and "Apache Group" must not be used to * endorse or promote products derived from this software without * prior written permission. For written permission, please contact * [EMAIL PROTECTED] * * 5. Products derived from this software may not be called "Apache" * nor may "Apache" appear in their names without prior written * permission of the Apache Group. * * 6. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by the Apache Group * for use in the Apache HTTP server project (http://www.apache.org/)." * * THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE APACHE GROUP OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Group and was originally based * on public domain software written at the National Center for * Supercomputing Applications, University of Illinois, Urbana-Champaign. * For more information on the Apache Group and the Apache HTTP server * project, please see <http://www.apache.org/>. * */ #include "httpd.h" #include "http_main.h" #include "http_log.h" #include "http_config.h" /* for read_config */ #include "http_protocol.h" /* for read_request */ #include "http_request.h" /* for process_request */ #include "http_conf_globals.h" #include "http_core.h" /* for get_remote_host */ #include "http_vhost.h" #include "util_script.h" /* to force util_script.c linking */ #include "util_uri.h" #include "fdqueue.h" #include "acceptlock.h" #include <netinet/tcp.h> #include <stdio.h> #ifdef USE_SHMGET_SCOREBOARD #include <sys/types.h> #include <sys/ipc.h> #include <sys/shm.h> #endif #include "pthread.h" #if defined(USE_FCNTL_SERIALIZED_ACCEPT) || defined(USE_FLOCK_SERIALIZED_ACCEPT) char * expand_lock_fname(pool *p, int i) { char *fname; /* XXXX possibly bogus cast */ fname = ap_psprintf(p, "%s.%d", ap_server_root_relative(p, ap_lock_fname), i, (unsigned long)getpid()); return fname; } #endif #if defined (USE_USLOCK_SERIALIZED_ACCEPT) #include <ulocks.h> static ulock_t *uslock = NULL; void accept_mutex_init(pool *p) { ptrdiff_t old; usptr_t *us; int i; uslock = (ulock_t *)ap_palloc(p, ap_acceptors_per_child * sizeof(ulock_t)); for (i = 0; i < ap_acceptors_per_child; i++) { /* default is 8, allocate enough for all the children plus the parent */ if ((old = usconfig(CONF_INITUSERS, HARD_SERVER_LIMIT + 1)) == -1) { perror("usconfig(CONF_INITUSERS)"); exit(-1); } if ((old = usconfig(CONF_LOCKTYPE, US_NODEBUG)) == -1) { perror("usconfig(CONF_LOCKTYPE)"); exit(-1); } if ((old = usconfig(CONF_ARENATYPE, US_SHAREDONLY)) == -1) { perror("usconfig(CONF_ARENATYPE)"); exit(-1); } if ((us = usinit("/dev/zero")) == NULL) { perror("usinit"); exit(-1); } if ((uslock[i] = usnewlock(us)) == NULL) { perror("usnewlock"); exit(-1); } } } void accept_mutex_on(int locknum) { switch (ussetlock(uslock[locknum])) { case 1: /* got lock */ break; case 0: fprintf(stderr, "didn't get lock\n"); clean_child_exit(APEXIT_CHILDFATAL); case -1: perror("ussetlock"); clean_child_exit(APEXIT_CHILDFATAL); } } void accept_mutex_off(int locknum) { if (usunsetlock(uslock[locknum]) == -1) { perror("usunsetlock"); clean_child_exit(APEXIT_CHILDFATAL); } } #elif 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 * 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 = (void *)(caddr_t) -1; static int *have_accept_mutex; static sigset_t accept_block_mask; static sigset_t accept_previous_mask; void accept_mutex_child_cleanup(void *foo) { int i; for (i = 0; i < ap_acceptors_per_child; i++) { if (accept_mutex[i] != (void *)(caddr_t)-1 && have_accept_mutex[i]) { pthread_mutex_unlock(accept_mutex[i]); } } } void accept_mutex_child_init(pool *p) { ap_register_cleanup(p, NULL, accept_mutex_child_cleanup, ap_null_cleanup); } void accept_mutex_cleanup(void *foo) { int i; for (i = 0; i < ap_acceptors_per_child; i++) { if (accept_mutex[i] != (void *)(caddr_t)-1 && munmap((caddr_t) accept_mutex[i], sizeof(pthread_mutex_t))) { perror("munmap"); } accept_mutex[i] = (void *)(caddr_t)-1; } } void accept_mutex_init(pool *p) { pthread_mutexattr_t mattr; int fd; int i; accept_mutex = (pthread_mutex_t *)ap_palloc(p, ap_acceptors_per_child * sizeof(pthread_mutex_t *)); have_accept_mutex = (int *)ap_palloc(p, ap_acceptors_per_child * sizeof(int)); for (i = 0; i < ap_acceptors_per_child; i++) { fd = open("/dev/zero", O_RDWR); if (fd == -1) { perror("open(/dev/zero)"); exit(APEXIT_INIT); } accept_mutex[i] = (pthread_mutex_t *) mmap((caddr_t) 0, sizeof(*accept_mutex), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (accept_mutex[i] == (void *) (caddr_t) - 1) { perror("mmap"); exit(APEXIT_INIT); } close(fd); if ((errno = pthread_mutexattr_init(&mattr))) { perror("pthread_mutexattr_init"); exit(APEXIT_INIT); } if ((errno = pthread_mutexattr_setpshared(&mattr, PTHREAD_PROCESS_SHARED))) { perror("pthread_mutexattr_setpshared"); exit(APEXIT_INIT); } if ((errno = pthread_mutex_init(accept_mutex, &mattr))) { perror("pthread_mutex_init"); exit(APEXIT_INIT); } sigfillset(&accept_block_mask); sigdelset(&accept_block_mask, SIGHUP); sigdelset(&accept_block_mask, SIGTERM); sigdelset(&accept_block_mask, SIGWINCH); ap_register_cleanup(p, NULL, accept_mutex_cleanup, ap_null_cleanup); } } void accept_mutex_on(int locknum) { int err; if (sigprocmask(SIG_BLOCK, &accept_block_mask, &accept_previous_mask)) { perror("sigprocmask(SIG_BLOCK)"); clean_child_exit(APEXIT_CHILDFATAL); } if ((err = pthread_mutex_lock(accept_mutex[locknum]))) { errno = err; perror("pthread_mutex_lock"); clean_child_exit(APEXIT_CHILDFATAL); } have_accept_mutex[locknum] = 1; } void accept_mutex_off(int locknum) { int err; if ((err = pthread_mutex_unlock(accept_mutex[locknum]))) { errno = err; perror("pthread_mutex_unlock"); clean_child_exit(APEXIT_CHILDFATAL); } /* 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[locknum] = 0; if (sigprocmask(SIG_SETMASK, &accept_previous_mask, NULL)) { perror("sigprocmask(SIG_SETMASK)"); clean_child_exit(1); } } #elif defined (USE_SYSVSEM_SERIALIZED_ACCEPT) #include <sys/types.h> #include <sys/ipc.h> #include <sys/sem.h> #ifdef NEED_UNION_SEMUN /* it makes no sense, but this isn't defined on solaris */ union semun { long val; struct semid_ds *buf; ushort *array; }; #endif static int *sem_id = NULL; static struct sembuf op_on; static struct sembuf op_off; /* We get a random semaphore ... the lame sysv semaphore interface * means we have to be sure to clean this up or else we'll leak * semaphores. */ void accept_mutex_cleanup(void *foo) { union semun ick; int i; for (i = 0; i < ap_acceptors_per_child; i++) { if (sem_id[i] < 0) return; /* this is ignored anyhow */ ick.val = 0; semctl(sem_id[i], 0, IPC_RMID, ick); } } void accept_mutex_init(pool *p) { union semun ick; struct semid_ds buf; int i; sem_id = (int *)ap_palloc(p, ap_acceptors_per_child * sizeof(int)); for (i = 0; i < ap_acceptors_per_child; i++) { /* acquire the semaphore */ sem_id[i] = semget(IPC_PRIVATE, 1, IPC_CREAT | 0600); if (sem_id[i] < 0) { perror("semget"); exit(APEXIT_INIT); } ick.val = 1; if (semctl(sem_id[i], 0, SETVAL, ick) < 0) { perror("semctl(SETVAL)"); exit(APEXIT_INIT); } if (!getuid()) { /* restrict it to use only by the appropriate user_id ... not that this * stops CGIs from acquiring it and dinking around with it. */ buf.sem_perm.uid = ap_user_id; buf.sem_perm.gid = ap_group_id; buf.sem_perm.mode = 0600; ick.buf = &buf; if (semctl(sem_id[i], 0, IPC_SET, ick) < 0) { perror("semctl(IPC_SET)"); exit(APEXIT_INIT); } } ap_register_cleanup(p, NULL, accept_mutex_cleanup, ap_null_cleanup); /* pre-initialize these */ op_on.sem_num = 0; op_on.sem_op = -1; op_on.sem_flg = SEM_UNDO; op_off.sem_num = 0; op_off.sem_op = 1; op_off.sem_flg = SEM_UNDO; } } void accept_mutex_on(int locknum) { if (semop(sem_id[locknum], &op_on, 1) < 0) { perror("accept_mutex_on"); clean_child_exit(APEXIT_CHILDFATAL); } } void accept_mutex_off(int locknum) { if (semop(sem_id[locknum], &op_off, 1) < 0) { perror("accept_mutex_off"); clean_child_exit(APEXIT_CHILDFATAL); } } #elif defined(USE_FCNTL_SERIALIZED_ACCEPT) static struct flock lock_it; static struct flock unlock_it; static int *lock_fd = NULL; /* * Initialize mutex lock. * Must be safe to call this on a restart. */ void accept_mutex_init(pool *p) { int i; char * lock_fname; lock_fd = (int *)ap_palloc(p, ap_acceptors_per_child * sizeof(int *)); lock_it.l_whence = SEEK_SET; /* from current point */ lock_it.l_start = 0; /* -"- */ lock_it.l_len = 0; /* until end of file */ lock_it.l_type = F_WRLCK; /* set exclusive/write lock */ lock_it.l_pid = 0; /* pid not actually interesting */ unlock_it.l_whence = SEEK_SET; /* from current point */ unlock_it.l_start = 0; /* -"- */ unlock_it.l_len = 0; /* until end of file */ unlock_it.l_type = F_UNLCK; /* set exclusive/write lock */ unlock_it.l_pid = 0; /* pid not actually interesting */ for (i = 0; i < ap_acceptors_per_child; i++) { lock_fname = expand_lock_fname(p, i); lock_fd[i] = ap_popenf(p, lock_fname, O_CREAT | O_WRONLY | O_EXCL, 0644); if (lock_fd[i] == -1) { perror("open"); fprintf(stderr, "Cannot open lock file: %s\n", lock_fname); exit(APEXIT_INIT); } unlink(lock_fname); } } void accept_mutex_on(int locknum) { int ret; while ((ret = fcntl(lock_fd[locknum], F_SETLKW, &lock_it)) < 0 && errno != EINTR) { /* nop */ } if (ret < 0 && errno != EINTR) { ap_log_error(APLOG_MARK, APLOG_EMERG, (const server_rec*) ap_get_server_conf(), "fcntl: F_SETLKW: Error getting accept lock, exiting! " "Perhaps you need to use the LockFile directive to place " "your lock file on a local disk!"); clean_child_exit(APEXIT_CHILDFATAL); } } void accept_mutex_off(int locknum) { int ret; while ((ret = fcntl(lock_fd[locknum], F_SETLKW, &unlock_it)) < 0 && errno != EINTR) { /* nop */ } if (ret < 0 && errno != EINTR) { ap_log_error(APLOG_MARK, APLOG_EMERG, (const server_rec*) ap_get_server_conf(), "fcntl: F_SETLKW: Error freeing accept lock, exiting! " "Perhaps you need to use the LockFile directive to place " "your lock file on a local disk!"); clean_child_exit(APEXIT_CHILDFATAL); } } #elif defined(USE_FLOCK_SERIALIZED_ACCEPT) static int *lock_fd = NULL; void accept_mutex_cleanup(void *foo) { int i; char * lock_fname; for (i = 0; i < ap_acceptors_per_child; i++) { lock_fname = expand_lock_fname(foo, i); unlink(lock_fname); } } /* * Initialize mutex lock. * Done by each child at it's birth */ void accept_mutex_child_init(pool *p) { int i; for (i = 0; i < ap_acceptors_per_child; i++) { char *lock_fname = expand_lock_fname(p, i); lock_fd[i] = ap_popenf(p, lock_fname, O_WRONLY, 0600); if (lock_fd[i] == -1) { ap_log_error(APLOG_MARK, APLOG_EMERG, ap_get_server_conf(), "Child cannot open lock file: %s", lock_fname); clean_child_exit(APEXIT_CHILDINIT); } } } /* * Initialize mutex lock. * Must be safe to call this on a restart. */ void accept_mutex_init(pool *p) { int i; char * lock_fname; lock_fd = (int *)ap_palloc(p, ap_acceptors_per_child * sizeof(int *)); for (i = 0; i < ap_acceptors_per_child; i++) { lock_fname = expand_lock_fname(p, i); unlink(lock_fname); lock_fd[i] = ap_popenf(p, lock_fname, O_CREAT | O_WRONLY | O_EXCL, 0600); if (lock_fd[i] == -1) { ap_log_error(APLOG_MARK, APLOG_EMERG, ap_get_server_conf(), "Parent cannot open lock file: %s", lock_fname); exit(APEXIT_INIT); } ap_register_cleanup(p, p, accept_mutex_cleanup, ap_null_cleanup); } } void accept_mutex_on(int locknum) { int ret; while ((ret = flock(lock_fd[locknum], LOCK_EX)) < 0 && errno != EINTR) continue; if (ret < 0 && errno != EINTR) { ap_log_error(APLOG_MARK, APLOG_EMERG, ap_get_server_conf(), "flock: LOCK_EX: Error getting accept lock. Exiting!"); clean_child_exit(APEXIT_CHILDFATAL); } } void accept_mutex_off(int locknum) { if (flock(lock_fd[locknum], LOCK_UN) < 0 && errno != EINTR) { ap_log_error(APLOG_MARK, APLOG_EMERG, ap_get_server_conf(), "flock: LOCK_UN: Error freeing accept lock. Exiting!"); clean_child_exit(APEXIT_CHILDFATAL); } } #elif defined(USE_OS2SEM_SERIALIZED_ACCEPT) static HMTX *lock_sem = NULL; void accept_mutex_cleanup(void *foo) { int i; for (i = 0; i < ap_acceptors_per_child; i++) { DosReleaseMutexSem(lock_sem[i]); DosCloseMutexSem(lock_sem[i]); } } /* * Initialize mutex lock. * Done by each child at it's birth */ void accept_mutex_child_init(pool *p) { int i; for(i = 0; i < ap_acceptors_per_child; i++) { int rc = DosOpenMutexSem(NULL, &lock_sem[locknum]); if (rc != 0) { ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_EMERG, ap_get_server_conf(), "Child cannot open lock semaphore, rc=%d", rc); clean_child_exit(APEXIT_CHILDINIT); } } } /* * Initialize mutex lock. * Must be safe to call this on a restart. */ void accept_mutex_init(pool *p) { int rc; int i; lock_fd = (int *)ap_palloc(p, ap_acceptors_per_child * sizeof(int *)); for (i = 0; i < ap_acceptors_per_child; i++) { rc = DosCreateMutexSem(NULL, &lock_sem[i], DC_SEM_SHARED, FALSE); if (rc != 0) { ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_EMERG, ap_get_server_conf(), "Parent cannot create lock semaphore, rc=%d", rc); exit(APEXIT_INIT); } ap_register_cleanup(p, NULL, accept_mutex_cleanup, ap_null_cleanup); } } void accept_mutex_on(int locknum) { int rc = DosRequestMutexSem(lock_sem[locknum], SEM_INDEFINITE_WAIT); if (rc != 0) { ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_EMERG, ap_get_server_conf(), "OS2SEM: Error %d getting accept lock. Exiting!", rc); clean_child_exit(APEXIT_CHILDFATAL); } } void accept_mutex_off(int locknum) { int rc = DosReleaseMutexSem(lock_sem[locknum]); if (rc != 0) { ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_EMERG, ap_get_server_conf(), "OS2SEM: Error %d freeing accept lock. Exiting!", rc); clean_child_exit(APEXIT_CHILDFATAL); } } #else /* Default --- no serialization. Other methods *could* go here, * as #elifs... */ #if !defined(MULTITHREAD) /* Multithreaded systems don't complete between processes for * the sockets. */ #endif #endif 1.1 apache-apr/pthreads/src/include/acceptlock.h Index: acceptlock.h =================================================================== /* ==================================================================== * Copyright (c) 1995-1999 The Apache Group. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. All advertising materials mentioning features or use of this * software must display the following acknowledgment: * "This product includes software developed by the Apache Group * for use in the Apache HTTP server project (http://www.apache.org/)." * * 4. The names "Apache Server" and "Apache Group" must not be used to * endorse or promote products derived from this software without * prior written permission. For written permission, please contact * [EMAIL PROTECTED] * * 5. Products derived from this software may not be called "Apache" * nor may "Apache" appear in their names without prior written * permission of the Apache Group. * * 6. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by the Apache Group * for use in the Apache HTTP server project (http://www.apache.org/)." * * THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE APACHE GROUP OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Group and was originally based * on public domain software written at the National Center for * Supercomputing Applications, University of Illinois, Urbana-Champaign. * For more information on the Apache Group and the Apache HTTP server * project, please see <http://www.apache.org/>. * */ #ifndef APACHE_ACCEPT_LOCK_H #define APACHE_ACCEPT_LOCK_H #ifdef __cplusplus extern "C" { #endif /* Prototyps for the accept mutex functions. */ #if defined (USE_USLOCK_SERIALIZED_ACCEPT) #define accept_mutex_child_init(x) void accept_mutex_init(pool *); void accept_mutex_on(int); void accept_mutex_off(int); #elif defined (USE_PTHREAD_SERIALIZED_ACCEPT) void accept_mutex_child_cleanup(void *); void accept_mutex_child_init(pool *); void accept_mutex_cleanup(void *); void accept_mutex_init(pool *); void accept_mutex_on(int); void accept_mutex_off(int); #elif defined (USE_SYSVSEM_SERIALIZED_ACCEPT) void accept_mutex_cleanup(void *); void accept_mutex_init(pool *); void accept_mutex_on(int); void accept_mutex_off(int); #elif defined(USE_FCNTL_SERIALIZED_ACCEPT) #define accept_mutex_child_init(x) void accept_mutex_init(pool *); void accept_mutex_on(int); void accept_mutex_off(int); #elif defined(USE_FLOCK_SERIALIZED_ACCEPT) #define accept_mutex_child_init(x) void accept_mutex_cleanup(void *); void accept_mutex_child_init(pool *); void accept_mutex_init(pool *); void accept_mutex_on(int); void accept_mutex_off(int); #elif defined(USE_OS2SEM_SERIALIZED_ACCEPT) void accept_mutex_cleanup(void *); void accept_mutex_child_init(pool *); void accept_mutex_init(pool *); void accept_mutex_on(int); void accept_mutex_off(int); #else #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(x) #define accept_mutex_off(x) #endif #endif /* Prototypes for functions required for accept_mutex */ void clean_child_exit(int); #ifdef __cplusplus } #endif #endif /* APACHE_ACCEPT_LOCK_H */