You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by mt...@apache.org on 2011/09/06 12:15:45 UTC

svn commit: r1165590 - in /commons/sandbox/runtime/trunk/src/main: native/os/win32/sendfd.c test/org/apache/commons/runtime/TestSendSocket.java

Author: mturk
Date: Tue Sep  6 10:15:45 2011
New Revision: 1165590

URL: http://svn.apache.org/viewvc?rev=1165590&view=rev
Log:
Implement windows send sockets

Modified:
    commons/sandbox/runtime/trunk/src/main/native/os/win32/sendfd.c
    commons/sandbox/runtime/trunk/src/main/test/org/apache/commons/runtime/TestSendSocket.java

Modified: commons/sandbox/runtime/trunk/src/main/native/os/win32/sendfd.c
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/win32/sendfd.c?rev=1165590&r1=1165589&r2=1165590&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/os/win32/sendfd.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/os/win32/sendfd.c Tue Sep  6 10:15:45 2011
@@ -33,3 +33,154 @@ ACR_NET_EXPORT(jstring, Utils, sendSocke
     return AcrNewJavaStringA(env, buf);
 }
 
+HANDLE send_pipe(LPCWSTR name, LPDWORD rpid)
+{
+    DWORD  rc = 0;
+    HANDLE ph;
+
+    ph = CreateNamedPipeW(name,
+                          PIPE_ACCESS_DUPLEX,
+                          PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
+                          PIPE_UNLIMITED_INSTANCES,
+                          ISIZEOF(WSAPROTOCOL_INFO),
+                          ISIZEOF(WSAPROTOCOL_INFO),
+                          0,
+                          0);
+    if (ph == INVALID_HANDLE_VALUE)
+        return 0;
+    if (!ConnectNamedPipe(ph, 0))
+        rc = GetLastError();
+    if (rc == 0 || rc == ERROR_PIPE_CONNECTED) {
+        DWORD nr;
+        WSAPROTOCOL_INFO id;
+        if (ReadFile(ph, &id, sizeof(WSAPROTOCOL_INFO), &nr, 0)) {
+            *rpid = id.dwProviderReserved;
+            return ph;
+        }
+    }
+    CloseHandle(ph);
+    return 0;
+}
+
+HANDLE recv_pipe(LPCWSTR name)
+{
+    DWORD  rc = 0;
+    HANDLE ph;
+    DWORD  wr;
+    WSAPROTOCOL_INFO id;
+    ph = CreateFileW(name,
+                     GENERIC_READ | GENERIC_WRITE,
+                     0,
+                     0,
+                     OPEN_EXISTING,
+                     0,
+                     0);
+    if (ph == INVALID_HANDLE_VALUE)
+        return 0;
+    if (!ConnectNamedPipe(ph, 0))
+        rc = GetLastError();
+    id.dwProviderReserved = GetCurrentProcessId();
+    if (WriteFile(ph, &id, sizeof(WSAPROTOCOL_INFO), &wr, 0))
+        return ph;
+    CloseHandle(ph);
+    return 0;
+}
+
+ACR_NET_EXPORT(jint, Utils, sendfd0)(JNI_STDARGS, jstring name,
+                                     jlongArray fda,
+                                     jint off, jint len)
+{
+    int    rc  = 0;
+    jlong *fds = 0;
+    int    i;
+
+    if (len > MAX_SEND_FDS)
+        return ACR_EOVERFLOW;
+    WITH_WSTR(name) {
+        HANDLE pipe;
+        DWORD  cpid;
+        WSAPROTOCOL_INFO pi;
+
+        pipe = send_pipe(J2S(name), &cpid);
+        if (pipe == 0) {
+            rc = ACR_GET_OS_ERROR();
+            goto cleanup;
+        }
+        fds = (*env)->GetLongArrayElements(env, fda, 0);
+        if (fds == 0) {
+            rc = ACR_EINVAL;
+            goto cleanup;
+        }
+        for (i = 0; i < len; i++) {
+            acr_sd_t *sp = J2P(fds[i + off], acr_sd_t *);
+            if (sp != 0) {
+                memset(&pi, 0, sizeof(WSAPROTOCOL_INFO));
+                rc = WSADuplicateSocket(sp->s, cpid, &pi);
+                if (rc == 0) {
+                    DWORD wr;
+                    WriteFile(pipe, &pi, sizeof(WSAPROTOCOL_INFO), &wr, 0);
+                }
+                else {
+                    /* Duplicate failed */
+                    break;
+                }
+            }
+        }
+        (*env)->ReleaseLongArrayElements(env, fda, fds, JNI_ABORT);
+cleanup:
+        SAFE_CLOSE_HANDLE(pipe);
+    } DONE_WITH_STR(name);
+    return rc;
+}
+
+ACR_NET_EXPORT(jlongArray, Utils, recvfd0)(JNI_STDARGS, jstring name)
+{
+    int rc  = 0;
+    jlongArray fds = 0;
+    jlong sda[MAX_SEND_FDS];
+
+    WITH_WSTR(name) {
+        HANDLE pipe;
+        if ((pipe = recv_pipe(J2S(name))) == 0) {
+            rc = ACR_GET_OS_ERROR();
+        }
+        else {
+            int nfd;
+
+            for (nfd = 0; nfd < MAX_SEND_FDS; nfd++) {
+                WSAPROTOCOL_INFO pi;
+                DWORD  rd;
+                SOCKET sd;
+                acr_sd_t *sp;
+
+                if (!ReadFile(pipe, &pi, sizeof(WSAPROTOCOL_INFO), &rd, 0))
+                    break;
+                sd = WSASocket(FROM_PROTOCOL_INFO, FROM_PROTOCOL_INFO, FROM_PROTOCOL_INFO, &pi, 0, 0);
+                if (sd == INVALID_SOCKET) {
+                    rc = WSAGetLastError();
+                    break;
+                }
+                sp = ACR_TALLOC(acr_sd_t);
+                if (sp == 0) {
+                    rc = ACR_ENOMEM;
+                    break;
+                }
+                sp->type    = ACR_DT_SOCKET;
+                sp->refs    = 1;
+                sp->s       = sd;
+                sp->timeout = -1;
+                sda[nfd]    = P2J(sp);
+            }
+            if (rc != 0 || nfd == 0)
+                goto cleanup;
+            fds = (*env)->NewLongArray(env, nfd);
+            if (fds != 0)
+                (*env)->SetLongArrayRegion(env, fds, 0, nfd, sda);
+cleanup:
+            CloseHandle(pipe);
+        }
+    } DONE_WITH_STR(name);
+    if (rc != 0)
+        ACR_THROW_NET_ERROR(rc);
+    return fds;
+}

