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 2011/04/19 17:06:05 UTC

svn commit: r1095107 - in /commons/sandbox/runtime/trunk/src/main: java/org/apache/commons/runtime/platform/unix/SysVMutex.java native/os/unix/posixapi.c native/os/unix/procmutex.c test/org/apache/commons/runtime/TestMutex.java

Author: mturk
Date: Tue Apr 19 15:06:05 2011
New Revision: 1095107

URL: http://svn.apache.org/viewvc?rev=1095107&view=rev
Log:
Implement SysV mutex

Modified:
    commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/platform/unix/SysVMutex.java
    commons/sandbox/runtime/trunk/src/main/native/os/unix/posixapi.c
    commons/sandbox/runtime/trunk/src/main/native/os/unix/procmutex.c
    commons/sandbox/runtime/trunk/src/main/test/org/apache/commons/runtime/TestMutex.java

Modified: commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/platform/unix/SysVMutex.java
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/platform/unix/SysVMutex.java?rev=1095107&r1=1095106&r2=1095107&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/platform/unix/SysVMutex.java (original)
+++ commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/platform/unix/SysVMutex.java Tue Apr 19 15:06:05 2011
@@ -18,6 +18,8 @@ package org.apache.commons.runtime.platf
 import org.apache.commons.runtime.Mutex;
 import org.apache.commons.runtime.Status;
 import org.apache.commons.runtime.AlreadyExistsException;
+import org.apache.commons.runtime.NoSuchObjectException;
+import org.apache.commons.runtime.ClosedDescriptorException;
 import org.apache.commons.runtime.SystemException;
 
 /**
@@ -34,15 +36,110 @@ final class SysVMutex extends Mutex
     {
         // No Instance
     }
+    private static native int  close0(int fd);
+    private static native int  create0(String name)
+        throws IllegalAccessException,
+               IllegalArgumentException,
+               AlreadyExistsException,
+               SystemException;
+    private static native int  open0(String name)
+        throws IllegalAccessException,
+               IllegalArgumentException,
+               NoSuchObjectException,
+               SystemException;
+
+    private static native int  wait0(int fd);
+    private static native int  try0(int fd);
+    private static native int  release0(int fd);
+
+    // OS mutex descriptor
+    private int    fd;
 
     public SysVMutex(final String name, boolean owner)
         throws IllegalAccessException,
                IllegalArgumentException,
                AlreadyExistsException,
+               NoSuchObjectException,
                UnsupportedOperationException,
                SystemException
     {
-        this.owner = true;
+        if (name == null)
+            throw new NullPointerException();
+        this.name = name;
+        if (owner)
+            fd = create0(this.name);
+        else
+            fd = open0(this.name);
+        this.owner = owner;
+    }
+
+    public void acquire()
+        throws SystemException
+    {
+        if (fd == -1)
+            throw new ClosedDescriptorException();
+        int rc = wait0(fd);
+        if (rc != 0)
+            throw new SystemException(Status.describe(rc));
+    }
+
+    public boolean tryAcquire()
+        throws SystemException
+    {
+        if (fd == -1)
+            throw new ClosedDescriptorException();
+        int rc = try0(fd);
+        if (rc == 0)
+            return true;
+        if (Status.IS_EBUSY(rc))
+            return false;
+        throw new SystemException(Status.describe(rc));
+    }
+
+    public void release()
+        throws SystemException
+    {
+        if (fd == -1)
+            throw new ClosedDescriptorException();
+        int rc = release0(fd);
+        if (rc != 0)
+            throw new SystemException(Status.describe(rc));
+    }
+
+    public void close()
+        throws SystemException
+    {
+        int rc;
+        if (fd == -1)
+            throw new ClosedDescriptorException();
+        release0(fd);
+        close0(fd);
+        if (owner) {
+            // Unlink if we are the semaphore owner.
+            rc = Posix.unlink(name);
+            if (rc != 0)
+                throw new SystemException(Status.describe(rc));
+        }
+        fd = -1;
+    }
+
+    /**
+     * Called by the garbage collector when the object is destroyed.
+     * The class will free internal resources allocated by the Operating system.
+     * @see Object#finalize()
+     * @throws Throwable the {@code Exception} raised by this method.
+     */
+    @Override
+    protected final void finalize()
+        throws Throwable
+    {
+        if (fd != -1) {
+            close0(fd);
+        }
+        if (owner) {
+            // Unlink if we are the semaphore owner.
+            Posix.unlink(name);
+        }
     }
 
 }

Modified: commons/sandbox/runtime/trunk/src/main/native/os/unix/posixapi.c
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/unix/posixapi.c?rev=1095107&r1=1095106&r2=1095107&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/os/unix/posixapi.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/os/unix/posixapi.c Tue Apr 19 15:06:05 2011
@@ -21,7 +21,7 @@
 
 #include <sys/mman.h>
 
