You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by mt...@apache.org on 2009/08/14 19:26:22 UTC

svn commit: r804304 - in /commons/sandbox/runtime/trunk/src/main/native: Makefile.in include/acr_descriptor.h include/acr_semaphore.h os/unix/psema.c

Author: mturk
Date: Fri Aug 14 17:26:21 2009
New Revision: 804304

URL: http://svn.apache.org/viewvc?rev=804304&view=rev
Log:
Add posix semaphore wrapper

Added:
    commons/sandbox/runtime/trunk/src/main/native/include/acr_semaphore.h   (with props)
    commons/sandbox/runtime/trunk/src/main/native/os/unix/psema.c   (with props)
Modified:
    commons/sandbox/runtime/trunk/src/main/native/Makefile.in
    commons/sandbox/runtime/trunk/src/main/native/include/acr_descriptor.h

Modified: commons/sandbox/runtime/trunk/src/main/native/Makefile.in
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/Makefile.in?rev=804304&r1=804303&r2=804304&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/Makefile.in (original)
+++ commons/sandbox/runtime/trunk/src/main/native/Makefile.in Fri Aug 14 17:26:21 2009
@@ -109,6 +109,7 @@
 	$(SRCDIR)/os/unix/group.$(OBJ) \
 	$(SRCDIR)/os/unix/user.$(OBJ) \
 	$(SRCDIR)/os/unix/pmutex.$(OBJ) \
+	$(SRCDIR)/os/unix/psema.$(OBJ) \
 	$(SRCDIR)/os/unix/shm.$(OBJ) \
 	$(SRCDIR)/os/unix/signals.$(OBJ) \
 	$(SRCDIR)/os/unix/syslog.$(OBJ) \
@@ -132,6 +133,7 @@
 	$(SRCDIR)/os/unix/group.$(OBJ) \
 	$(SRCDIR)/os/unix/user.$(OBJ) \
 	$(SRCDIR)/os/unix/pmutex.$(OBJ) \
+	$(SRCDIR)/os/unix/psema.$(OBJ) \
 	$(SRCDIR)/os/unix/shm.$(OBJ) \
 	$(SRCDIR)/os/unix/signals.$(OBJ) \
 	$(SRCDIR)/os/unix/syslog.$(OBJ) \
@@ -152,6 +154,7 @@
 	$(SRCDIR)/os/unix/ios.$(OBJ) \
 	$(SRCDIR)/os/unix/group.$(OBJ) \
 	$(SRCDIR)/os/unix/user.$(OBJ) \
+	$(SRCDIR)/os/unix/psema.$(OBJ) \
 	$(SRCDIR)/os/unix/shm.$(OBJ) \
 	$(SRCDIR)/os/unix/signals.$(OBJ) \
 	$(SRCDIR)/os/unix/syslog.$(OBJ) \
@@ -174,6 +177,7 @@
 	$(SRCDIR)/os/unix/group.$(OBJ) \
 	$(SRCDIR)/os/unix/user.$(OBJ) \
 	$(SRCDIR)/os/unix/pmutex.$(OBJ) \
+	$(SRCDIR)/os/unix/psema.$(OBJ) \
 	$(SRCDIR)/os/unix/signals.$(OBJ) \
 	$(SRCDIR)/os/unix/syslog.$(OBJ) \
 	$(SRCDIR)/os/unix/time.$(OBJ) \

Modified: commons/sandbox/runtime/trunk/src/main/native/include/acr_descriptor.h
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/include/acr_descriptor.h?rev=804304&r1=804303&r2=804304&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/include/acr_descriptor.h (original)
+++ commons/sandbox/runtime/trunk/src/main/native/include/acr_descriptor.h Fri Aug 14 17:26:21 2009
@@ -40,6 +40,7 @@
 #define ACR_DT_PIPE             0x00000006
 #define ACR_DT_SOCKET           0x00000007
 #define ACR_DT_DSO              0x00000008
