commons-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mt...@apache.org
Subject svn commit: r883303 - in /commons/sandbox/runtime/trunk/src/main/native/os/win32: fsysio.c pipe.c
Date Mon, 23 Nov 2009 10:45:16 GMT
Author: mturk
Date: Mon Nov 23 10:45:15 2009
New Revision: 883303

URL: http://svn.apache.org/viewvc?rev=883303&view=rev
Log:
Implement windows Pipe

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

Modified: commons/sandbox/runtime/trunk/src/main/native/os/win32/fsysio.c
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/win32/fsysio.c?rev=883303&r1=883302&r2=883303&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/os/win32/fsysio.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/os/win32/fsysio.c Mon Nov 23 10:45:15 2009
@@ -43,6 +43,13 @@
             rc = ACR_SUCCESS;
         fp->fd = INVALID_HANDLE_VALUE;
     }
+    if (IS_VALID_HANDLE(fp->overlap.hEvent)) {
+        if (!CloseHandle(fp->overlap.hEvent))
+            rc = rc ? rc : ACR_GET_OS_ERROR();
+        else
+            rc = rc ? rc : ACR_SUCCESS;
+        fp->overlap.hEvent = NULL;
+    }
     if (fp->name) {
         x_free(fp->name);
         fp->name = NULL;

Modified: commons/sandbox/runtime/trunk/src/main/native/os/win32/pipe.c
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/win32/pipe.c?rev=883303&r1=883302&r2=883303&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/os/win32/pipe.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/os/win32/pipe.c Mon Nov 23 10:45:15 2009
@@ -22,6 +22,7 @@
 #include "acr_error.h"
 #include "acr_clazz.h"
 #include "acr_string.h"
+#include "acr_memory.h"
 #include "acr_descriptor.h"
 #include "acr_file.h"
 #include "acr_pipe.h"
@@ -199,6 +200,230 @@
     return rv;
 }
 
