httpd-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From stodd...@hyperreal.org
Subject cvs commit: apache-apr/pthreads/src/include acceptlock.h
Date Fri, 05 Mar 1999 16:45:58 GMT
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 
   *    apache@apache.org. 
   * 
   * 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 
   *    apache@apache.org. 
   * 
   * 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 */
  
  
  

Mime
View raw message