+#define ACR_DT_SEMAPHORE        0x00000009
 #define ACR_DT_MASK             0x000000FF
 
 typedef enum {

Added: commons/sandbox/runtime/trunk/src/main/native/include/acr_semaphore.h
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/include/acr_semaphore.h?rev=804304&view=auto
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/include/acr_semaphore.h (added)
+++ commons/sandbox/runtime/trunk/src/main/native/include/acr_semaphore.h Fri Aug 14 17:26:21 2009
@@ -0,0 +1,95 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _ACR_SEMAPHORE_H
+#define _ACR_SEMAPHORE_H
+
+#include "acr.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @file acr_semaphore.h
+ * @brief
+ *
+ * ACR Semaphore functions
+ *
+ */
+
+/**
+ * Private, platform-specific data struture representing a semaphore.
+ */
+typedef struct acr_semaphore_t acr_semaphore_t;
+
+
+/**
+ * Create and initialize a semaphore that can be used to synchronize processes.
+ * @param env JNI environment to use.
+ * @param name A name to use for the semaphore.
+ * @param value Initial semaphore value.
+ */
+ACR_DECLARE(int) ACR_SemaphoreCreate(JNIEnv *env, const acr_pchar_t *name,
+                                     int value);
+
+/**
+ * Re-open a semaphore in child process.
+ * @param env JNI environment to use.
+ * @param name A name of the semaphore to open.
+ */
+ACR_DECLARE(int) ACR_SemaphoreAttach(JNIEnv *env, const acr_pchar_t *name);
+
+/**
+ * Acquire the lock for the given semaphore.
+ * If the semaphore is already locked,
+ * the current thread will be put to sleep until the lock becomes available.
+ * @param env JNI environment to use.
+ * @param semaphore the semaphore on which to acquire the lock.
+ */
+ACR_DECLARE(int) ACR_SemaphoreWait(JNIEnv *env, int semaphore);
+
+/**
+ * Attempt to acquire the lock for the given semaphore.
+ * If the semaphore has already
+ * been acquired, the call returns immediately with APR_EBUSY. Note: it
+ * is important that the APR_STATUS_IS_EBUSY(s) macro be used to determine
+ * if the return value was APR_EBUSY, for portability reasons.
+ * @param env JNI environment to use.
+ * @param semaphore the semaphore on which to attempt the lock acquiring.
+ */
+ACR_DECLARE(int) ACR_SemaphoreTryWait(JNIEnv *env, int semaphore);
+
+/**
+ * Release the lock for the given mutex.
+ * @param env JNI environment to use.
+ * @param semaphore the semaphore from which to release the lock.
+ */
+ACR_DECLARE(int) ACR_SemaphoreRelease(JNIEnv *env, int semaphore);
+
+/**
+ * Destroy the semaphore and free the memory associated with the lock.
+ * @param env JNI environment to use.
+ * @param semaphore the semaphore to destroy.
+ */
+ACR_DECLARE(int) ACR_SemaphoreClose(JNIEnv *env, int semaphore);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _ACR_SEMAPHORE_H */
+

Propchange: commons/sandbox/runtime/trunk/src/main/native/include/acr_semaphore.h
------------------------------------------------------------------------------
    svn:eol-style = native

Added: commons/sandbox/runtime/trunk/src/main/native/os/unix/psema.c
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/unix/psema.c?rev=804304&view=auto
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/os/unix/psema.c (added)
+++ commons/sandbox/runtime/trunk/src/main/native/os/unix/psema.c Fri Aug 14 17:26:21 2009
@@ -0,0 +1,249 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "acr.h"
+#include "acr_private.h"
+#include "acr_arch.h"
+#include "acr_error.h"
+#include "acr_memory.h"
+#include "acr_string.h"
+#include "acr_descriptor.h"
+#include "acr_semaphore.h"
+
+#include <semaphore.h>
+
+#ifndef SEM_FAILED
+#define SEM_FAILED (-1)
+#endif
+
+static volatile unsigned int _sem_counter = 1;
+
+struct acr_semaphore_t {
+    sem_t *sem;
+    int    locked;
+    char   name[64];
+};
+
+static int semaphore_cleanup(void *sema, int type, unsigned int flags)
+{
+    if (type != ACR_DT_SEMAPHORE) {
+        int rc = 0;
+        acr_semaphore_t *s = (acr_semaphore_t *)sema;
+        if (s->name[0])
+            sem_unlink(s->name);
+        if (s->sem != (sem_t *)SEM_FAILED) {
+            if (sem_close(s->sem) < 0)
+                rc = ACR_GET_OS_ERROR();
+        }
+        free(s);
+        return rc;
+    }
+    return ACR_EINVAL;
+}
+
+ACR_DECLARE(int) ACR_SemaphoreCreate(JNIEnv *_E, const acr_pchar_t *name,
+                                     int value)
+{
+    unsigned int ic = _sem_counter;
+    int rc = 0;
+    acr_semaphore_t *s;
+
+    s = ACR_Calloc(_E, THROW_FMARK, sizeof(acr_semaphore_t));
+    if (!s)
+        return -1;
+    if (!name)
+        sprintf(s->name, "/AcS.%06x%02x", ((unsigned int)getpid() & 0xFFFFFF),
+                                          _sem_counter++);
+    else
+        strncpy(s->name, name, 63);
+    do {
+        s->sem = sem_open(s->name, O_CREAT | O_EXCL, 0644, value);
+        if (s->sem == (sem_t *)SEM_FAILED) {
+            if (rc)
+                goto finally;
+            rc = ACR_GET_OS_ERROR();
+            if (rc == ENAMETOOLONG) {
+                s->name[13] = '\0';
+                continue;
+            } else if (rc == EEXIST && !name) {
+                if ((_sem_counter - ic) > 10)
+                    goto finally;
+                sprintf(s->name, "/AcS.%06x%02x",
+                        ((unsigned int)getpid() & 0xFFFFFF),
+                        _sem_counter++);
+                rc = 0;
+            }
+        }
+    } while (rc != 0);
+
+    if (!name) {
+        /* 
+         * Unlink the semaphore immediately, so it can't be accessed externally.
+         * However this prevents calling attach.
+         */
+        sem_unlink(s->name);
+        s->name[0] = '\0';
+    }
+    s->locked = 0;
+finally:
+    if (rc) {
+        free(s);
+        if (!IS_INVALID_HANDLE(_E)) {
+            if (rc == EACCES)
+                ACR_ThrowException(_E, THROW_NMARK, ACR_EX_ESECURITY, 0);
+            else
+                ACR_ThrowException(_E, THROW_NMARK, ACR_EX_EIO, rc);
+        }
+        ACR_SET_OS_ERROR(rc);
+        return -1;
+    }
+    else {
+        rc = acr_ioh_open(s, ACR_DT_SEMAPHORE, 0, semaphore_cleanup);
+        return rc;
+    }
+}
+
+ACR_DECLARE(int) ACR_SemaphoreAttach(JNIEnv *_E, const acr_pchar_t *name)
+{
+    int rc = 0;
+    acr_semaphore_t *s = NULL;
+
+    if (!name) {
+        rc = ACR_EINVAL;
+        goto finally;
+    }
+    s = ACR_Calloc(_E, THROW_FMARK, sizeof(acr_semaphore_t));
+    if (!s)
+        return -1;
+    s->sem = sem_open(s->name, O_RDWR);
+    if (s->sem == (sem_t *)SEM_FAILED) {
+        rc = ACR_GET_OS_ERROR();
+        goto finally;
+    }
+    s->locked = 0;
+finally:
+    if (rc) {
+        x_free(s);
+        if (!IS_INVALID_HANDLE(_E)) {
+            if (rc == EACCES)
+                ACR_ThrowException(_E, THROW_NMARK, ACR_EX_ESECURITY, 0);
+            else
+                ACR_ThrowException(_E, THROW_NMARK, ACR_EX_EIO, rc);
+        }
+        ACR_SET_OS_ERROR(rc);
+        return -1;
+    }
+    else {
+        rc = acr_ioh_open(s, ACR_DT_SEMAPHORE, 0, semaphore_cleanup);
+        return rc;
+    }
+}
+
+ACR_DECLARE(int) ACR_SemaphoreClose(JNIEnv *_E, int sema)
+{
+
+    /* Close will call the cleanup function
+     */
+    return acr_ioh_close(sema);
+}
+
+ACR_DECLARE(int) ACR_SemaphorePermSet(JNIEnv *_E, int sema, int perms,
+                                      acr_uid_t uid, acr_uid_t gid)
+{
+    int rc;
+    acr_semaphore_t *s = (acr_semaphore_t *)ACR_IOH(sema);
+
+    if (IS_INVALID_HANDLE(s) || ACR_IOH_TYPE(sema) != ACR_DT_SEMAPHORE) {
+        return ACR_EINVAL;
+    }
+    if (!s->name[0])
+        return ACR_EINVAL;
+
+    if (uid != (uid_t)-1 && gid != (gid_t)-1) {
+        if (chown(s->name, uid, gid) < 0)
+            rc = ACR_GET_OS_ERROR();
+    }
+    if (!rc) {
+        if (chmod(s->name, ACR_UnixPermsToMode(perms)) < 0)
+            rc = ACR_GET_OS_ERROR();
+    }
+    return rc;
+}
+
+ACR_DECLARE(int) ACR_SemaphoreWait(JNIEnv *_E, int sema)
+{
+    int rc;
+    acr_semaphore_t *s = (acr_semaphore_t *)ACR_IOH(sema);
+
+    if (IS_INVALID_HANDLE(s) || ACR_IOH_TYPE(sema) != ACR_DT_SEMAPHORE) {
+        return ACR_EINVAL;
+    }
+
+    do {
+        rc = sem_wait(s->sem);
+    } while (rc < 0 && errno == EINTR);
+
+    if (rc < 0)
+        return ACR_GET_OS_ERROR();
+    s->locked = 1;
+
+    return ACR_SUCCESS;
+}
+
+ACR_DECLARE(int) ACR_SemaphoreTryWait(JNIEnv *_E, int sema)
+{
+    int rc;
+    acr_semaphore_t *s = (acr_semaphore_t *)ACR_IOH(sema);
+
+    if (IS_INVALID_HANDLE(s) || ACR_IOH_TYPE(sema) != ACR_DT_SEMAPHORE) {
+        return ACR_EINVAL;
+    }
+
+    do {
+        rc = sem_trywait(s->sem);
+    } while (rc < 0 && errno == EINTR);
+    if (rc < 0) {
+        if (errno == EAGAIN)
+            return ACR_EBUSY;
+        else
+            return ACR_GET_OS_ERROR();
+    }
+    s->locked = 1;
+
+    return ACR_SUCCESS;
+}
+
+ACR_DECLARE(int) ACR_SemaphoreRelease(JNIEnv *env, int sema)
+{
+    int rc;
+    acr_semaphore_t *s = (acr_semaphore_t *)ACR_IOH(sema);
+
+    if (IS_INVALID_HANDLE(s) || ACR_IOH_TYPE(sema) != ACR_DT_SEMAPHORE) {
+        return ACR_EINVAL;
+    }
+
+    s->locked = 0;
+    do {
+        rc = sem_post(s->sem);
+    } while (rc < 0 && errno == EINTR);
+
+    if (rc < 0)
+        return ACR_GET_OS_ERROR();
+    else
+        return ACR_SUCCESS;
+
+}
+

Propchange: commons/sandbox/runtime/trunk/src/main/native/os/unix/psema.c
------------------------------------------------------------------------------
    svn:eol-style = native