Return-Path: X-Original-To: apmail-commons-commits-archive@minotaur.apache.org Delivered-To: apmail-commons-commits-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 7C9E97388 for ; Thu, 11 Aug 2011 05:43:49 +0000 (UTC) Received: (qmail 64446 invoked by uid 500); 11 Aug 2011 05:43:48 -0000 Delivered-To: apmail-commons-commits-archive@commons.apache.org Received: (qmail 64100 invoked by uid 500); 11 Aug 2011 05:43:38 -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 64093 invoked by uid 99); 11 Aug 2011 05:43:34 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 11 Aug 2011 05:43:34 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.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; Thu, 11 Aug 2011 05:43:32 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id 0B72623889E7 for ; Thu, 11 Aug 2011 05:43:13 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1156493 - in /commons/sandbox/runtime/trunk/src/main/native: include/acr/descriptor.h os/win32/arch_opts.h os/win32/exec.c os/win32/inetsock.c os/win32/init.c os/win32/sendfile.c os/win32/sockstream.c os/win32/util.c Date: Thu, 11 Aug 2011 05:43:12 -0000 To: commits@commons.apache.org From: mturk@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20110811054313.0B72623889E7@eris.apache.org> Author: mturk Date: Thu Aug 11 05:43:12 2011 New Revision: 1156493 URL: http://svn.apache.org/viewvc?rev=1156493&view=rev Log: Implement basic win32 sendfile Modified: commons/sandbox/runtime/trunk/src/main/native/include/acr/descriptor.h commons/sandbox/runtime/trunk/src/main/native/os/win32/arch_opts.h commons/sandbox/runtime/trunk/src/main/native/os/win32/exec.c commons/sandbox/runtime/trunk/src/main/native/os/win32/inetsock.c commons/sandbox/runtime/trunk/src/main/native/os/win32/init.c commons/sandbox/runtime/trunk/src/main/native/os/win32/sendfile.c commons/sandbox/runtime/trunk/src/main/native/os/win32/sockstream.c commons/sandbox/runtime/trunk/src/main/native/os/win32/util.c Modified: commons/sandbox/runtime/trunk/src/main/native/include/acr/descriptor.h URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/include/acr/descriptor.h?rev=1156493&r1=1156492&r2=1156493&view=diff ============================================================================== --- commons/sandbox/runtime/trunk/src/main/native/include/acr/descriptor.h (original) +++ commons/sandbox/runtime/trunk/src/main/native/include/acr/descriptor.h Thu Aug 11 05:43:12 2011 @@ -92,13 +92,13 @@ struct acr_sf_t { #else HANDLE fh; #endif - off_t off; + acr_off_t off; #if !defined(WINDOWS) struct_stat_t info; #else LPOVERLAPPED pob; /**< For TransmitFile */ #endif - size_t count; + acr_off_t size; }; @@ -111,6 +111,13 @@ AcrGetDescriptorFd(JNI_STDARGS); int AcrSetDescriptorFd(JNI_STDARGS, void *fd); +#if defined (WINDOWS) +HANDLE +AcrGetFileDescriptorHandle(JNI_STDARGS); +int +AcrSetFileDescriptorHandle(JNI_STDARGS, HANDLE fh); +#endif + #ifdef __cplusplus } #endif Modified: commons/sandbox/runtime/trunk/src/main/native/os/win32/arch_opts.h URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/win32/arch_opts.h?rev=1156493&r1=1156492&r2=1156493&view=diff ============================================================================== --- commons/sandbox/runtime/trunk/src/main/native/os/win32/arch_opts.h (original) +++ commons/sandbox/runtime/trunk/src/main/native/os/win32/arch_opts.h Thu Aug 11 05:43:12 2011 @@ -266,6 +266,22 @@ ACR_INLINE(void) MsecTimeToFileTime(LPFI return; } +ACR_INLINE(acr_int64_t) AcrToInt64(DWORD hi, DWORD lo) +{ + LARGE_INTEGER i; + i.HighPart = hi; + i.LowPart = lo; + return i.QuadPart; +} + +typedef struct winsock_env_t { + LPFN_ACCEPTEX AcceptEx; + LPFN_GETACCEPTEXSOCKADDRS GetAcceptExSockaddrs; + LPFN_TRANSMITFILE TransmitFile; +} winsock_env_t; + +extern winsock_env_t *winsock; + HANDLE AcrNullPipe(int flags, int fd); int AcrPipePair(HANDLE *rd, HANDLE *wr, int flags, char *name); int AcrSocketPair(SOCKET *rd, SOCKET *wr, int nonblocking); Modified: commons/sandbox/runtime/trunk/src/main/native/os/win32/exec.c URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/win32/exec.c?rev=1156493&r1=1156492&r2=1156493&view=diff ============================================================================== --- commons/sandbox/runtime/trunk/src/main/native/os/win32/exec.c (original) +++ commons/sandbox/runtime/trunk/src/main/native/os/win32/exec.c Thu Aug 11 05:43:12 2011 @@ -566,7 +566,7 @@ ACR_WIN_EXPORT(jlong, WindowsExec, exec0 rv = _run_exec(J2S(executable), J2S(args), J2S(envb), J2S(cwd), ob, eb, ib, timeout, &rc); if (inpcopy != 0) { - (*env)->ReleasePrimitiveArrayCritical(env, inpcopy, ib->buf, 0); + (*env)->ReleasePrimitiveArrayCritical(env, inpcopy, ib->buf, 0); (*env)->DeleteLocalRef(env, inpcopy); } if (rv != ACR_PARENT_ERROR) { @@ -604,5 +604,5 @@ cleanup: } DONE_WITH_STR(args); } DONE_WITH_STR(executable); - return ((jlong)rv << 32) | ((jlong)rc & ACR_I64_C(0xFFFFFFFF)); + return AcrToInt64(rv, rc); } Modified: commons/sandbox/runtime/trunk/src/main/native/os/win32/inetsock.c URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/win32/inetsock.c?rev=1156493&r1=1156492&r2=1156493&view=diff ============================================================================== --- commons/sandbox/runtime/trunk/src/main/native/os/win32/inetsock.c (original) +++ commons/sandbox/runtime/trunk/src/main/native/os/win32/inetsock.c Thu Aug 11 05:43:12 2011 @@ -38,12 +38,14 @@ ACR_NET_EXPORT(jint, SocketDescriptor, c if (fd == 0) return ACR_EBADF; sd = fd->s; +#if 0 if (fd->pob != 0) { /* Close TransmitFile overlapped struct */ SAFE_CLOSE_HANDLE(fd->pob->hEvent); AcrFree(fd->pob); fd->pob = 0; } +#endif if (sd != INVALID_SOCKET) { fd->s = INVALID_SOCKET; if (fd->socketfname != 0) { Modified: commons/sandbox/runtime/trunk/src/main/native/os/win32/init.c URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/win32/init.c?rev=1156493&r1=1156492&r2=1156493&view=diff ============================================================================== --- commons/sandbox/runtime/trunk/src/main/native/os/win32/init.c (original) +++ commons/sandbox/runtime/trunk/src/main/native/os/win32/init.c Thu Aug 11 05:43:12 2011 @@ -32,7 +32,6 @@ HANDLE _heap_handle = 0 LPSYSTEM_INFO acr_osinf = &osinf; LPOSVERSIONINFOEXA acr_osver = &osver; HANDLE acr_raised_event = 0; -HANDLE acr_alived_mutex = 0; extern int AcrIpcInit(void); typedef struct tlsd_t @@ -139,6 +138,28 @@ AcrGetThreadError() return ACR_ENOMEM; } +int +AcrInitialize() +{ + int rc; + WORD wVersionRequested; + WSADATA wsaData; + + /* Winsock should be already initialized + * by the JVM + */ + wVersionRequested = MAKEWORD(2, 2); + if ((rc = WSAStartup(wVersionRequested, &wsaData)) != 0) + return rc; + GetSystemInfo(acr_osinf); + acr_osver->dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXA); + GetVersionExA((LPOSVERSIONINFOA)acr_osver); + acr_raised_event = CreateEvent(0, TRUE, FALSE, 0); + if (IS_INVALID_HANDLE(acr_raised_event)) + return GetLastError(); + return rc; +} + /* Called by the JVM when ACR is loaded */ ACR_API(jint) JNI_OnLoad(JavaVM *vm, void *reserved) @@ -154,13 +175,7 @@ JNI_OnLoad(JavaVM *vm, void *reserved) */ return JNI_ERR; } - GetSystemInfo(acr_osinf); - acr_osver->dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXA); - GetVersionExA((LPOSVERSIONINFOA)acr_osver); - acr_raised_event = CreateEvent(0, TRUE, FALSE, 0); - acr_alived_mutex = CreateMutex(GetSaWithNullDacl(0, JNI_FALSE), TRUE, 0); - - if (IS_INVALID_HANDLE(acr_raised_event)) + if (AcrInitialize() != 0) return JNI_ERR; if (AcrLoadLateDLLs() != 0) return JNI_ERR; Modified: commons/sandbox/runtime/trunk/src/main/native/os/win32/sendfile.c URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/win32/sendfile.c?rev=1156493&r1=1156492&r2=1156493&view=diff ============================================================================== --- commons/sandbox/runtime/trunk/src/main/native/os/win32/sendfile.c (original) +++ commons/sandbox/runtime/trunk/src/main/native/os/win32/sendfile.c Thu Aug 11 05:43:12 2011 @@ -22,7 +22,199 @@ #include "acr/iodefs.h" #include "acr/netapi.h" #include "acr/ring.h" +#include "acr/string.h" #include "acr/misc.h" #include "arch_opts.h" #include "arch_sync.h" +ACR_NET_EXPORT(jlong, SendFile, open0)(JNI_STDARGS, jstring fname) +{ + int rc = 0; + acr_sf_t *sf; + if ((sf = ACR_TALLOC(acr_sf_t)) == 0) + return 0; + WITH_WSTR(fname) { + sf->fh = CreateFileW(J2S(fname), + GENERIC_READ, + FILE_SHARE_READ, + 0, + OPEN_EXISTING, + FILE_FLAG_SEQUENTIAL_SCAN, + 0); + if (sf->fh == INVALID_HANDLE_VALUE) { + rc = GetLastError(); + } + else { + BY_HANDLE_FILE_INFORMATION fi; + if (GetFileInformationByHandle(sf->fh, &fi)) + sf->size = AcrToInt64(fi.nFileSizeHigh, fi.nFileSizeLow); + else + rc = GetLastError(); + } + } DONE_WITH_STR(fname); + if (rc != 0) { + SAFE_CLOSE_HANDLE(sf->fh); + AcrFree(sf); + ACR_THROW_NET_ERROR(rc); + return 0; + } + sf->pob = ACR_TALLOC(OVERLAPPED); + if (sf->pob != 0) { + sf->pob->hEvent = CreateEvent(0, FALSE, FALSE, 0); + return P2J(sf); + } + else { + CloseHandle(sf->fh); + AcrFree(sf); + return 0; + } +} + +ACR_NET_EXPORT(jlong, SendFile, open1)(JNI_STDARGS, jobject fd) +{ + int rc = 0; + HANDLE nd; + acr_sf_t *sf; + + if (fd == 0) { + ACR_THROW_NET_ERROR(ACR_EBADF); + return 0; + } + nd = AcrGetFileDescriptorHandle(env, fd); + if (IS_INVALID_HANDLE(nd)) { + ACR_THROW_NET_ERROR(ACR_EIO); + return 0; + } + if ((sf = ACR_TALLOC(acr_sf_t)) == 0) + return 0; + /* Duplicate FileDescriptor so + * we don't have to reference it + */ + if (!DuplicateHandle(GetCurrentProcess(), nd, + GetCurrentProcess(), &sf->fh, + 0, FALSE, DUPLICATE_SAME_ACCESS)) { + rc = GetLastError(); + } + else { + BY_HANDLE_FILE_INFORMATION fi; + if (GetFileInformationByHandle(sf->fh, &fi)) + sf->size = AcrToInt64(fi.nFileSizeHigh, fi.nFileSizeLow); + else + rc = GetLastError(); + } + if (rc != 0) { + SAFE_CLOSE_HANDLE(sf->fh); + AcrFree(sf); + ACR_THROW_NET_ERROR(rc); + return 0; + } + sf->pob = ACR_TALLOC(OVERLAPPED); + if (sf->pob != 0) { + sf->pob->hEvent = CreateEvent(0, FALSE, FALSE, 0); + return P2J(sf); + } + else { + CloseHandle(sf->fh); + AcrFree(sf); + return 0; + } +} + +ACR_NET_EXPORT(jint, SendFile, close0)(JNI_STDARGS, jlong fp) +{ + int rc = 0; + acr_sf_t *sf = J2P(fp, acr_sf_t *); + + CloseHandle(sf->fh); + CloseHandle(sf->pob->hEvent); + AcrFree(sf->pob); + AcrFree(sf); + return rc; +} + +ACR_NET_EXPORT(jlong, Sendfile, size0)(JNI_STDARGS, jlong fp) +{ + acr_sf_t *sf = J2P(fp, acr_sf_t *); + return (jlong)sf->size; +} + +ACR_NET_EXPORT(jlong, Sendfile, size1)(JNI_STDARGS, jlong fp) +{ + acr_sf_t *sf = J2P(fp, acr_sf_t *); + return (jlong)sf->off; +} + +#define MAX_SEGMENT_SIZE 65536 +ACR_NET_EXPORT(jint, Sendfile, send0)(JNI_STDARGS, jlong sp, jlong fp) +{ + int rc = 0; + DWORD cnt = 0; + acr_sd_t *sd = J2P(sp, acr_sd_t *); + acr_sf_t *sf = J2P(fp, acr_sf_t *); + DWORD dwFlags = 0; + SOCKET sock; + acr_off_t tosend; + int xmitted = 0; + + if ((sock = AcrSdRetain(sd)) == INVALID_SOCKET) { + ACR_THROW_NET_ERROR(ACR_EBADF); + return -1; + } + if ((sf->size - sf->off) > INT_MAX) + tosend = INT_MAX; + else + tosend = sf->size - sf->off; + + if (ACR_HASFLAG(sd, ACR_SO_WPART)) { + ACR_CLRFLAG(sd, ACR_SO_WPART); + /* Wait for the previous operation to finish */ + rc = AcrWaitIO(sock, sd->timeout, POLLOUT); + } + sf->pob->Offset = (DWORD)(sf->off); + sf->pob->OffsetHigh = (DWORD)(sf->off >> 32); + while (tosend > 0) { + if (tosend > MAX_SEGMENT_SIZE) + cnt = MAX_SEGMENT_SIZE; + else + cnt = (DWORD)tosend; /* Last call to TransmitFile() */ + /* XXX: MSDN says that it should be obtained by WSAIoctl + * but it seems this works just fine as it is. + */ + if (!(*winsock->TransmitFile)(sock, /* socket */ + sf->fh, /* file descriptor of the file to be sent */ + cnt, /* number of bytes to send. 0=send all */ + 0, /* Number of bytes per send. 0=use default */ + sf->pob, /* OVERLAPPED structure */ + 0, /* header and trailer buffers */ + dwFlags)) { /* flags to control various aspects of TransmitFile */ + rc = WSAGetLastError(); + if (rc == ERROR_IO_PENDING || rc == WSA_IO_PENDING) { + DWORD ws = WaitForSingleObject(sf->pob->hEvent, sd->timeout); + if (ws == WAIT_OBJECT_0) { + rc = 0; + if (!WSAGetOverlappedResult(sock, + sf->pob->hEvent, + &cnt, + FALSE, + &dwFlags)) + rc = WSAGetLastError(); + } + else if (ws == WAIT_TIMEOUT) + rc = ACR_TIMEUP; + else + rc = GetLastError(); + } + } + if (rc != 0) + break; + tosend -= cnt; + sf->off += cnt; + xmitted += cnt; + } + if (rc != 0) { + xmitted = -1; + ACR_THROW_NET_ERROR(rc); + } + AcrSdRelease(sd); + return xmitted; +} Modified: commons/sandbox/runtime/trunk/src/main/native/os/win32/sockstream.c URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/win32/sockstream.c?rev=1156493&r1=1156492&r2=1156493&view=diff ============================================================================== --- commons/sandbox/runtime/trunk/src/main/native/os/win32/sockstream.c (original) +++ commons/sandbox/runtime/trunk/src/main/native/os/win32/sockstream.c Thu Aug 11 05:43:12 2011 @@ -550,6 +550,7 @@ ACR_NET_EXPORT(jlong, SocketStream, writ { int i; DWORD wr = 0; + DWORD sz = 0; int rc = 0; SOCKET sd; jbyteArray *boa = 0; @@ -594,6 +595,7 @@ ACR_NET_EXPORT(jlong, SocketStream, writ } iov[i].len = (u_long)(*env)->GetArrayLength(env, boa[i]); iov[i].buf = (char *)(*env)->GetByteArrayElements(env, boa[i], 0); + sz += iov[i].len; } if (ACR_HASFLAG(ss->fd, ACR_SO_WPART)) { ACR_CLRFLAG(ss->fd, ACR_SO_WPART); @@ -609,7 +611,7 @@ waitio: if (WSASend(sd, iov, len, &wr, 0, 0, 0) == SOCKET_ERROR) rc = WSAGetLastError(); } - if (rc == 0 && ss->fd->timeout > 0 && wr < len) + if (rc == 0 && ss->fd->timeout > 0 && wr < sz) ss->fd->flags |= ACR_SO_WPART; finally: sdrelease(ss); @@ -639,6 +641,7 @@ ACR_NET_EXPORT(jlong, SocketStream, writ { int i; DWORD wr = 0; + DWORD sz = 0; int rc = 0; SOCKET sd; LPWSABUF iov = 0; @@ -671,7 +674,7 @@ ACR_NET_EXPORT(jlong, SocketStream, writ } iov[i].len = (u_long)(*env)->GetDirectBufferCapacity(env, bb); iov[i].buf = (char *)(*env)->GetDirectBufferAddress(env, bb); - + sz += iov[i].len; (*env)->DeleteLocalRef(env, bb); } if (ACR_HASFLAG(ss->fd, ACR_SO_WPART)) { @@ -688,7 +691,7 @@ waitio: if (WSASend(sd, iov, len, &wr, 0, 0, 0) == SOCKET_ERROR) rc = WSAGetLastError(); } - if (rc == 0 && ss->fd->timeout > 0 && wr < len) + if (rc == 0 && ss->fd->timeout > 0 && wr < sz) ss->fd->flags |= ACR_SO_WPART; finally: sdrelease(ss); Modified: commons/sandbox/runtime/trunk/src/main/native/os/win32/util.c URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/win32/util.c?rev=1156493&r1=1156492&r2=1156493&view=diff ============================================================================== --- commons/sandbox/runtime/trunk/src/main/native/os/win32/util.c (original) +++ commons/sandbox/runtime/trunk/src/main/native/os/win32/util.c Thu Aug 11 05:43:12 2011 @@ -50,6 +50,9 @@ static HMODULE _opt_libinst[SYSDLL_DEFIN 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; +static winsock_env_t winsock_s = { AcceptEx, GetAcceptExSockaddrs, TransmitFile }; +winsock_env_t *winsock = &winsock_s; + HMODULE AcrGetLateDLL(SYSDLL_TOKEN libidx) { @@ -114,6 +117,12 @@ int AcrLoadLateDLLs() { SYSDLL_TOKEN idx = SYSDLL_KERNEL32; + GUID id0 = WSAID_ACCEPTEX; + GUID id1 = WSAID_GETACCEPTEXSOCKADDRS; + GUID id2 = WSAID_TRANSMITFILE; + SOCKET sd; + int rc = 0; + DWORD bytes; for (idx = SYSDLL_KERNEL32; idx < SYSDLL_DEFINED; idx++) { if (AcrGetLateDLL(idx) == 0 && (idx < SYSDLL_JVM)) { @@ -124,7 +133,32 @@ AcrLoadLateDLLs() return GetLastError(); } } + /* Load winsock pointers */ + sd = socket(AF_INET, SOCK_STREAM, 0); + if (sd == INVALID_SOCKET) + return WSAGetLastError(); + if (WSAIoctl(sd, SIO_GET_EXTENSION_FUNCTION_POINTER, + &id0, sizeof(id0), + &winsock_s.AcceptEx, sizeof(&winsock_s.AcceptEx), + &bytes, 0, 0) == SOCKET_ERROR) + goto failed; + if (WSAIoctl(sd, SIO_GET_EXTENSION_FUNCTION_POINTER, + &id1, sizeof(id1), + &winsock_s.GetAcceptExSockaddrs, sizeof(&winsock_s.GetAcceptExSockaddrs), + &bytes, 0, 0) == SOCKET_ERROR) + goto failed; + if (WSAIoctl(sd, SIO_GET_EXTENSION_FUNCTION_POINTER, + &id2, sizeof(id2), + &winsock_s.TransmitFile, sizeof(&winsock_s.TransmitFile), + &bytes, 0, 0) == SOCKET_ERROR) + goto failed; + closesocket(sd); return 0; + +failed: + rc = WSAGetLastError(); + closesocket(sd); + return rc; } /* Similar to posix dup3 but it only actually works for