+static int create_pipepair(JNIEnv *_E, acr_file_t **rd, acr_file_t **wr,
+                           int flags)
+{
+    int rc = 0;
+    SECURITY_ATTRIBUTES sa;
+    HANDLE hr = NULL;
+    HANDLE hw = NULL;
+    wchar_t  buff[64];
+    wchar_t *name;
+    DWORD    dwOpenMode;
+    DWORD    dwPipeMode;
+
+    name = pipe_name_from_pid(buff,
+                              GetCurrentProcessId(),
+                              ACR_AtomicInc32(&pipe_id));
+
+    dwOpenMode = PIPE_ACCESS_INBOUND;
+    dwPipeMode = 0;
+    if (flags == ACR_PIPE_WRITE_BLOCK ||
+        flags == ACR_PIPE_FULL_NONBLOCK)
+        dwOpenMode |= FILE_FLAG_OVERLAPPED;
+
+    sa.nLength              = sizeof(SECURITY_ATTRIBUTES);
+    sa.bInheritHandle       = FALSE;
+    sa.lpSecurityDescriptor = NULL;
+
+    hr = CreateNamedPipeW(name,
+                          dwOpenMode,
+                          dwPipeMode,
+                          1,
+                          0,
+                          65536,
+                          1,
+                          &sa);
+    if (IS_INVALID_HANDLE(hr))
+        return ACR_GET_OS_ERROR();
+    dwOpenMode = FILE_ATTRIBUTE_NORMAL;
+    if (flags == ACR_PIPE_READ_BLOCK ||
+        flags == ACR_PIPE_FULL_NONBLOCK)
+        dwOpenMode |= FILE_FLAG_OVERLAPPED;
+    hw = CreateFileW(name,
+                     GENERIC_WRITE,
+                     0,
+                     &sa,
+                     OPEN_EXISTING,
+                     dwOpenMode,
+                     NULL);
+    if (IS_INVALID_HANDLE(hw)) {
+        rc = ACR_GET_OS_ERROR();
+        CloseHandle(hr);
+        return rc;
+    }
+    /* We have two handles created.
+     * Create wrapper objects and events
+     */
+    *rd = ACR_CALLOC(acr_file_t, 1);
+    if (!*rd) {
+        rc = ACR_ENOMEM;
+        goto finally;
+    }
+    (*rd)->fd     = hr;
+    (*rd)->name   = ACR_wcsdup(name);
+    (*rd)->flags  = flags;
+    (*rd)->type   = ACR_FT_PIPE;
+    if (flags == ACR_PIPE_WRITE_BLOCK ||
+        flags == ACR_PIPE_FULL_NONBLOCK) {
+        (*rd)->overlap.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
+        (*rd)->blocking = BLK_OFF;
+        (*rd)->timeout  = 0;
+    }
+    else {
+        (*rd)->blocking = BLK_ON;
+        (*rd)->timeout  = -1;
+    }
+
+    *wr = ACR_CALLOC(acr_file_t, 1);
+    if (!*wr) {
+        rc = ACR_ENOMEM;
+        goto finally;
+    }
+    (*wr)->fd     = hw;
+    (*wr)->name   = ACR_wcsdup(name);
+    (*wr)->flags  = flags;
+    (*wr)->type   = ACR_FT_PIPE;
+    if (flags == ACR_PIPE_WRITE_BLOCK ||
+        flags == ACR_PIPE_FULL_NONBLOCK) {
+        (*wr)->overlap.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
+        (*wr)->blocking = BLK_OFF;
+        (*wr)->timeout  = 0;
+    }
+    else {
+        (*wr)->blocking = BLK_ON;
+        (*wr)->timeout  = -1;
+    }
+
+    return 0;
+finally:
+    if (IS_VALID_HANDLE(hr))
+        CloseHandle(hr);
+    if (*rd) {
+        CloseHandle((*rd)->fd);
+        if ((*rd)->overlap.hEvent)
+            CloseHandle((*rd)->overlap.hEvent);
+        x_free((*rd)->name);
+        x_free(*rd);
+    }
+    return rc;
+}
+
+static int file_cleanup(void *file, int type, unsigned int flags)
+{
+    int rc = ACR_EBADF;
+    acr_file_t *fp = (acr_file_t *)file;
+
+    if (type != ACR_DT_FILE) {
+        return ACR_EBADF;
+    }
+    if (IS_VALID_HANDLE(fp->fd)) {
+        if (!CloseHandle(fp->fd))
+            rc = ACR_GET_OS_ERROR();
+        else
+            rc = ACR_SUCCESS;
+        fp->fd = INVALID_HANDLE_VALUE;
+    }
+    if (IS_VALID_HANDLE(fp->overlap.hEvent)) {
+        if (!CloseHandle(fp->overlap.hEvent))
+            rc = rc ? rc : ACR_GET_OS_ERROR();
+        else
+            rc = rc ? rc : ACR_SUCCESS;
+        fp->overlap.hEvent = NULL;
+    }
+    if (fp->name) {
+        x_free(fp->name);
+        fp->name = NULL;
+    }
+    if (flags & ACR_IOH_CLEAR)
+        x_free(fp);
+    return rc;
+}
+
+static int descriptor_cleanup(ACR_JNISTDARGS,
+                              acr_descriptor_cb_type_e cm,
+                              acr_descriptor_cb_t *dp)
+{
+    int rc = ACR_SUCCESS;
+    switch (cm) {
+        case ACR_DESC_FINALIZE:
+            if (dp->di > 0) {
+                acr_file_t *fp = ACR_IOH_FDATA(dp->di);
+                if (fp->descriptor) {
+                    (*_E)->DeleteWeakGlobalRef(_E, fp->descriptor);
+                    fp->descriptor = NULL;
+                }
+                rc = acr_ioh_clear(dp->di);
+            }
+            else
+                rc = ACR_EBADF;
+        break;
+        case ACR_DESC_CLOSE:
+            if (dp->di > 0) {
+                acr_file_t *fp = ACR_IOH_FDATA(dp->di);
+                if (fp->descriptor) {
+                    (*_E)->DeleteWeakGlobalRef(_E, fp->descriptor);
+                    fp->descriptor = NULL;
+                }
+                rc = acr_ioh_close(dp->di);
+            }
+            else
+                rc = ACR_EBADF;
+        break;
+        case ACR_DESC_FLUSH:
+        case ACR_DESC_SYNC:
+            if (dp->di > 0) {
+                acr_file_t *fp = ACR_IOH_FDATA(dp->di);
+                if (!FlushFileBuffers(fp->fd))
+                    rc = ACR_GET_OS_ERROR();
+            }
+            else
+                rc = ACR_EBADF;
+        break;
+        default:
+            rc = ACR_ENOTIMPL;
+        break;
+    }
+    return rc;
+}
+
+static int do_popen(JNIEnv *_E, acr_file_t *fp, int flags,
+                    jobject *fdo)
+{
+    int rc =  0;
+    int fo;
+    jobject od;
+
+    fo = acr_ioh_open(fp, ACR_DT_FILE, 0, file_cleanup);
+    if (fo < 0) {
+        rc = ACR_GET_OS_ERROR();
+        goto finally;
+    }
+    /* Create File Descriptor Object */
+    od = ACR_DescriptorCreate(_E, ACR_DT_FILE, fo, NULL,
+                              descriptor_cleanup);
+    if (!od) {
+        rc = ACR_GET_OS_ERROR();
+        goto finally;
+    }
+    /* Create Pipe object */
+    fp->descriptor = (*_E)->NewWeakGlobalRef(_E, *fdo);
+    *fdo = ACR_NewPipeObject(_E, flags, od, NULL);
+    if (!*fdo) {
+        rc = ACR_GET_OS_ERROR();
+        goto finally;
+    }
+finally:
+    if (rc) {
+        if (fp && fp->descriptor)
+            (*_E)->DeleteWeakGlobalRef(_E, fp->descriptor);
+        /* ### close the fp */
+        x_free(fp);
+    }
+
+    return rc;
+}
+
 ACR_CLASS_UDEF(io_Pipe)
 {
     ACR_UnloadClass(_E, &_clazzn);
@@ -221,3 +446,112 @@
     else
         return NULL;
 }
