commons-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mt...@apache.org
Subject svn commit: r806450 - in /commons/sandbox/runtime/trunk/src/main/native: configure os/unix/pmutex.c
Date Fri, 21 Aug 2009 08:25:33 GMT
Author: mturk
Date: Fri Aug 21 08:25:33 2009
New Revision: 806450

URL: http://svn.apache.org/viewvc?rev=806450&view=rev
Log:
Combine posix and sysv mutexes and decide what to use at configure time

Modified:
    commons/sandbox/runtime/trunk/src/main/native/configure
    commons/sandbox/runtime/trunk/src/main/native/os/unix/pmutex.c

Modified: commons/sandbox/runtime/trunk/src/main/native/configure
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/configure?rev=806450&r1=806449&r2=806450&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/configure (original)
+++ commons/sandbox/runtime/trunk/src/main/native/configure Fri Aug 21 08:25:33 2009
@@ -89,6 +89,7 @@
 has_memprotect=no
 has_maintainer_mode=no
 has_native_threads=no
+has_sysv_mutex=no
 is_unix=true
 
 has_openssl=no
@@ -539,6 +540,9 @@
 if [ ".$has_memprotect" = .yes ]; then
     varadds cppopts -DACR_ENABLE_SEH
 fi
+if [ ".$has_sysv_mutex" = .yes ]; then
+    varadds cppopts -DACR_USE_SYSV_MUTEX
+fi
 if [ ".$has_test" = .yes ]; then
     varadds cppopts -DACR_ENABLE_TEST
     testobjs='$(TEST_OBJS)'

Modified: commons/sandbox/runtime/trunk/src/main/native/os/unix/pmutex.c
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/unix/pmutex.c?rev=806450&r1=806449&r2=806450&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/os/unix/pmutex.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/os/unix/pmutex.c Fri Aug 21 08:25:33 2009
@@ -28,6 +28,9 @@
 #include "acr_descriptor.h"
 #include "acr_procmutex.h"
 
+#include <sys/ipc.h>
+#include <sys/sem.h>
+#include <sys/file.h>
 #include <semaphore.h>
 
 #ifndef SEM_FAILED
@@ -52,19 +55,404 @@
 
 static volatile unsigned int _mtx_counter = 1;
 
+union semun {
+    int val;
+    struct semid_ds *buf;
+    unsigned short *array;
+};
+
+typedef struct semblock_t {
+    acr_uint32_t    magic;       /* Is this our memeory     */
+    pid_t           creator;     /* Creator's process ID    */
+    acr_uint32_t    value;       /* Maximum semaphore value */
+} semblock_t;
+
+
 struct acr_pmutex_t {
-    sem_t *sem;
-    int    locked;
-    char   name[NAME_MAX];
+    int         locked;
+#if defined(ACR_USE_SYSV_MUTEX)
+    int         filedes;
+    const char *filename;       /* NULL if anonymous */
+#else
+    sem_t      *sem;
+    char        filename[NAME_MAX];
+#endif
 };
 
