commons-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mt...@apache.org
Subject svn commit: r806454 - /commons/sandbox/runtime/trunk/src/main/native/os/darwin/pmutex.c
Date Fri, 21 Aug 2009 08:31:42 GMT
Author: mturk
Date: Fri Aug 21 08:31:42 2009
New Revision: 806454

URL: http://svn.apache.org/viewvc?rev=806454&view=rev
Log:
Add sysv mutexes for Darwin

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

Modified: commons/sandbox/runtime/trunk/src/main/native/os/darwin/pmutex.c
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/darwin/pmutex.c?rev=806454&r1=806453&r2=806454&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/os/darwin/pmutex.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/os/darwin/pmutex.c Fri Aug 21 08:31:42 2009
@@ -33,6 +33,7 @@
 #include "acr_procmutex.h"
 
 #include <sys/ipc.h>
+#include <sys/sem.h>
 #include <sys/file.h>
 
 J_DECLARE_CLAZZ = {
@@ -48,12 +49,362 @@
 };
 
 struct acr_pmutex_t {
-    int   filedes;
-    int   locked;
-    int   anon;
-    char *fname;
+    int         filedes;
+    int         locked;
+    const char *filename;
 };
 
+#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) {
@@ -74,9 +425,9 @@
         }
         if (m->filedes > 0)
             close(m->filedes);
-        if (m->fname) {
-            unlink(m->fname);
-            free(m->fname);
+        if (m->filename) {
+            unlink(m->filename);
+            free((void *)(m->filename));
         }
         free(m);
         return rc;
@@ -96,17 +447,17 @@
         m->anon = 1;
         fname   = "/tmp/apmXXXXXX";
     }
-    m->fname = ACR_StrdupA(_E, THROW_FMARK, fname);
-    if (!m->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;
     }
     if (m->anon)
-        m->filedes = mkstemp(m->fname);
+        m->filedes = mkstemp(m->filename);
     else
-        m->filedes = open(m->fname, O_CREAT | O_WRONLY | O_EXCL, 0660);
+        m->filedes = open(m->filename, O_CREAT | O_WRONLY | O_EXCL, 0660);
 
     if (m->filedes < 0) {
         rc =  ACR_GET_OS_ERROR();
@@ -116,7 +467,7 @@
 
 finally:
     if (rc) {
-        free(m->fname);
+        free((void *)(m->filename));
         free(m);
         ACR_THROW_IO_IF_ERR(rc);
         return -1;
@@ -149,7 +500,7 @@
 
 finally:
     if (rc) {
-        free(m->fname);
+        free((void *)(m->filename));
         free(m);
         ACR_THROW_IO_IF_ERR(rc);
         return -1;
@@ -262,14 +613,6 @@
         return ACR_SUCCESS;
 }
 
-ACR_DECLARE(int) ACR_ProcMutexClose(JNIEnv *_E, int mutex)
-{
-
-    /* Close will call the cleanup function
-     */
-    return acr_ioh_close(mutex);
-}
-
 ACR_DECLARE(int) ACR_ProcMutexRemove(JNIEnv *_E, const acr_pchar_t *filename)
 {
 
@@ -281,6 +624,16 @@
         return ACR_SUCCESS;
 }
 
+#endif  /* ACR_USE_SYSV_MUTEX */
+
+ACR_DECLARE(int) ACR_ProcMutexClose(JNIEnv *_E, int mutex)
+{
+
+    /* Close will call the cleanup function
+     */
+    return acr_ioh_close(mutex);
+}
+
 ACR_CLASS_LDEF(Mutex)
 {
     int rv;



Mime
View raw message