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/09/29 09:08:58 UTC

svn commit: r819846 - /commons/sandbox/runtime/trunk/src/main/native/os/unix/fsysio.c

Author: mturk
Date: Tue Sep 29 07:08:57 2009
New Revision: 819846

URL: http://svn.apache.org/viewvc?rev=819846&view=rev
Log:
Implement range lock/unlock

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

Modified: commons/sandbox/runtime/trunk/src/main/native/os/unix/fsysio.c
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/unix/fsysio.c?rev=819846&r1=819845&r2=819846&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/os/unix/fsysio.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/os/unix/fsysio.c Tue Sep 29 07:08:57 2009
@@ -273,9 +273,76 @@
         struct flock l = { 0 };
         int fc;
 
-        l.l_whence = SEEK_SET;  /* lock from current point */
-        l.l_start  = 0;         /* begin lock at this offset */
-        l.l_len    = 0;         /* lock to end of file */
+        l.l_whence = SEEK_SET;    /* lock from current point */
+        l.l_start  = 0;           /* begin lock at this offset */
+        l.l_len    = 0;           /* lock to end of file */
+        if ((type & ACR_FLOCK_TYPEMASK) == ACR_FLOCK_SHARED)
+            l.l_type = F_RDLCK;
+        else
+            l.l_type = F_WRLCK;
+
+        fc = (type & ACR_FLOCK_NONBLOCK) ? F_SETLK : F_SETLKW;
+
+        /* keep trying if fcntl() gets interrupted (by a signal) */
+        while ((rc = fcntl(f->fd, fc, &l)) < 0 && errno == EINTR)
+            continue;
+
+        if (rc == -1) {
+            /* on some Unix boxes (e.g., Tru64), we get EACCES instead
+             * of EAGAIN; we don't want APR_STATUS_IS_EAGAIN() matching EACCES
+             * since that breaks other things, so fix up the retcode here
+             */
+            if (errno == EACCES) {
+                return ACR_EAGAIN;
+            }
+            return ACR_GET_OS_ERROR();
+        }
+    }
+#elif HAVE_SYS_FILE_H
+    {
+        int ltype;
+
+        if ((type & ACR_FLOCK_TYPEMASK) == ACR_FLOCK_SHARED)
+            ltype = LOCK_SH;
+        else
+            ltype = LOCK_EX;
+        if ((type & ACR_FLOCK_NONBLOCK) != 0)
+            ltype |= LOCK_NB;
+
+        /* keep trying if flock() gets interrupted (by a signal) */
+        while ((rc = flock(f->fd, ltype)) < 0 && errno == EINTR)
+            continue;
+
+        if (rc == -1)
+            return ACR_GET_OS_ERROR();
+    }
+#else
+#error No file locking mechanism is available.
+#endif
+    return 0;
+}
+
+ACR_IO_EXPORT_DECLARE(jint, FileSystemProvider, lock1)(ACR_JNISTDARGS,
+                                                       jint file,
+                                                       jint type,
+                                                       jlong off,
+                                                       jlong len)
+{
+    int rc;
+    acr_file_t *f = (acr_file_t *)ACR_IOH_FDATA(file);
+
+    if (ACR_IOH_FTYPE(file) != ACR_DT_FILE)
+        return ACR_EFTYPE;
+    if (IS_INVALID_HANDLE(f))
+        return ACR_EBADF;
+#if HAVE_FCNTL_H
+    {
+        struct flock l = { 0 };
+        int fc;
+
+        l.l_whence = SEEK_SET;    /* lock from current point */
+        l.l_start  = (off_t)off;  /* begin lock at this offset */
+        l.l_len    = (off_t)len;  /* lock to end of file */
         if ((type & ACR_FLOCK_TYPEMASK) == ACR_FLOCK_SHARED)
             l.l_type = F_RDLCK;
         else
@@ -336,9 +403,54 @@
     {
         struct flock l = { 0 };
 
-        l.l_whence = SEEK_SET;  /* lock from current point */
-        l.l_start  = 0;         /* begin lock at this offset */
-        l.l_len    = 0;         /* lock to end of file */
+        l.l_whence = SEEK_SET;    /* lock from current point */
+        l.l_start  = 0;           /* begin lock at this offset */
+        l.l_len    = 0;           /* lock to end of file */
+        l.l_type   = F_UNLCK;
+
+        /* keep trying if fcntl() gets interrupted (by a signal) */
+        while ((rc = fcntl(f->fd, F_SETLKW, &l)) < 0
+               && errno == EINTR)
+            continue;
+
+        if (rc == -1)
+            return ACR_GET_OS_ERROR();
+    }
+#elif HAVE_SYS_FILE_H
+    {
+        /* keep trying if flock() gets interrupted (by a signal) */
+        while ((rc = flock(f->fd, LOCK_UN)) < 0 && errno == EINTR)
+            continue;
+
+        if (rc == -1)
+            return ACR_GET_OS_ERROR();
+    }
+#else
+#error No file locking mechanism is available.
+#endif
+
+    return 0;
+}
+
+ACR_IO_EXPORT_DECLARE(jint, FileSystemProvider, unlock1)(ACR_JNISTDARGS,
+                                                         jint file,
+                                                         jlong off,
+                                                         jlong len)
+{
+    int rc;
+    acr_file_t *f = (acr_file_t *)ACR_IOH_FDATA(file);
+
+    if (ACR_IOH_FTYPE(file) != ACR_DT_FILE)
+        return ACR_EFTYPE;
+    if (IS_INVALID_HANDLE(f))
+        return ACR_EBADF;
+#if HAVE_FCNTL_H
+    {
+        struct flock l = { 0 };
+
+        l.l_whence = SEEK_SET;    /* lock from current point */
+        l.l_start  = (off_t)off;  /* begin lock at this offset */
+        l.l_len    = (off_t)len;  /* lock to end of file */
         l.l_type   = F_UNLCK;
 
         /* keep trying if fcntl() gets interrupted (by a signal) */
@@ -478,6 +590,8 @@
 {
     jbyte  *bb = NULL;
     jbyte  *bc = NULL;
+    size_t  po = (size_t)off;
+    size_t  cs = (size_t)len;
     jbyte   onstack[ACR_PBUFF_SIZ];
     ssize_t rd;
     acr_file_t *f = (acr_file_t *)ACR_IOH_FDATA(file);
@@ -493,14 +607,14 @@
     if (f->eof) {
         return -1;
     }
-    if (len > sizeof(onstack)) {
-        if (len > (1024 * 1024)) {
+    if (cs > sizeof(onstack)) {
+        if (cs > (1024 * 1024)) {
             bc = (*_E)->GetByteArrayElements(_E, buf, NULL);
             if (bc)
-                bb = bc + (size_t)off;
+                bb = bc + po;
         }
         else
-            bb = ACR_Malloc(_E, THROW_FMARK, (size_t)len);
+            bb = ACR_Malloc(_E, THROW_FMARK, cs);
     }
     else
         bb = onstack;
@@ -508,7 +622,7 @@
         /* Exception was already thrown */
         return -1;
     }
-    rd = r_read(f->fd, bb, (size_t)len);
+    rd = r_read(f->fd, bb, cs);
     if (rd == -1 && (errno == EAGAIN || errno == EWOULDBLOCK) &&
         f->timeout != 0) {
         int rc;
@@ -523,7 +637,7 @@
             return rc == ACR_TIMEUP ? 0 : -1;
         }
         else {
-            rd = r_read(f->fd, bb, (size_t)len);
+            rd = r_read(f->fd, bb, cs);
         }
     }
     if (rd == -1) {
@@ -542,7 +656,7 @@
             return (jint)rd;
         }
         else {
-            (*_E)->SetByteArrayRegion(_E, buf, (jsize)off, (jsize)rd, bb);
+            (*_E)->SetByteArrayRegion(_E, buf, (jsize)po, (jsize)rd, bb);
         }
     }
     if (bb != onstack) {
@@ -557,8 +671,8 @@
 ACR_IO_EXPORT_DECLARE(jint, FileSystemProvider, read2)(ACR_JNISTDARGS,
                                                        jint file,
                                                        jobject ptr,
-                                                       jint off,
-                                                       jint len)
+                                                       jlong off,
+                                                       jlong len)
 {
     size_t  pl;
     size_t  po = (size_t)off;
@@ -617,8 +731,8 @@
 ACR_IO_EXPORT_DECLARE(jint, FileSystemProvider, read3)(ACR_JNISTDARGS,
                                                        jint file,
                                                        jobject dbb,
-                                                       jint off,
-                                                       jint len)
+                                                       jlong off,
+                                                       jlong len)
 {
 #if defined(_DEBUG)
     size_t  pl;
@@ -766,8 +880,8 @@
 ACR_IO_EXPORT_DECLARE(jint, FileSystemProvider, write2)(ACR_JNISTDARGS,
                                                         jint file,
                                                         jobject ptr,
-                                                        jint off,
-                                                        jint len)
+                                                        jlong off,
+                                                        jlong len)
 {
     size_t  pl;
     size_t  po = (size_t)off;
@@ -818,8 +932,8 @@
 ACR_IO_EXPORT_DECLARE(jint, FileSystemProvider, write3)(ACR_JNISTDARGS,
                                                         jint file,
                                                         jobject dbb,
-                                                        jint off,
-                                                        jint len)
+                                                        jlong off,
+                                                        jlong len)
 {
 #if defined(_DEBUG)
     size_t  pl;
@@ -886,8 +1000,8 @@
     ssize_t wr;
     struct iovec *iov;
     struct iovec  onstack[ACR_IOVEC_ON_STACK];
-    jobject       bastack[ACR_IOVEC_ON_STACK];
-    jobject      *boa;
+    jbyteArray    bastack[ACR_IOVEC_ON_STACK];
+    jbyteArray   *boa;
     acr_file_t *f = (acr_file_t *)ACR_IOH_FDATA(file);
 
     if (ACR_IOH_FTYPE(file) != ACR_DT_FILE) {
@@ -903,11 +1017,11 @@
         ACR_ThrowException(_E, THROW_NMARK, ACR_EX_EINDEX, 0);
         return -1;
     }
-    if ((*_E)->EnsureLocalCapacity(_E, (jint)(pl * 2)))
+    if ((*_E)->EnsureLocalCapacity(_E, (jint)(cs * 2)))
         return -1;
-    if (pl > ACR_IOVEC_ON_STACK) {
-        iov = ACR_MALLOC(struct iovec, pl);
-        boa = ACR_MALLOC(jobject, pl);
+    if (cs > ACR_IOVEC_ON_STACK) {
+        iov = ACR_MALLOC(struct iovec, cs);
+        boa = ACR_MALLOC(jbyteArray, cs);
     }
     else {
         iov = onstack;
@@ -919,8 +1033,8 @@
         return -1;
     }
 
-    for (i = 0; i < pl; i++) {
-        boa[i] = (*_E)->GetObjectArrayElement(_E, vec, i);
+    for (i = 0; i < cs; i++) {
+        boa[i] = (*_E)->GetObjectArrayElement(_E, vec, (jsize)(i + po));
         iov[i].iov_len  = (size_t)(*_E)->GetArrayLength(_E, boa[i]);
         iov[i].iov_base = (*_E)->GetByteArrayElements(_E, boa[i], NULL);
     }
@@ -932,7 +1046,7 @@
         int rc;
         if ((rc = wait_for_io_or_timeout(f, 0))) {
             f->err = rc;
-            for (i = 0; i < pl; i++) {
+            for (i = 0; i < cs; i++) {
                 (*_E)->ReleaseByteArrayElements(_E, boa[i], iov[i].iov_base,
                                                 JNI_ABORT);
             }
@@ -955,7 +1069,7 @@
     }
     else if (wr == 1)
         f->err = 0;
-    for (i = 0; i < pl; i++) {
+    for (i = 0; i < cs; i++) {
         (*_E)->ReleaseByteArrayElements(_E, boa[i], iov[i].iov_base, JNI_ABORT);
     }
     if (iov != onstack) {
@@ -978,8 +1092,6 @@
     ssize_t wr;
     struct iovec *iov;
     struct iovec  onstack[ACR_IOVEC_ON_STACK];
-    jobject       bastack[ACR_IOVEC_ON_STACK];
-    jobject      *boa;
     acr_file_t *f = (acr_file_t *)ACR_IOH_FDATA(file);
 
     if (ACR_IOH_FTYPE(file) != ACR_DT_FILE) {
@@ -995,26 +1107,18 @@
         ACR_ThrowException(_E, THROW_NMARK, ACR_EX_EINDEX, 0);
         return -1;
     }
-    if ((*_E)->EnsureLocalCapacity(_E, (jint)(pl * 2)))
-        return -1;
-    if (pl > ACR_IOVEC_ON_STACK) {
-        iov = ACR_MALLOC(struct iovec, pl);
-        boa = ACR_MALLOC(jobject, pl);
-    }
-    else {
+    if (cs > ACR_IOVEC_ON_STACK)
+        iov = ACR_MALLOC(struct iovec, cs);
+    else
         iov = onstack;
-        boa = bastack;
-    }
-    if (!iov || !boa) {
-        x_free(iov);
-        x_free(boa);
+    if (!iov)
         return -1;
-    }
 
-    for (i = 0; i < pl; i++) {
-        boa[i] = (*_E)->GetObjectArrayElement(_E, vec, i);
-        iov[i].iov_len  = (size_t)(*_E)->GetDirectBufferCapacity(_E, boa[i]);
-        iov[i].iov_base = (*_E)->GetDirectBufferAddress(_E, boa[i]);
+    for (i = 0; i < cs; i++) {
+        jobject bb = (*_E)->GetObjectArrayElement(_E, vec, (jsize)(i + po));
+        iov[i].iov_len  = (size_t)(*_E)->GetDirectBufferCapacity(_E, bb);
+        iov[i].iov_base = (*_E)->GetDirectBufferAddress(_E, bb);
+        (*_E)->DeleteLocalRef(_E, bb);
     }
     do {
         wr = writev(f->fd, iov, pl);
@@ -1024,10 +1128,8 @@
         int rc;
         if ((rc = wait_for_io_or_timeout(f, 0))) {
             f->err = rc;
-            if (iov != onstack) {
+            if (iov != onstack)
                 x_free(iov);
-                x_free(boa);
-            }
             return rc == ACR_TIMEUP ? 0 : -1;
         }
         else {
@@ -1043,9 +1145,7 @@
     }
     else if (wr == 1)
         f->err = 0;
-    if (iov != onstack) {
+    if (iov != onstack)
         x_free(iov);
-        x_free(boa);
-    }
     return (jint)wr;
 }