Modified: commons/sandbox/runtime/trunk/src/main/test/org/apache/commons/runtime/TestSendSocket.java
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/test/org/apache/commons/runtime/TestSendSocket.java?rev=1165590&r1=1165589&r2=1165590&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/test/org/apache/commons/runtime/TestSendSocket.java (original)
+++ commons/sandbox/runtime/trunk/src/main/test/org/apache/commons/runtime/TestSendSocket.java Tue Sep  6 10:15:45 2011
@@ -24,10 +24,6 @@ import org.testng.Assert;
 public class TestSendSocket extends Assert
 {
 
-    // TODO: How can we get a process id from the testng
-    //       and use it here?
-    private static final String ipcname = "acrSendSockets23";
-
     @Test(groups = { "sendsd.parent" })
     public void sendSocket()
         throws Exception
@@ -37,7 +33,7 @@ public class TestSendSocket extends Asse
         ss.bind(sa);        
         long fds[] = new long[1];
         fds[0] = ss.descriptor().fd();
-        Utils.sendSockets(ipcname, fds, 0, 1);
+        Utils.sendSockets(Utils.sendSocketName(0), fds, 0, 1);
         System.out.println("[parent] Done.");
         System.out.flush();
     }
@@ -48,7 +44,7 @@ public class TestSendSocket extends Asse
     {
         System.out.println("[child]  Geting sockets");
         System.out.flush();
-        long[] fds = Utils.recvSockets(ipcname);
+        long[] fds = Utils.recvSockets(Utils.sendSocketName(0));
         assertEquals(fds.length, 1);
         System.out.println("[child]  Done.");
         System.out.flush();