Return-Path: Delivered-To: apmail-commons-commits-archive@minotaur.apache.org Received: (qmail 96116 invoked from network); 23 Nov 2009 10:45:41 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.3) by minotaur.apache.org with SMTP; 23 Nov 2009 10:45:41 -0000 Received: (qmail 33595 invoked by uid 500); 23 Nov 2009 10:45:40 -0000 Delivered-To: apmail-commons-commits-archive@commons.apache.org Received: (qmail 33507 invoked by uid 500); 23 Nov 2009 10:45:40 -0000 Mailing-List: contact commits-help@commons.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@commons.apache.org Delivered-To: mailing list commits@commons.apache.org Received: (qmail 33498 invoked by uid 99); 23 Nov 2009 10:45:40 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 23 Nov 2009 10:45:40 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 23 Nov 2009 10:45:37 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id 1C445238898B; Mon, 23 Nov 2009 10:45:16 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit 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 -0000 To: commits@commons.apache.org From: mturk@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20091123104516.1C445238898B@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org 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; +}