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();