You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@apr.apache.org by ji...@apache.org on 2002/04/04 20:33:57 UTC

cvs commit: apr/locks/unix crossproc.c locks.c proc_mutex.c

jim         02/04/04 10:33:57

  Modified:    .        CHANGES configure.in
               include  apr.h.in apr_global_mutex.h apr_lock.h
                        apr_proc_mutex.h
               include/arch/unix locks.h proc_mutex.h
               locks/unix crossproc.c locks.c proc_mutex.c
  Log:
  Support for Posix semaphores for locking has been added. This uses
  named semaphores (sem_open). Because there are a few different
  implementations around, this uses the lowest common denominator in
  creating the semaphore name. As far as its location in DEFAULT
  priority, it's placed between pthread and sysvsem. Tested on
  Darwin (in which it's the new default) and Solaris.
  
  As part of the discovery of sem_open under Solaris, APR is now
  aware of shm_open (Posix shared memory) under Solaris as well, if
  someone wants to monkey with that :)
  
  Revision  Changes    Path
  1.252     +5 -0      apr/CHANGES
  
  Index: CHANGES
  ===================================================================
  RCS file: /home/cvs/apr/CHANGES,v
  retrieving revision 1.251
  retrieving revision 1.252
  diff -u -r1.251 -r1.252
  --- CHANGES	1 Apr 2002 21:03:04 -0000	1.251
  +++ CHANGES	4 Apr 2002 18:33:56 -0000	1.252
  @@ -1,5 +1,10 @@
   Changes with APR b1
   
  +  *) Added support for Posix semaphores (sem_open, et.al.) for mutex
  +     locking. We use named semaphores in this implementation. The
  +     default priority is between pthread and sysvsem.
  +     [Jim Jagielski]
  +
     *) Get flock-based mutexes to work in apps like Apache.  Use the
        same permissions on flock- and fcntl-based mutexes as Apache
        1.3.  [Jeff Trawick]
  
  
  
  1.423     +25 -1     apr/configure.in
  
  Index: configure.in
  ===================================================================
  RCS file: /home/cvs/apr/configure.in,v
  retrieving revision 1.422
  retrieving revision 1.423
  diff -u -r1.422 -r1.423
  --- configure.in	27 Mar 2002 14:18:12 -0000	1.422
  +++ configure.in	4 Apr 2002 18:33:56 -0000	1.423
  @@ -568,6 +568,14 @@
   dnl #----------------------------- Checking for Shared Memory Support 
   echo $ac_n "${nl}Checking for Shared Memory Support...${nl}"
   
  +dnl The Posix function are in librt on Solaris. This will
  +dnl also help us find sem_open when doing locking below
  +case $host in
  +   *-solaris*)
  +       AC_CHECK_LIB(rt, shm_open)
  +       ;;
  +esac
  +
   AC_CHECK_HEADERS(sys/mman.h)
   APR_CHECK_DEFINE(MAP_ANON, sys/mman.h)
   AC_CHECK_FUNCS(mmap munmap shm_open shm_unlink)
  @@ -833,6 +841,7 @@
       poll.h		\
       process.h		\
       pwd.h		\
  +    semaphore.h		\
       signal.h		\
       stdarg.h		\
       stddef.h		\
  @@ -916,6 +925,7 @@
   AC_SUBST(signalh)
   AC_SUBST(sys_waith)
   AC_SUBST(pthreadh)
  +AC_SUBST(semaphoreh)
   
   dnl #----------------------------- Checking for h_errno in <netdb.h>
   if test "$netdbh" = "1"; then
  @@ -1230,6 +1240,8 @@
   
   AC_CHECK_FUNCS(semget semctl flock)
   APR_CHECK_FILE(/dev/zero)
  +AC_CHECK_HEADERS(semaphore.h)
  +AC_CHECK_FUNCS(sem_open sem_close sem_unlink sem_post sem_wait)
   
   # It's stupid, but not all platforms have union semun, even those that need it.
   AC_MSG_CHECKING(for union semun in sys/sem.h)
  @@ -1316,6 +1328,9 @@
   fi
   
   # See which lock mechanisms we can support on this system.
  +APR_IFALLYES(header:semaphore.h func:sem_open func_sem_close dnl
  +             func_sem_unlink func:sem_post func_sem_wait,
  +             hasposixser="1", hasposixser="0")
   APR_IFALLYES(func:semget func:semctl define:SEM_UNDO, hassysvser="1", 
                hassysvser="0")
   APR_IFALLYES(func:flock define:LOCK_EX, hasflockser="1", hasflockser="0")
  @@ -1330,7 +1345,7 @@
   # See which lock mechanism we'll select by default on this system.
   # The last APR_DECIDE to execute sets the default.
   # At this stage, we match the ordering in Apache 1.3
  -# which is (highest to lowest): pthread -> sysvsem -> fcntl -> flock
  +# which is (highest to lowest): pthread -> posixsem -> sysvsem -> fcntl -> flock
   #
   APR_BEGIN_DECISION([apr_lock implementation method])
   APR_IFALLYES(func:flock define:LOCK_EX,
  @@ -1339,6 +1354,9 @@
               APR_DECIDE(USE_FCNTL_SERIALIZE, [SVR4-style fcntl()]))
   APR_IFALLYES(func:semget func:semctl define:SEM_UNDO,
               APR_DECIDE(USE_SYSVSEM_SERIALIZE, [SysV IPC semget()]))
  +APR_IFALLYES(header:semaphore.h func:sem_open func_sem_close dnl
  +             func_sem_unlink func:sem_post func_sem_wait,
  +             APR_DECIDE(USE_POSIXSEM_SERIALIZE, [Posix sem_open()]))
   # note: the current APR use of shared mutex requires /dev/zero
   APR_IFALLYES(header:pthread.h define:PTHREAD_PROCESS_SHARED dnl
               func:pthread_mutexattr_setpshared dnl
  @@ -1352,6 +1370,7 @@
   
   flockser="0"
   sysvser="0"
  +posixser="0"
   procpthreadser="0"
   fcntlser="0"
   case $ac_decision in
  @@ -1364,6 +1383,9 @@
       USE_SYSVSEM_SERIALIZE )
           sysvser="1"
           ;;
  +    USE_POSIXSEM_SERIALIZE )
  +        posixser="1"
  +        ;;
       USE_PROC_PTHREAD_SERIALIZE )
           procpthreadser="1"
           ;;
  @@ -1371,11 +1393,13 @@
   
   AC_SUBST(hasflockser)
   AC_SUBST(hassysvser)
  +AC_SUBST(hasposixser)
   AC_SUBST(hasfcntlser)
   AC_SUBST(hasprocpthreadser)
   AC_SUBST(hasrwlockser)
   AC_SUBST(flockser)
   AC_SUBST(sysvser)
  +AC_SUBST(posixser)
   AC_SUBST(fcntlser)
   AC_SUBST(procpthreadser)
   AC_SUBST(pthreadser)
  
  
  
  1.105     +3 -0      apr/include/apr.h.in
  
  Index: apr.h.in
  ===================================================================
  RCS file: /home/cvs/apr/include/apr.h.in,v
  retrieving revision 1.104
  retrieving revision 1.105
  diff -u -r1.104 -r1.105
  --- apr.h.in	22 Mar 2002 06:06:26 -0000	1.104
  +++ apr.h.in	4 Apr 2002 18:33:56 -0000	1.105
  @@ -45,6 +45,7 @@
   #define APR_HAVE_NETINET_IN_H    @netinet_inh@
   #define APR_HAVE_NETINET_TCP_H   @netinet_tcph@
   #define APR_HAVE_PTHREAD_H       @pthreadh@
  +#define APR_HAVE_SEMAPHORE_H     @semaphoreh@
   #define APR_HAVE_SIGNAL_H        @signalh@
   #define APR_HAVE_STDARG_H        @stdargh@
   #define APR_HAVE_STDINT_H        @stdint@
  @@ -82,12 +83,14 @@
   
   #define APR_USE_FLOCK_SERIALIZE           @flockser@ 
   #define APR_USE_SYSVSEM_SERIALIZE         @sysvser@
  +#define APR_USE_POSIXSEM_SERIALIZE        @posixser@
   #define APR_USE_FCNTL_SERIALIZE           @fcntlser@
   #define APR_USE_PROC_PTHREAD_SERIALIZE    @procpthreadser@ 
   #define APR_USE_PTHREAD_SERIALIZE         @pthreadser@ 
   
   #define APR_HAS_FLOCK_SERIALIZE           @hasflockser@
   #define APR_HAS_SYSVSEM_SERIALIZE         @hassysvser@
  +#define APR_HAS_POSIXSEM_SERIALIZE        @hasposixser@
   #define APR_HAS_FCNTL_SERIALIZE           @hasfcntlser@
   #define APR_HAS_PROC_PTHREAD_SERIALIZE    @hasprocpthreadser@
   #define APR_HAS_RWLOCK_SERIALIZE          @hasrwlockser@
  
  
  
  1.6       +1 -0      apr/include/apr_global_mutex.h
  
  Index: apr_global_mutex.h
  ===================================================================
  RCS file: /home/cvs/apr/include/apr_global_mutex.h,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- apr_global_mutex.h	17 Mar 2002 13:21:26 -0000	1.5
  +++ apr_global_mutex.h	4 Apr 2002 18:33:56 -0000	1.6
  @@ -97,6 +97,7 @@
    *            APR_LOCK_FCNTL
    *            APR_LOCK_FLOCK
    *            APR_LOCK_SYSVSEM
  + *            APR_LOCK_POSIXSEM
    *            APR_LOCK_PROC_PTHREAD
    *            APR_LOCK_DEFAULT     pick the default mechanism for the platform
    * </PRE>
  
  
  
  1.34      +3 -1      apr/include/apr_lock.h
  
  Index: apr_lock.h
  ===================================================================
  RCS file: /home/cvs/apr/include/apr_lock.h,v
  retrieving revision 1.33
  retrieving revision 1.34
  diff -u -r1.33 -r1.34
  --- apr_lock.h	13 Mar 2002 20:39:14 -0000	1.33
  +++ apr_lock.h	4 Apr 2002 18:33:56 -0000	1.34
  @@ -80,7 +80,8 @@
   
   typedef enum {APR_READER, APR_WRITER} apr_readerwriter_e;
   
  -typedef enum {APR_LOCK_FCNTL, APR_LOCK_FLOCK, APR_LOCK_SYSVSEM, APR_LOCK_PROC_PTHREAD,
  +typedef enum {APR_LOCK_FCNTL, APR_LOCK_FLOCK, APR_LOCK_SYSVSEM,
  +              APR_LOCK_PROC_PTHREAD, APR_LOCK_POSIXSEM,
                 APR_LOCK_DEFAULT} apr_lockmech_e;
   
   typedef struct apr_lock_t    apr_lock_t;
  @@ -107,6 +108,7 @@
    *            APR_LOCK_FCNTL
    *            APR_LOCK_FLOCK
    *            APR_LOCK_SYSVSEM
  + *            APR_LOCK_POSIXSEM
    *            APR_LOCK_PROC_PTHREAD
    *            APR_LOCK_DEFAULT     pick the default mechanism for the platform
    * </PRE>
  
  
  
  1.6       +1 -0      apr/include/apr_proc_mutex.h
  
  Index: apr_proc_mutex.h
  ===================================================================
  RCS file: /home/cvs/apr/include/apr_proc_mutex.h,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- apr_proc_mutex.h	13 Mar 2002 20:39:14 -0000	1.5
  +++ apr_proc_mutex.h	4 Apr 2002 18:33:56 -0000	1.6
  @@ -91,6 +91,7 @@
    *            APR_LOCK_FCNTL
    *            APR_LOCK_FLOCK
    *            APR_LOCK_SYSVSEM
  + *            APR_LOCK_POSIXSEM
    *            APR_LOCK_PROC_PTHREAD
    *            APR_LOCK_DEFAULT     pick the default mechanism for the platform
    * </PRE>
  
  
  
  1.42      +6 -0      apr/include/arch/unix/locks.h
  
  Index: locks.h
  ===================================================================
  RCS file: /home/cvs/apr/include/arch/unix/locks.h,v
  retrieving revision 1.41
  retrieving revision 1.42
  diff -u -r1.41 -r1.42
  --- locks.h	13 Mar 2002 20:39:18 -0000	1.41
  +++ locks.h	4 Apr 2002 18:33:56 -0000	1.42
  @@ -95,6 +95,9 @@
   #if APR_HAVE_PTHREAD_H
   #include <pthread.h>
   #endif
  +#if APR_HAVE_SEMAPHORE_H
  +#include <semaphore.h>
  +#endif
   /* End System Headers */
   
   struct apr_unix_lock_methods_t {
  @@ -113,6 +116,9 @@
   /* bit values for flags field in apr_unix_lock_methods_t */
   #define APR_PROCESS_LOCK_MECH_IS_GLOBAL          1
   
  +#if APR_HAS_POSIXSEM_SERIALIZE
  +extern const apr_unix_lock_methods_t apr_unix_posix_methods;
  +#endif
   #if APR_HAS_SYSVSEM_SERIALIZE
   extern const apr_unix_lock_methods_t apr_unix_sysv_methods;
   #endif
  
  
  
  1.5       +6 -0      apr/include/arch/unix/proc_mutex.h
  
  Index: proc_mutex.h
  ===================================================================
  RCS file: /home/cvs/apr/include/arch/unix/proc_mutex.h,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- proc_mutex.h	13 Mar 2002 20:39:19 -0000	1.4
  +++ proc_mutex.h	4 Apr 2002 18:33:56 -0000	1.5
  @@ -97,6 +97,9 @@
   #if APR_HAVE_PTHREAD_H
   #include <pthread.h>
   #endif
  +#if APR_HAVE_SEMAPHORE_H
  +#include <semaphore.h>
  +#endif
   /* End System Headers */
   
   struct apr_proc_mutex_unix_lock_methods_t {
  @@ -113,6 +116,9 @@
   /* bit values for flags field in apr_unix_lock_methods_t */
   #define APR_PROCESS_LOCK_MECH_IS_GLOBAL          1
   
  +#if APR_HAS_POSIXSEM_SERIALIZE
  +extern const apr_proc_mutex_unix_lock_methods_t apr_proc_mutex_unix_posix_methods;
  +#endif
   #if APR_HAS_SYSVSEM_SERIALIZE
   extern const apr_proc_mutex_unix_lock_methods_t apr_proc_mutex_unix_sysv_methods;
   #endif
  
  
  
  1.59      +121 -0    apr/locks/unix/crossproc.c
  
  Index: crossproc.c
  ===================================================================
  RCS file: /home/cvs/apr/locks/unix/crossproc.c,v
  retrieving revision 1.58
  retrieving revision 1.59
  diff -u -r1.58 -r1.59
  --- crossproc.c	13 Mar 2002 20:39:21 -0000	1.58
  +++ crossproc.c	4 Apr 2002 18:33:56 -0000	1.59
  @@ -58,6 +58,124 @@
   #include "locks.h"
   #include "fileio.h" /* for apr_mkstemp() */
   
  +#if APR_HAS_POSIXSEM_SERIALIZE
  +
  +#ifndef SEM_FAILED
  +#define SEM_FAILED (-1)
  +#endif
  +
  +static void posix_setup(void)
  +{
  +}
  +
  +static apr_status_t posix_cleanup(void *lock_)
  +{
  +    apr_lock_t *lock=lock_;
  +    apr_status_t stat = APR_SUCCESS;
  +    
  +    if (lock->interproc->filedes != -1) {
  +        if (sem_close((sem_t *)lock->interproc->filedes) < 0) {
  +            stat = errno;
  +        }
  +    }
  +    return stat;
  +}    
  +
  +static apr_status_t posix_create(apr_lock_t *new, const char *fname)
  +{
  +    sem_t *psem;
  +    apr_status_t stat;
  +    char semname[14];
  +    unsigned long epoch;
  +    
  +    new->interproc = apr_palloc(new->pool, sizeof(*new->interproc));
  +    /*
  +     * This bogusness is to follow what appears to be the
  +     * lowest common denominator in Posix semaphore naming:
  +     *   - start with '/'
  +     *   - be at most 14 chars
  +     *   - be unique and not match anything on the filesystem
  +     *
  +     * Because of this, we ignore fname and craft our own.
  +     *
  +     * FIXME: if we try to create another semaphore within a second
  +     * of creating this on, we won't get a new one but another
  +     * reference to this one.
  +     */
  +    epoch = apr_time_now() / APR_USEC_PER_SEC;
  +    apr_snprintf(semname, sizeof(semname), "/ApR.%lx", epoch);
  +    psem = sem_open((const char *) semname, O_CREAT, 0644, 1);
  +
  +    if (psem == (sem_t *)SEM_FAILED) {
  +        stat = errno;
  +        posix_cleanup(new);
  +        return stat;
  +    }
  +    /* Ahhh. The joys of Posix sems. Predelete it... */
  +    sem_unlink((const char *) semname);
  +    new->interproc->filedes = (int)psem;	/* Ugg */
  +    apr_pool_cleanup_register(new->pool, (void *)new, posix_cleanup, 
  +                              apr_pool_cleanup_null);
  +    return APR_SUCCESS;
  +}
  +
  +static apr_status_t posix_acquire(apr_lock_t *lock)
  +{
  +    int rc;
  +
  +    if ((rc = sem_wait((sem_t *)lock->interproc->filedes)) < 0) {
  +        return errno;
  +    }
  +    lock->curr_locked = 1;
  +    return APR_SUCCESS;
  +}
  +
  +static apr_status_t posix_release(apr_lock_t *lock)
  +{
  +    int rc;
  +
  +    if ((rc = sem_post((sem_t *)lock->interproc->filedes)) < 0) {
  +        return errno;
  +    }
  +    lock->curr_locked = 0;
  +    return APR_SUCCESS;
  +}
  +
  +static apr_status_t posix_destroy(apr_lock_t *lock)
  +{
  +    apr_status_t stat;
  +
  +    if ((stat = posix_cleanup(lock)) == APR_SUCCESS) {
  +        apr_pool_cleanup_kill(lock->pool, lock, posix_cleanup);
  +        return APR_SUCCESS;
  +    }
  +    return stat;
  +}
  +
  +static apr_status_t posix_child_init(apr_lock_t **lock, apr_pool_t *cont, const char *fname)
  +{
  +    return APR_SUCCESS;
  +}
  +
  +const apr_unix_lock_methods_t apr_unix_posix_methods =
  +{
  +#if APR_PROCESS_LOCK_IS_GLOBAL || !APR_HAS_THREADS
  +    APR_PROCESS_LOCK_MECH_IS_GLOBAL,
  +#else
  +    0,
  +#endif
  +    posix_create,
  +    posix_acquire,
  +    NULL, /* no tryacquire */
  +    NULL, /* no rw lock */
  +    NULL, /* no rw lock */
  +    posix_release,
  +    posix_destroy,
  +    posix_child_init
  +};
  +
  +#endif /* Posix sem implementation */
  +
   #if APR_HAS_SYSVSEM_SERIALIZE
   
   static struct sembuf op_on;
  @@ -598,6 +716,9 @@
   
   void apr_unix_setup_lock(void)
   {
  +#if APR_HAS_POSIXSEM_SERIALIZE
  +    posix_setup();
  +#endif
   #if APR_HAS_SYSVSEM_SERIALIZE
       sysv_setup();
   #endif
  
  
  
  1.67      +12 -3     apr/locks/unix/locks.c
  
  Index: locks.c
  ===================================================================
  RCS file: /home/cvs/apr/locks/unix/locks.c,v
  retrieving revision 1.66
  retrieving revision 1.67
  diff -u -r1.66 -r1.67
  --- locks.c	13 Mar 2002 20:39:21 -0000	1.66
  +++ locks.c	4 Apr 2002 18:33:56 -0000	1.67
  @@ -152,6 +152,13 @@
           return APR_ENOTIMPL;
   #endif
           break;
  +    case APR_LOCK_POSIXSEM:
  +#if APR_HAS_POSIXSEM_SERIALIZE
  +        new->inter_meth = &apr_unix_posix_methods;
  +#else
  +        return APR_ENOTIMPL;
  +#endif
  +        break;
       case APR_LOCK_PROC_PTHREAD:
   #if APR_HAS_PROC_PTHREAD_SERIALIZE
           new->inter_meth = &apr_unix_proc_pthread_methods;
  @@ -162,6 +169,8 @@
       case APR_LOCK_DEFAULT:
   #if APR_USE_FLOCK_SERIALIZE
           new->inter_meth = &apr_unix_flock_methods;
  +#elif APR_USE_POSIXSEM_SERIALIZE
  +        new->inter_meth = &apr_unix_posix_methods;
   #elif APR_USE_SYSVSEM_SERIALIZE
           new->inter_meth = &apr_unix_sysv_methods;
   #elif APR_USE_FCNTL_SERIALIZE
  @@ -242,7 +251,7 @@
       new->pool  = pool;
       new->type  = type;
       new->scope = scope;
  -#if APR_HAS_SYSVSEM_SERIALIZE || APR_HAS_FCNTL_SERIALIZE || APR_HAS_FLOCK_SERIALIZE
  +#if APR_HAS_SYSVSEM_SERIALIZE || APR_HAS_FCNTL_SERIALIZE || APR_HAS_FLOCK_SERIALIZE || APR_HAS_POSIXSEM_SERIALIZE
       new->interproc = NULL;
   #endif
   
  @@ -362,7 +371,7 @@
   
   APR_DECLARE(apr_status_t) apr_os_lock_get(apr_os_lock_t *oslock, apr_lock_t *lock)
   {
  -#if APR_HAS_SYSVSEM_SERIALIZE || APR_HAS_FCNTL_SERIALIZE || APR_HAS_FLOCK_SERIALIZE
  +#if APR_HAS_SYSVSEM_SERIALIZE || APR_HAS_FCNTL_SERIALIZE || APR_HAS_FLOCK_SERIALIZE || APR_HAS_POSIXSEM_SERIALIZE
       oslock->crossproc = lock->interproc->filedes;
   #endif
   #if APR_HAS_PROC_PTHREAD_SERIALIZE
  @@ -387,7 +396,7 @@
           (*lock) = (apr_lock_t *)apr_pcalloc(pool, sizeof(apr_lock_t));
           (*lock)->pool = pool;
       }
  -#if APR_HAS_SYSVSEM_SERIALIZE || APR_HAS_FCNTL_SERIALIZE || APR_HAS_FLOCK_SERIALIZE
  +#if APR_HAS_SYSVSEM_SERIALIZE || APR_HAS_FCNTL_SERIALIZE || APR_HAS_FLOCK_SERIALIZE || APR_HAS_POSIXSEM_SERIALIZE
       apr_os_file_put(&(*lock)->interproc, &thelock->crossproc, 0, pool);
   #endif
   #if APR_HAS_PROC_PTHREAD_SERIALIZE
  
  
  
  1.14      +136 -3    apr/locks/unix/proc_mutex.c
  
  Index: proc_mutex.c
  ===================================================================
  RCS file: /home/cvs/apr/locks/unix/proc_mutex.c,v
  retrieving revision 1.13
  retrieving revision 1.14
  diff -u -r1.13 -r1.14
  --- proc_mutex.c	1 Apr 2002 21:03:04 -0000	1.13
  +++ proc_mutex.c	4 Apr 2002 18:33:56 -0000	1.14
  @@ -57,6 +57,127 @@
   #include "proc_mutex.h"
   #include "fileio.h" /* for apr_mkstemp() */
   
  +#if APR_HAS_POSIXSEM_SERIALIZE
  +
  +#ifndef SEM_FAILED
  +#define SEM_FAILED (-1)
  +#endif
  +
  +static void proc_mutex_posix_setup(void)
  +{
  +}
  +
  +static apr_status_t proc_mutex_posix_cleanup(void *mutex_)
  +{
  +    apr_proc_mutex_t *mutex=mutex_;
  +    apr_status_t stat = APR_SUCCESS;
  +    
  +    if (mutex->interproc->filedes != -1) {
  +        if (sem_close((sem_t *)mutex->interproc->filedes) < 0) {
  +            stat = errno;
  +        }
  +    }
  +    return stat;
  +}    
  +
  +static apr_status_t proc_mutex_posix_create(apr_proc_mutex_t *new_mutex,
  +                                            const char *fname)
  +{
  +    sem_t *psem;
  +    apr_status_t stat;
  +    char semname[14];
  +    unsigned long epoch;
  +    
  +    new_mutex->interproc = apr_palloc(new_mutex->pool,
  +                                      sizeof(*new_mutex->interproc));
  +    /*
  +     * This bogusness is to follow what appears to be the
  +     * lowest common denominator in Posix semaphore naming:
  +     *   - start with '/'
  +     *   - be at most 14 chars
  +     *   - be unique and not match anything on the filesystem
  +     *
  +     * Because of this, we ignore fname and craft our own.
  +     *
  +     * FIXME: if we try to create another semaphore within a second
  +     * of creating this on, we won't get a new one but another
  +     * reference to this one.
  +     */
  +    epoch = apr_time_now() / APR_USEC_PER_SEC;
  +    apr_snprintf(semname, sizeof(semname), "/ApR.%lx", epoch);
  +    psem = sem_open((const char *) semname, O_CREAT, 0644, 1);
  +
  +    if (psem == (sem_t *)SEM_FAILED) {
  +        stat = errno;
  +        proc_mutex_posix_cleanup(new_mutex);
  +        return stat;
  +    }
  +    /* Ahhh. The joys of Posix sems. Predelete it... */
  +    sem_unlink((const char *) semname);
  +    new_mutex->interproc->filedes = (int)psem;	/* Ugg */
  +    apr_pool_cleanup_register(new_mutex->pool, (void *)new_mutex,
  +                              proc_mutex_posix_cleanup, 
  +                              apr_pool_cleanup_null);
  +    return APR_SUCCESS;
  +}
  +
  +static apr_status_t proc_mutex_posix_acquire(apr_proc_mutex_t *mutex)
  +{
  +    int rc;
  +
  +    if ((rc = sem_wait((sem_t *)mutex->interproc->filedes)) < 0) {
  +        return errno;
  +    }
  +    mutex->curr_locked = 1;
  +    return APR_SUCCESS;
  +}
  +
  +static apr_status_t proc_mutex_posix_release(apr_proc_mutex_t *mutex)
  +{
  +    int rc;
  +
  +    if ((rc = sem_post((sem_t *)mutex->interproc->filedes)) < 0) {
  +        return errno;
  +    }
  +    mutex->curr_locked = 0;
  +    return APR_SUCCESS;
  +}
  +
  +static apr_status_t proc_mutex_posix_destroy(apr_proc_mutex_t *mutex)
  +{
  +    apr_status_t stat;
  +
  +    if ((stat = proc_mutex_posix_cleanup(mutex)) == APR_SUCCESS) {
  +        apr_pool_cleanup_kill(mutex->pool, mutex, proc_mutex_posix_cleanup);
  +        return APR_SUCCESS;
  +    }
  +    return stat;
  +}
  +
  +static apr_status_t proc_mutex_posix_child_init(apr_proc_mutex_t **mutex,
  +                                                apr_pool_t *cont,
  +                                                const char *fname)
  +{
  +    return APR_SUCCESS;
  +}
  +
  +const apr_proc_mutex_unix_lock_methods_t apr_proc_mutex_unix_posix_methods =
  +{
  +#if APR_PROCESS_LOCK_IS_GLOBAL || !APR_HAS_THREADS
  +    APR_PROCESS_LOCK_MECH_IS_GLOBAL,
  +#else
  +    0,
  +#endif
  +    proc_mutex_posix_create,
  +    proc_mutex_posix_acquire,
  +    NULL, /* no tryacquire */
  +    proc_mutex_posix_release,
  +    proc_mutex_posix_destroy,
  +    proc_mutex_posix_child_init
  +};
  +
  +#endif /* Posix sem implementation */
  +
   #if APR_HAS_SYSVSEM_SERIALIZE
   
   static struct sembuf proc_mutex_op_on;
  @@ -612,6 +733,9 @@
   
   void apr_proc_mutex_unix_setup_lock(void)
   {
  +#if APR_HAS_POSIXSEM_SERIALIZE
  +    proc_mutex_posix_setup();
  +#endif
   #if APR_HAS_SYSVSEM_SERIALIZE
       proc_mutex_sysv_setup();
   #endif
  @@ -650,6 +774,13 @@
           return APR_ENOTIMPL;
   #endif
           break;
  +    case APR_LOCK_POSIXSEM:
  +#if APR_HAS_POSIXSEM_SERIALIZE
  +        new_mutex->inter_meth = &apr_proc_mutex_unix_posix_methods;
  +#else
  +        return APR_ENOTIMPL;
  +#endif
  +        break;
       case APR_LOCK_PROC_PTHREAD:
   #if APR_HAS_PROC_PTHREAD_SERIALIZE
           new_mutex->inter_meth = &apr_proc_mutex_unix_proc_pthread_methods;
  @@ -666,6 +797,8 @@
           new_mutex->inter_meth = &apr_proc_mutex_unix_fcntl_methods;
   #elif APR_USE_PROC_PTHREAD_SERIALIZE
           new_mutex->inter_meth = &apr_proc_mutex_unix_proc_pthread_methods;
  +#elif APR_USE_POSIXSEM_SERIALIZE
  +        new_mutex->inter_meth = &apr_proc_mutex_unix_posix_methods;
   #else
           return APR_ENOTIMPL;
   #endif
  @@ -707,7 +840,7 @@
                                                   sizeof(apr_proc_mutex_t));
   
       new_mutex->pool  = pool;
  -#if APR_HAS_SYSVSEM_SERIALIZE || APR_HAS_FCNTL_SERIALIZE || APR_HAS_FLOCK_SERIALIZE
  +#if APR_HAS_SYSVSEM_SERIALIZE || APR_HAS_FCNTL_SERIALIZE || APR_HAS_FLOCK_SERIALIZE || APR_HAS_POSIXSEM_SERIALIZE
       new_mutex->interproc = NULL;
   #endif
   
  @@ -807,7 +940,7 @@
   APR_DECLARE(apr_status_t) apr_os_proc_mutex_get(apr_os_proc_mutex_t *ospmutex,
                                                   apr_proc_mutex_t *pmutex)
   {
  -#if APR_HAS_SYSVSEM_SERIALIZE || APR_HAS_FCNTL_SERIALIZE || APR_HAS_FLOCK_SERIALIZE
  +#if APR_HAS_SYSVSEM_SERIALIZE || APR_HAS_FCNTL_SERIALIZE || APR_HAS_FLOCK_SERIALIZE || APR_HAS_POSIXSEM_SERIALIZE
       ospmutex->crossproc = pmutex->interproc->filedes;
   #endif
   #if APR_HAS_PROC_PTHREAD_SERIALIZE
  @@ -828,7 +961,7 @@
                                                       sizeof(apr_proc_mutex_t));
           (*pmutex)->pool = pool;
       }
  -#if APR_HAS_SYSVSEM_SERIALIZE || APR_HAS_FCNTL_SERIALIZE || APR_HAS_FLOCK_SERIALIZE
  +#if APR_HAS_SYSVSEM_SERIALIZE || APR_HAS_FCNTL_SERIALIZE || APR_HAS_FLOCK_SERIALIZE || APR_HAS_POSIXSEM_SERIALIZE
       apr_os_file_put(&(*pmutex)->interproc, &ospmutex->crossproc, 0, pool);
   #endif
   #if APR_HAS_PROC_PTHREAD_SERIALIZE
  
  
  

Re: cvs commit: apr/locks/unix crossproc.c locks.c proc_mutex.c

Posted by Jeff Trawick <tr...@attglobal.net>.
Aaron Bannert <aa...@clove.org> writes:

> On Thu, Apr 04, 2002 at 04:04:46PM -0500, Jeff Trawick wrote:
> > You should hard-code posix semaphores for Darwin in apr_hints.m4.  We
> > should not be playing around with the lock choice and affecting
> > multiple systems when we get specific platform knowledge we want to
> > exploit.  apr_hints.m4 is for that specific platform knowledge.
> 
> I don't consider this to be platform specific knowledge. Posix semaphores
> can be used on other platforms as well (Jim said he tested it on
> Solaris).

There is a big difference between "can be used" and "should be used."
flock() "can be used" on a bunch of systems but nobody went to the
trouble to add the right AC_CHECK_LIB() function to pick up BSD
compatibility stuff because nobody wants to use it on those systems
because the performance is not up to par with the other choices.

What you are saying is they "should be used" on Darwin.  Sorry, but I
cannot agree that that is anything but platform specific knowledge
:)

When an OS/390 kernel guru says SysV sems "should be used" on OS/390,
that is platform-specific knowledge and is unrelated to the fact that
SysV sems "can be used" on AIX (where pthread mutexes "should be
used" since their use results in better scalability of programs like
Apache).

> So is sem_open() broken on linux 2.2.12 or is it just being used incorrectly?

I looked at the usage (reviewing Stevens UNP volume 2) and the code looks
reasonable.  In fact, I don't see how anybody could screw it up.

There is no "sem_open" in the 2.2.12 kernel sources.  I googled and
found some weak indications that sem_open() doesn't work with this
level of glibc.  I was surprised that I didn't get a crystal clear
indication (I did find a note from Ulrich Drepper in 1996 explaining
how they work and why he thought kernel support was needed; but lots
of things can happen since 1996 so that isn't a strong indication).

-- 
Jeff Trawick | trawick@attglobal.net
Born in Roswell... married an alien...

Re: cvs commit: apr/locks/unix crossproc.c locks.c proc_mutex.c

Posted by Pier Fumagalli <pi...@betaversion.org>.
"Aaron Bannert" <aa...@clove.org> wrote:

> On Thu, Apr 04, 2002 at 04:04:46PM -0500, Jeff Trawick wrote:
>> You should hard-code posix semaphores for Darwin in apr_hints.m4.  We
>> should not be playing around with the lock choice and affecting
>> multiple systems when we get specific platform knowledge we want to
>> exploit.  apr_hints.m4 is for that specific platform knowledge.
> 
> I don't consider this to be platform specific knowledge. Posix semaphores
> can be used on other platforms as well (Jim said he tested it on
> Solaris).
> 
> So is sem_open() broken on linux 2.2.12 or is it just being used incorrectly?

Isn't it somehow related to glibc rather than to the kernel?

    Pier


Re: cvs commit: apr/locks/unix crossproc.c locks.c proc_mutex.c

Posted by Aaron Bannert <aa...@clove.org>.
On Thu, Apr 04, 2002 at 04:04:46PM -0500, Jeff Trawick wrote:
> You should hard-code posix semaphores for Darwin in apr_hints.m4.  We
> should not be playing around with the lock choice and affecting
> multiple systems when we get specific platform knowledge we want to
> exploit.  apr_hints.m4 is for that specific platform knowledge.

I don't consider this to be platform specific knowledge. Posix semaphores
can be used on other platforms as well (Jim said he tested it on
Solaris).

So is sem_open() broken on linux 2.2.12 or is it just being used incorrectly?

-aaron

Re: cvs commit: apr/locks/unix crossproc.c locks.c proc_mutex.c

Posted by Jeff Trawick <tr...@attglobal.net>.
Aaron Bannert <aa...@clove.org> writes:

> On Thu, Apr 04, 2002 at 03:39:41PM -0500, Jeff Trawick wrote:
> > "sem_open("/ApR.whatever", O_CREAT, 0644,1)" returns ENOSYS on Linux
> > (2.2.12 kernel).  I'll try to add an autoconf check for that.
> > 
> > Beyond the issue mentioned above, why is a new lock mechanism
> > suddenly so high in the priority list?  Aren't we throwing away a lot
> > of past experience (1.3 and 2.0)?
> 
> Posix semaphores appear to be the only non-filesystem-based way to
> get cross-process mutexes on Darwin. We're looking for a performance
> boost above fcntl/flock.

You should hard-code posix semaphores for Darwin in apr_hints.m4.  We
should not be playing around with the lock choice and affecting
multiple systems when we get specific platform knowledge we want to
exploit.  apr_hints.m4 is for that specific platform knowledge.

-- 
Jeff Trawick | trawick@attglobal.net
Born in Roswell... married an alien...

Re: cvs commit: apr/locks/unix crossproc.c locks.c proc_mutex.c

Posted by Aaron Bannert <aa...@clove.org>.
On Thu, Apr 04, 2002 at 03:39:41PM -0500, Jeff Trawick wrote:
> "sem_open("/ApR.whatever", O_CREAT, 0644,1)" returns ENOSYS on Linux
> (2.2.12 kernel).  I'll try to add an autoconf check for that.
> 
> Beyond the issue mentioned above, why is a new lock mechanism
> suddenly so high in the priority list?  Aren't we throwing away a lot
> of past experience (1.3 and 2.0)?

Posix semaphores appear to be the only non-filesystem-based way to
get cross-process mutexes on Darwin. We're looking for a performance
boost above fcntl/flock.

-aaron

Re: cvs commit: apr/locks/unix crossproc.c locks.c proc_mutex.c

Posted by Jeff Trawick <tr...@attglobal.net>.
jim@apache.org writes:

> jim         02/04/04 10:33:57
> 
>   Modified:    .        CHANGES configure.in
>                include  apr.h.in apr_global_mutex.h apr_lock.h
>                         apr_proc_mutex.h
>                include/arch/unix locks.h proc_mutex.h
>                locks/unix crossproc.c locks.c proc_mutex.c
>   Log:
>   Support for Posix semaphores for locking has been added. This uses
>   named semaphores (sem_open). Because there are a few different
>   implementations around, this uses the lowest common denominator in
>   creating the semaphore name. As far as its location in DEFAULT
>   priority, it's placed between pthread and sysvsem. Tested on
>   Darwin (in which it's the new default) and Solaris.

"sem_open("/ApR.whatever", O_CREAT, 0644,1)" returns ENOSYS on Linux
(2.2.12 kernel).  I'll try to add an autoconf check for that.

Beyond the issue mentioned above, why is a new lock mechanism
suddenly so high in the priority list?  Aren't we throwing away a lot
of past experience (1.3 and 2.0)?

-- 
Jeff Trawick | trawick@attglobal.net
Born in Roswell... married an alien...

Re: cvs commit: apr/locks/unix crossproc.c locks.c proc_mutex.c

Posted by Jeff Trawick <tr...@attglobal.net>.
jim@apache.org writes:

> jim         02/04/04 10:33:57
> 
>   Modified:    .        CHANGES configure.in
>                include  apr.h.in apr_global_mutex.h apr_lock.h
>                         apr_proc_mutex.h
>                include/arch/unix locks.h proc_mutex.h
>                locks/unix crossproc.c locks.c proc_mutex.c
>   Log:
>   Support for Posix semaphores for locking has been added. This uses
>   named semaphores (sem_open). Because there are a few different
>   implementations around, this uses the lowest common denominator in
>   creating the semaphore name. As far as its location in DEFAULT
>   priority, it's placed between pthread and sysvsem. Tested on
>   Darwin (in which it's the new default) and Solaris.

"sem_open("/ApR.whatever", O_CREAT, 0644,1)" returns ENOSYS on Linux
(2.2.12 kernel).  I'll try to add an autoconf check for that.

Beyond the issue mentioned above, why is a new lock mechanism
suddenly so high in the priority list?  Aren't we throwing away a lot
of past experience (1.3 and 2.0)?

-- 
Jeff Trawick | trawick@attglobal.net
Born in Roswell... married an alien...