-ACR_JNI_EXPORT(jint, Posix, open)(JNI_STDARGS, jstring name,
+ACR_UNX_EXPORT(jint, Posix, open)(JNI_STDARGS, jstring name,
                                   jint flags, jint mode)
 {
     int fd = -1;
@@ -55,7 +55,7 @@ ACR_JNI_EXPORT(jint, Posix, open)(JNI_ST
     return fd;
 }
 
-ACR_JNI_EXPORT(jint, Posix, close)(JNI_STDARGS, jint fd)
+ACR_UNX_EXPORT(jint, Posix, close)(JNI_STDARGS, jint fd)
 {
     if (r_close(fd) == 0)
         return 0;
@@ -63,7 +63,7 @@ ACR_JNI_EXPORT(jint, Posix, close)(JNI_S
         return errno;
 }
 
-ACR_JNI_EXPORT(jint, Posix, unlink)(JNI_STDARGS, jstring name)
+ACR_UNX_EXPORT(jint, Posix, unlink)(JNI_STDARGS, jstring name)
 {
     int rc = EINVAL;
 
@@ -77,7 +77,7 @@ ACR_JNI_EXPORT(jint, Posix, unlink)(JNI_
     return rc;
 }
 
-ACR_JNI_EXPORT(jint, Posix, chmod)(JNI_STDARGS, jstring name, jint mode)
+ACR_UNX_EXPORT(jint, Posix, chmod)(JNI_STDARGS, jstring name, jint mode)
 {
     int rc = EINVAL;
 
@@ -91,7 +91,7 @@ ACR_JNI_EXPORT(jint, Posix, chmod)(JNI_S
     return rc;
 }
 
-ACR_JNI_EXPORT(jint, Posix, chown)(JNI_STDARGS, jstring name, jint uid, jint gid)
+ACR_UNX_EXPORT(jint, Posix, chown)(JNI_STDARGS, jstring name, jint uid, jint gid)
 {
     int rc = EINVAL;
 
@@ -105,7 +105,7 @@ ACR_JNI_EXPORT(jint, Posix, chown)(JNI_S
     return rc;
 }
 
-ACR_JNI_EXPORT(jint, Posix, chdir)(JNI_STDARGS, jstring path)
+ACR_UNX_EXPORT(jint, Posix, chdir)(JNI_STDARGS, jstring path)
 {
     int rc = EINVAL;
 
@@ -119,7 +119,7 @@ ACR_JNI_EXPORT(jint, Posix, chdir)(JNI_S
     return rc;
 }
 
-ACR_JNI_EXPORT(jint, Posix, fchdir)(JNI_STDARGS, jint fd)
+ACR_UNX_EXPORT(jint, Posix, fchdir)(JNI_STDARGS, jint fd)
 {
     if (fchdir(fd) == 0)
         return 0;
@@ -127,7 +127,7 @@ ACR_JNI_EXPORT(jint, Posix, fchdir)(JNI_
         return errno;
 }
 
-ACR_JNI_EXPORT(jint, Posix, fchown)(JNI_STDARGS, jint fd, jint uid, jint gid)
+ACR_UNX_EXPORT(jint, Posix, fchown)(JNI_STDARGS, jint fd, jint uid, jint gid)
 {
     if (fchown(fd, (uid_t)uid, (gid_t)gid) == 0)
         return 0;
@@ -135,7 +135,7 @@ ACR_JNI_EXPORT(jint, Posix, fchown)(JNI_
         return errno;
 }
 
-ACR_JNI_EXPORT(jint, Posix, fchmod)(JNI_STDARGS, jint fd, jint mode)
+ACR_UNX_EXPORT(jint, Posix, fchmod)(JNI_STDARGS, jint fd, jint mode)
 {
     if (fchmod(fd, (mode_t)mode) == 0)
         return 0;
@@ -143,7 +143,7 @@ ACR_JNI_EXPORT(jint, Posix, fchmod)(JNI_
         return errno;
 }
 
-ACR_JNI_EXPORT(jstring, Posix, getcwd)(JNI_STDARGS)
+ACR_UNX_EXPORT(jstring, Posix, getcwd)(JNI_STDARGS)
 {
     char path[ACR_PATH_MAX];
 

Modified: commons/sandbox/runtime/trunk/src/main/native/os/unix/procmutex.c
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/unix/procmutex.c?rev=1095107&r1=1095106&r2=1095107&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/os/unix/procmutex.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/os/unix/procmutex.c Tue Apr 19 15:06:05 2011
@@ -102,17 +102,40 @@ ACR_JNI_EXPORT(jobject, MutexImpl, init0
     return (*env)->NewObject(env, _clazzn.i, J4MID(0000), (jint)_DEFAULT_MUTEX_TYPE);
 }
 
+ACR_JNI_EXPORT(jboolean, Mutex, unlink0)(JNI_STDARGS, jstring name)
+{
+    jboolean rc = JNI_FALSE;
+    WITH_CSTR(name) {
+#if _DEFAULT_MUTEX_TYPE == 1        
+        char *p;
+        char buf[PATH_MAX] = "/";
+
+        strlcat(buf, J2S(name), PATH_MAX);
+        for (p = &buf[1]; *p != '\0'; p++) {
+            if (*p == '/')
+                *p = '_';
+        }
+        if (sem_unlink(buf) == 0)
+            rc = JNI_TRUE;
+#else
+        if (unlink(J2S(name)) == 0)
+            rc = JNI_TRUE;
+#endif
+    } DONE_WITH_STR(name);
+    return rc;
+}
+
 ACR_UNX_EXPORT(jint, SysVMutex, create0)(JNI_STDARGS, jstring name)
 {
     union semun ick;
     int pd = -1;
     key_t mkey;
-    int flags  = IPC_CREAT;
 
     WITH_CSTR(name) {
         size_t     nbytes;
         semblock_t hdr;
-        int fd = -1;
+        int fd    = -1;
+        int flags = IPC_CREAT | IPC_EXCL;
 
         fd = open(J2S(name), O_WRONLY | O_CREAT | O_EXCL, 0660);
         if (fd == -1) {
@@ -136,13 +159,11 @@ ACR_UNX_EXPORT(jint, SysVMutex, create0)
             ACR_THROW_SYS_ERROR();
             goto cleanup;
         }
-        flags |= IPC_EXCL;
         pd = semget(mkey, 1, flags | 0660);
         if (pd == -1) {
             ACR_THROW_BY_ERRNO();
             goto cleanup;
         }
-
 cleanup:
         if (fd != -1) {
             close(fd);
@@ -176,6 +197,9 @@ ACR_UNX_EXPORT(jint, SysVMutex, open0)(J
             ACR_THROW_BY_ERRNO();
             goto cleanup;
         }
+        /* TODO: Read file header so we check if
+         * this is mutex shadow or not
+         */
         mkey = ftok(J2S(name), 'a');
         if (mkey == (key_t)-1) {
             ACR_THROW_SYS_ERROR();
@@ -196,21 +220,15 @@ cleanup:
     return pd;
 }
 
-ACR_UNX_EXPORT(jint, SysVMutex, unlink0)(JNI_STDARGS, jint fd, jstring name)
+ACR_UNX_EXPORT(jint, SysVMutex, close0)(JNI_STDARGS, jint fd)
 {
-    int rc = 0;
-
-    WITH_CSTR(name) {
-        union semun ick;
-
-        ick.val = 0;
-        if (semctl(fd, 0, IPC_RMID, ick) == -1)
-            rc = ACR_GET_OS_ERROR();
-        if (unlink(J2S(name)) == -1 && rc == 0)
-            rc = ACR_GET_OS_ERROR();
-    } DONE_WITH_STR(name);
+    union semun ick;
 
-    return rc;
+    ick.val = 0;
+    if (semctl(fd, 0, IPC_RMID, ick) == 0)
+        return 0;
+    else
+        return ACR_GET_OS_ERROR();
 }
 
 ACR_UNX_EXPORT(jint, SysVMutex, wait0)(JNI_STDARGS, jint fd)

Modified: commons/sandbox/runtime/trunk/src/main/test/org/apache/commons/runtime/TestMutex.java
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/test/org/apache/commons/runtime/TestMutex.java?rev=1095107&r1=1095106&r2=1095107&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/test/org/apache/commons/runtime/TestMutex.java (original)
+++ commons/sandbox/runtime/trunk/src/main/test/org/apache/commons/runtime/TestMutex.java Tue Apr 19 15:06:05 2011
@@ -24,7 +24,7 @@ import org.testng.Assert;
 public class TestMutex extends Assert
 {
 
-    private static final String semname = "acrMutex23";
+    private static final String mtxname = "acrMutex23";
 
     @Test(groups = { "mutex.parent" })
     public void checkMutex()
@@ -32,11 +32,11 @@ public class TestMutex extends Assert
     {
         System.out.flush();
         try {
-            Mutex s = Mutex.create(semname);
+            Mutex s = Mutex.create(mtxname);
             s.close();
         } catch (Exception ex) {
-            System.out.println("[parent] Removing stalled mutex " + semname);
-            assertTrue(Mutex.remove(semname));
+            System.out.println("[parent] Removing stalled mutex " + mtxname);
+            assertTrue(Mutex.remove(mtxname));
         }
     }
 
@@ -44,7 +44,7 @@ public class TestMutex extends Assert
     public void createMutex()
         throws Exception
     {
-        Mutex s = Mutex.create(semname);
+        Mutex s = Mutex.create(mtxname);
         assertNotNull(s);
         System.out.println("[parent] Waiting for a child to attach");
         System.out.flush();
@@ -67,7 +67,7 @@ public class TestMutex extends Assert
         int step = 125;
         while (step <= 2000) {
             try {
-                s = Mutex.open(semname);
+                s = Mutex.open(mtxname);
                 break;
             } catch (Exception x) {