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;
+}