+
+ACR_IO_EXPORT_DECLARE(jobjectArray, Pipe, create0)(ACR_JNISTDARGS,
+                                                   jint flags)
+{
+    int rc = 0;
+    jobjectArray pa = NULL;
+    jobject      fd[2];
+    acr_file_t  *pd[2] = { NULL, NULL };
+
+    if ((rc = create_pipepair(_E, &pd[0], &pd[1], flags))) {
+        ACR_THROW_IO_IF_ERR(rc);
+        return NULL;
+    }
+    pa = ACR_NewPipeArray(_E, 2);
+    if (pa == NULL) {
+        file_cleanup(pd[0], ACR_DT_FILE, ACR_IOH_CLEAR);
+        file_cleanup(pd[1], ACR_DT_FILE, ACR_IOH_CLEAR);
+    }
+    rc = do_popen(_E, pd[0], flags & ACR_PIPE_RD,  &fd[0]);
+    if (rc) {
+        goto cleanup;
+    }
+    rc = do_popen(_E, pd[1], flags & ACR_PIPE_WR, &fd[1]);
+    if (rc) {
+        /* ### fd[0] will be closed by GC ?
+         */
+        pd[0] = NULL;
+        goto cleanup;
+    }
+    (*_E)->SetObjectArrayElement(_E, pa, 0, fd[0]);
+    (*_E)->SetObjectArrayElement(_E, pa, 1, fd[1]);
+    return pa;
+
+cleanup:
+    if (pd[0])
+        file_cleanup(pd[0], ACR_DT_FILE, ACR_IOH_CLEAR);
+    if (pd[1])
+        file_cleanup(pd[1], ACR_DT_FILE, ACR_IOH_CLEAR);
+
+    ACR_THROW_IO_IF_ERR(rc);
+    return NULL;
+}
+
+ACR_IO_EXPORT_DECLARE(jboolean, Pipe, blocking0)(ACR_JNISTDARGS,
+                                                 jint pipe)
+{
+    acr_file_t *f = (acr_file_t *)ACR_IOH_FDATA(pipe);
+
+    if (ACR_IOH_FTYPE(pipe) != ACR_DT_FILE) {
+        ACR_THROW_IO_IF_ERR(ACR_EFTYPE);
+        return JNI_FALSE;
+    }
+    if (IS_INVALID_HANDLE(f)) {
+        ACR_THROW_IO_IF_ERR(ACR_EBADF);
+        return JNI_FALSE;
+    }
+    return f->blocking == BLK_ON ? JNI_TRUE : JNI_FALSE;
+}
+
+ACR_IO_EXPORT_DECLARE(jint, Pipe, tmset0)(ACR_JNISTDARGS,
+                                          jint pipe, jint timeout)
+{
+    int rc;
+    acr_file_t *f = ACR_IOH_FDATA(pipe);
+
+    if (ACR_IOH_FTYPE(pipe) != ACR_DT_FILE)
+        return ACR_EFTYPE;
+    if (IS_INVALID_HANDLE(f))
+        return ACR_EBADF;
+    if (f->type != ACR_FT_PIPE)
+        return ACR_EFTYPE;
+    if (timeout >= 0) {
+        if (f->blocking == BLK_OFF) {
+            /* Pipe is in the nonblocking state
+             */
+            f->timeout  = timeout;
+        }
+        else {
+            /* Pipe blocking mode can be set only during
+             * the pipe creation
+             */
+            rc = ACR_EINVAL;
+        }
+    }
+    else {
+        /* Always OK to unset timeouts.
+         * This will produce infinite timeout
+         * basically making the pipe blocking.
+         */
+        f->timeout = INFINITE;
+    }
+    return 0;
+}
+
+ACR_IO_EXPORT_DECLARE(jint, Pipe, tmget0)(ACR_JNISTDARGS,
+                                          jint pipe)
+{
+    acr_file_t *f = (acr_file_t *)ACR_IOH_FDATA(pipe);
+
+    if (ACR_IOH_FTYPE(pipe) != ACR_DT_FILE) {
+        ACR_THROW_IO_IF_ERR(ACR_EFTYPE);
+        return 0;
+    }
+    if (IS_INVALID_HANDLE(f)) {
+        ACR_THROW_IO_IF_ERR(ACR_EBADF);
+        return 0;
+    }
+    return (jint)f->timeout;
+}



Mime
View raw message