+ACR_CLASS_LDEF(Mutex)
+{
+    int rv;
+
+    if ((rv = ACR_LoadClass(_E, &_clazzn, 0)) != ACR_SUCCESS)
+        return rv;
+    J_LOAD_METHOD(0000);
+
+    return ACR_SUCCESS;
+}
+
+ACR_CLASS_UDEF(Mutex)
+{
+    ACR_UnloadClass(_E, &_clazzn);
+}
+
+#if defined(ACR_USE_SYSV_MUTEX)
+
+static int mutex_owner_cleanup(void *mutex, int type, unsigned int flags)
+{
+    if (type == ACR_DT_MUTEX) {
+        int rc = ACR_SUCCESS;
+        acr_pmutex_t *m = (acr_pmutex_t *)mutex;
+        if (m->filedes > 0) {
+            union semun ick;
+            if (m->locked) {
+                struct sembuf op;
+                /* Unlock our instance */
+                op.sem_num = 0;
+                op.sem_op  = 1;
+                op.sem_flg = SEM_UNDO;
+                do {
+                    rc = semop(m->filedes, &op, 1);
+                } while (rc < 0 && errno == EINTR);
+            }
+            ick.val = 0;
+            semctl(m->filedes, 0, IPC_RMID, ick);
+        }
+        if (m->filename) {
+            if (access(m->filename, F_OK)) {
+                rc = ACR_SUCCESS;
+            }
+            else {
+                if (unlink(m->filename))
+                    rc = ACR_GET_OS_ERROR();
+            }
+            free((void *)(m->filename));
+        }
+        free(m);
+        return rc;
+    }
+    return ACR_EBADF;
+}
+
+static int mutex_child_cleanup(void *mutex, int type, unsigned int flags)
+{
+    if (type == ACR_DT_MUTEX) {
+        int rc;
+        acr_pmutex_t *m = (acr_pmutex_t *)mutex;
+        if (m->filedes > 0) {
+            if (m->locked) {
+                struct sembuf op;
+                /* Unlock our instance */
+                op.sem_num = 0;
+                op.sem_op  = 1;
+                op.sem_flg = SEM_UNDO;
+                do {
+                    rc = semop(m->filedes, &op, 1);
+                } while (rc < 0 && errno == EINTR);
+            }
+        }
+        free(m);
+        return ACR_SUCCESS;
+    }
+    return ACR_EBADF;
+}
+
+ACR_DECLARE(int) ACR_ProcMutexCreate(JNIEnv *_E, const acr_pchar_t *fname)
+{
+    union semun ick;
+    int rc = 0;
+    acr_pmutex_t *m;
+    key_t mkey = IPC_PRIVATE;
+    int flags  = IPC_CREAT;
+
+    if (fname) {
+        size_t     nbytes;
+        semblock_t hdr;
+        int fs, fd = -1;
+
+        fd = open(fname, O_WRONLY | O_CREAT | O_EXCL, 0660);
+        if (fd < 0) {
+            rc =  ACR_GET_OS_ERROR();
+            ACR_THROW_IO_ERRNO();
+            return -1;
+        }
+        mkey = ftok(fname, 1);
+        if (mkey == (key_t)-1) {
+            rc =  ACR_GET_OS_ERROR();
+            close(fd);
+            ACR_THROW_IO_IF_ERR(rc);
+            return -1;
+        }
+        /* Write our header to shadow file
+         * Not needed, but might be used in the
+         * future to pass some data along with the mutex
+         */
+        nbytes = sizeof(semblock_t);
+        hdr.creator = getpid();
+        hdr.magic   = ACR_MTX_MAGIC;
+        hdr.value   = 1;
+        do {
+            fs = write(fd,(const void *)&hdr, nbytes);
+        } while (fs == (acr_size_t)-1 && errno == EINTR);
+        if (fs == -1) {
+            rc = ACR_GET_OS_ERROR();
+            close(fd);
+            ACR_THROW_IO_IF_ERR(rc);
+            return -1;
+        }
+        close(fd);
+        flags |= IPC_EXCL;
+    }
+    m = ACR_Calloc(_E, THROW_FMARK, sizeof(acr_pmutex_t));
+    if (!m)
+        return -1;
+    if (fname) {
+        m->filename = ACR_StrdupA(_E, THROW_FMARK, fname);
+        if (!m->filename) {
+            rc =  ACR_GET_OS_ERROR();
+            free(m);
+            ACR_SET_OS_ERROR(rc);
+            return -1;
+        }
+    }
+    m->filedes = semget(mkey, 1, flags | 0660);
+
+    if (m->filedes < 0) {
+        if (fname && errno == EEXIST) {
+            /* XXX: Should we throw separate exception here?
+             */
+        }
+        rc =  ACR_GET_OS_ERROR();
+        goto finally;
+    }
+    ick.val = 1;
+    if (semctl(m->filedes, 0, SETVAL, ick) < 0) {
+        rc =  ACR_GET_OS_ERROR();
+        goto finally;
+    }
+    m->locked = 0;
+
+finally:
+    if (rc) {
+        if (m->filedes > 0) {
+            ick.val = 0;
+            semctl(m->filedes, 0, IPC_RMID, ick);
+        }
+        x_free((void *)(m->filename));
+        free(m);
+        ACR_THROW_IO_IF_ERR(rc);
+        return -1;
+    }
+    else {
+        rc = acr_ioh_open(m, ACR_DT_MUTEX, 0, mutex_owner_cleanup);
+        return rc;
+    }
+}
+
+ACR_DECLARE(int) ACR_ProcMutexAttach(JNIEnv *_E, const acr_pchar_t *fname)
+{
+    int rc = 0;
+    acr_pmutex_t *m;
+    key_t mkey;
+    int   file;
+
+    if (!fname) {
+        /* Cannot attach to unnamed mutex */
+        ACR_THROW_IO_IF_ERR(ACR_EINVAL);
+        return -1;
+    }
+
+    file = open(fname, O_RDONLY);
+    if (file < 0) {
+        ACR_THROW_IO_ERRNO();
+        return -1;
+    }
+
+    mkey = ftok(fname, 1);
+    if (mkey == (key_t)-1) {
+        rc = ACR_GET_OS_ERROR();
+        close(file);
+        ACR_THROW_IO_IF_ERR(rc);
+        return -1;
+    }
+    close(file);
+    m = ACR_Calloc(_E, THROW_FMARK, sizeof(acr_pmutex_t));
+    if (!m)
+        return -1;
+
+    m->filedes = semget(mkey, 1, 0);
+    if (m->filedes < 0) {
+        rc =  ACR_GET_OS_ERROR();
+        goto finally;
+    }
+    m->locked = 0;
+
+finally:
+    if (rc) {
+        free(m);
+        ACR_THROW_IO_IF_ERR(rc);
+        return -1;
+    }
+    else {
+        rc = acr_ioh_open(m, ACR_DT_MUTEX, 0, mutex_child_cleanup);
+        return rc;
+    }
+}
+
+ACR_DECLARE(int) ACR_ProcMutexLock(JNIEnv *_E, int mutex)
+{
+    int rc;
+    struct sembuf op;
+    acr_pmutex_t *m = (acr_pmutex_t *)ACR_IOH(mutex);
+
+    if (IS_INVALID_HANDLE(m) || ACR_IOH_TYPE(mutex) != ACR_DT_MUTEX) {
+        ACR_SET_OS_ERROR(ACR_EINVAL);
+        return -1;
+    }
+    op.sem_num = 0;
+    op.sem_op  = -1;
+    op.sem_flg = SEM_UNDO;
+
+    do {
+        rc = semop(m->filedes, &op, 1);
+    } while (rc < 0 && errno == EINTR);
+
+    if (rc < 0)
+        return ACR_GET_OS_ERROR();
+    m->locked = 1;
+
+    return ACR_SUCCESS;
+}
+
+ACR_DECLARE(int) ACR_ProcMutexTryLock(JNIEnv *_E, int mutex)
+{
+    int rc;
+    struct sembuf op;
+    acr_pmutex_t *m = (acr_pmutex_t *)ACR_IOH(mutex);
+
+    if (IS_INVALID_HANDLE(m) || ACR_IOH_TYPE(mutex) != ACR_DT_MUTEX) {
+        return ACR_EINVAL;
+    }
+    op.sem_num = 0;
+    op.sem_op  = -1;
+    op.sem_flg = SEM_UNDO | IPC_NOWAIT;
+
+    do {
+        rc = semop(m->filedes, &op, 1);
+    } while (rc < 0 && errno == EINTR);
+
+    if (rc < 0) {
+        if (errno == EAGAIN) {
+            return ACR_EBUSY;
+        }
+        else
+            return ACR_GET_OS_ERROR();
+    }
+    else
+        m->locked = 1;
+
+    return ACR_SUCCESS;;
+}
+
+ACR_DECLARE(int) ACR_ProcMutexRelease(JNIEnv *_E, int mutex)
+{
+    int rc;
+    struct sembuf op;
+    acr_pmutex_t *m = (acr_pmutex_t *)ACR_IOH(mutex);
+
+    if (IS_INVALID_HANDLE(m) || ACR_IOH_TYPE(mutex) != ACR_DT_MUTEX) {
+        return ACR_EINVAL;
+    }
+
+    m->locked  = 0;
+    op.sem_num = 0;
+    op.sem_op  = 1;
+    op.sem_flg = SEM_UNDO;
+    do {
+        rc = semop(m->filedes, &op, 1);
+    } while (rc < 0 && errno == EINTR);
+
+    if (rc < 0)
+        return ACR_GET_OS_ERROR();
+    else
+        return ACR_SUCCESS;
+}
+
+ACR_DECLARE(int) ACR_ProcMutexPermSet(JNIEnv *_E, int mutex, int perms,
+                                      acr_uid_t uid, acr_uid_t gid)
+{
+    union  semun ick;
+    struct semid_ds buf;
+    acr_pmutex_t *m = (acr_pmutex_t *)ACR_IOH(mutex);
+
+    if (IS_INVALID_HANDLE(m) || ACR_IOH_TYPE(mutex) != ACR_DT_MUTEX) {
+        return ACR_EINVAL;
+    }
+    buf.sem_perm.uid  = uid;
+    buf.sem_perm.gid  = gid;
+    buf.sem_perm.mode = ACR_UnixPermsToMode(perms);
+    ick.buf = &buf;
+
+    if (semctl(m->filedes, 0, IPC_SET, ick) < 0) {
+        return ACR_GET_OS_ERROR();
+    }
+    else
+        return ACR_SUCCESS;
+}
+
+ACR_DECLARE(int) ACR_ProcMutexRemove(JNIEnv *_E, const acr_pchar_t *filename)
+{
+    union semun ick;
+    int         rc = 0;
+    int         file;
+    key_t       mkey;
+    int         mfid;
+
+    /* Presume that the file already exists; just open for writing.
+     * Mode is not needed cause we don't use O_CREAT flag.
+     */
+    file = open(filename, O_WRONLY);
+    if (file < 0) {
+        rc = ACR_GET_OS_ERROR();
+        goto finally;
+    }
+
+    /* ftok() (on solaris at least) requires that the file actually
+     * exist before calling ftok().
+     */
+    mkey = ftok(filename, 1);
+    if (mkey == (key_t)-1) {
+        rc = ACR_GET_OS_ERROR();
+        close(file);
+        goto finally;
+    }
+    close(file);
+    mfid = semget(mkey, 1, 0);
+
+    if ((mfid = semget(mkey, 1, 0)) < 0) {
+        rc =  ACR_GET_OS_ERROR();
+        goto finally;
+    }
+    ick.val = 0;
+    if (semctl(mfid, 0, IPC_RMID, ick) < 0) {
+        rc = ACR_GET_OS_ERROR();
+        goto finally;
+    }
+
+finally:
+    unlink(filename);
+    ACR_THROW_IO_IF_ERR(rc);
+    return rc;
+}
+
+#else   /* ACR_USE_SYSV_MUTEX */
+
 static int mutex_cleanup(void *mutex, int type, unsigned int flags)
 {
     if (type == ACR_DT_MUTEX) {
         int rc = 0;
         acr_pmutex_t *m = (acr_pmutex_t *)mutex;
-        if (m->name[0])
-            sem_unlink(m->name);
+        if (m->filename[0])
+            sem_unlink(m->filename);
         if (m->sem != (sem_t *)SEM_FAILED) {
             if (sem_close(m->sem) < 0)
                 rc = ACR_GET_OS_ERROR();
@@ -85,27 +473,27 @@
     if (!m)
         return -1;
     if (!name)
-        sprintf(m->name, "/AcM.%08x", _mtx_counter++);
+        sprintf(m->filename, "/AcM.%08x", _mtx_counter++);
     else {
         if (*name != '/')
-            m->name[0] = '/';
-        strlcat(m->name, name, NAME_MAX - 2);
+            m->filename[0] = '/';
+        strlcat(m->filename, name, NAME_MAX - 2);
     }
-    for (p = &m->name[1]; *p; p++) {
+    for (p = &m->filename[1]; *p; p++) {
         if (*p == '/')
             *p = '_';
     }
     do {
-        m->sem = sem_open(m->name, O_CREAT | O_EXCL, 0660, 1);
+        m->sem = sem_open(m->filename, O_CREAT | O_EXCL, 0660, 1);
         if (m->sem == (sem_t *)SEM_FAILED) {
             if (rc)
                 goto finally;
             rc = ACR_GET_OS_ERROR();
             if (errno == ENAMETOOLONG) {
-                m->name[13] = '\0';
+                m->filename[13] = '\0';
                 continue;
             } else if (errno == EEXIST && !name) {
-                sprintf(m->name, "/AcM.%08x", _mtx_counter++);
+                sprintf(m->filename, "/AcM.%08x", _mtx_counter++);
                 rc = 0;
                 continue;
             }
@@ -117,8 +505,8 @@
          * Unlink the semaphore immediately, so it can't be accessed externally.
          * However this prevents calling attach.
          */
-        sem_unlink(m->name);
-        m->name[0] = '\0';
+        sem_unlink(m->filename);
+        m->filename[0] = '\0';
     }
     m->locked = 0;
 
@@ -148,19 +536,19 @@
     if (!m)
         return -1;
     if (*name != '/')
-        m->name[0] = '/';
-    strlcat(m->name, name, NAME_MAX - 2);
-    for (p = &m->name[1]; *p; p++) {
+        m->filename[0] = '/';
+    strlcat(m->filename, name, NAME_MAX - 2);
+    for (p = &m->filename[1]; *p; p++) {
         if (*p == '/')
             *p = '_';
     }
-    m->sem = sem_open(m->name, O_RDWR);
+    m->sem = sem_open(m->filename, O_RDWR);
     if (m->sem == (sem_t *)SEM_FAILED) {
         rc = ACR_GET_OS_ERROR();
         goto finally;
     }
-    m->name[0] = '\0';
-    m->locked  = 0;
+    m->filename[0] = '\0';
+    m->locked      = 0;
 finally:
     if (rc) {
         x_free(m);
@@ -246,29 +634,12 @@
     return ACR_ENOTIMPL;
 }
 
-ACR_DECLARE(int) ACR_ProcMutexClose(JNIEnv *_E, int mutex)
+ACR_DECLARE(int) ACR_ProcMutexRemove(JNIEnv *_E, const acr_pchar_t *filename)
 {
-
-    /* Close will call the cleanup function
-     */
-    return acr_ioh_close(mutex);
-}
-
-ACR_CLASS_LDEF(Mutex)
-{
-    int rv;
-
-    if ((rv = ACR_LoadClass(_E, &_clazzn, 0)) != ACR_SUCCESS)
-        return rv;
-    J_LOAD_METHOD(0000);
-
-    return ACR_SUCCESS;
+    return ACR_ENOTIMPL;
 }
 
-ACR_CLASS_UDEF(Mutex)
-{
-    ACR_UnloadClass(_E, &_clazzn);
-}
+#endif  /* ACR_USE_SYSV_MUTEX */
 
 static int mtx_descriptor_cleanup(ACR_JNISTDARGS,
                                   acr_descriptor_cb_type_e cm,
@@ -289,6 +660,14 @@
     return rc;
 }
 
+ACR_DECLARE(int) ACR_ProcMutexClose(JNIEnv *_E, int mutex)
+{
+
+    /* Close will call the cleanup function
+     */
+    return acr_ioh_close(mutex);
+}
+
 ACR_DECLARE(jobject) ACR_ProcMutexObjectCreate(JNIEnv *_E,
                                                const acr_pchar_t *name)
 {



Mime
View raw message