commons-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mt...@apache.org
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 GMT
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



Mime
View raw message