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 */
  
  
  

Reply via email to