HADOOP-10198. DomainSocket: add support for socketpair. Contributed by Colin Patrick McCabe.

git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/branches/branch-2@1554891 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Andrew Wang 2014-01-02 20:07:21 +00:00
parent 48e255ff5d
commit 4cf8f575fc
4 changed files with 97 additions and 8 deletions

View File

@ -112,6 +112,9 @@ Release 2.4.0 - UNRELEASED
HADOOP-10169. Remove the unnecessary synchronized in JvmMetrics class. HADOOP-10169. Remove the unnecessary synchronized in JvmMetrics class.
(Liang Xie via jing9) (Liang Xie via jing9)
HADOOP-10198. DomainSocket: add support for socketpair.
(Colin Patrick McCabe via wang)
OPTIMIZATIONS OPTIMIZATIONS
HADOOP-9748. Reduce blocking on UGI.ensureInitialized (daryn) HADOOP-9748. Reduce blocking on UGI.ensureInitialized (daryn)

View File

@ -276,6 +276,24 @@ public class DomainSocket implements Closeable {
return new DomainSocket(path, fd); return new DomainSocket(path, fd);
} }
/**
* Create a pair of UNIX domain sockets which are connected to each other
* by calling socketpair(2).
*
* @return An array of two UNIX domain sockets connected to
* each other.
* @throws IOException on error.
*/
public static DomainSocket[] socketpair() throws IOException {
int fds[] = socketpair0();
return new DomainSocket[] {
new DomainSocket("(anonymous0)", fds[0]),
new DomainSocket("(anonymous1)", fds[1])
};
}
private static native int[] socketpair0() throws IOException;
private static native int accept0(int fd) throws IOException; private static native int accept0(int fd) throws IOException;
/** /**

View File

@ -364,6 +364,50 @@ JNIEnv *env, jclass clazz, jstring path)
return fd; return fd;
} }
#define SOCKETPAIR_ARRAY_LEN 2
JNIEXPORT jarray JNICALL
Java_org_apache_hadoop_net_unix_DomainSocket_socketpair0(
JNIEnv *env, jclass clazz)
{
jarray arr = NULL;
int idx, err, fds[SOCKETPAIR_ARRAY_LEN] = { -1, -1 };
jthrowable jthr = NULL;
arr = (*env)->NewIntArray(env, SOCKETPAIR_ARRAY_LEN);
jthr = (*env)->ExceptionOccurred(env);
if (jthr) {
(*env)->ExceptionClear(env);
goto done;
}
if (socketpair(PF_UNIX, SOCK_STREAM, 0, fds) < 0) {
err = errno;
jthr = newSocketException(env, err,
"socketpair(2) error: %s", terror(err));
goto done;
}
(*env)->SetIntArrayRegion(env, arr, 0, SOCKETPAIR_ARRAY_LEN, fds);
jthr = (*env)->ExceptionOccurred(env);
if (jthr) {
(*env)->ExceptionClear(env);
goto done;
}
done:
if (jthr) {
(*env)->DeleteLocalRef(env, arr);
arr = NULL;
for (idx = 0; idx < SOCKETPAIR_ARRAY_LEN; idx++) {
if (fds[idx] >= 0) {
close(fds[idx]);
fds[idx] = -1;
}
}
(*env)->Throw(env, jthr);
}
return arr;
}
JNIEXPORT jint JNICALL JNIEXPORT jint JNICALL
Java_org_apache_hadoop_net_unix_DomainSocket_accept0( Java_org_apache_hadoop_net_unix_DomainSocket_accept0(
JNIEnv *env, jclass clazz, jint fd) JNIEnv *env, jclass clazz, jint fd)

View File

@ -420,7 +420,8 @@ public class TestDomainSocket {
* @throws IOException * @throws IOException
*/ */
void testClientServer1(final Class<? extends WriteStrategy> writeStrategyClass, void testClientServer1(final Class<? extends WriteStrategy> writeStrategyClass,
final Class<? extends ReadStrategy> readStrategyClass) throws Exception { final Class<? extends ReadStrategy> readStrategyClass,
final DomainSocket preConnectedSockets[]) throws Exception {
final String TEST_PATH = new File(sockDir.getDir(), final String TEST_PATH = new File(sockDir.getDir(),
"test_sock_client_server1").getAbsolutePath(); "test_sock_client_server1").getAbsolutePath();
final byte clientMsg1[] = new byte[] { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6 }; final byte clientMsg1[] = new byte[] { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6 };
@ -428,13 +429,15 @@ public class TestDomainSocket {
final byte clientMsg2 = 0x45; final byte clientMsg2 = 0x45;
final ArrayBlockingQueue<Throwable> threadResults = final ArrayBlockingQueue<Throwable> threadResults =
new ArrayBlockingQueue<Throwable>(2); new ArrayBlockingQueue<Throwable>(2);
final DomainSocket serv = DomainSocket.bindAndListen(TEST_PATH); final DomainSocket serv = (preConnectedSockets != null) ?
null : DomainSocket.bindAndListen(TEST_PATH);
Thread serverThread = new Thread() { Thread serverThread = new Thread() {
public void run(){ public void run(){
// Run server // Run server
DomainSocket conn = null; DomainSocket conn = null;
try { try {
conn = serv.accept(); conn = preConnectedSockets != null ?
preConnectedSockets[0] : serv.accept();
byte in1[] = new byte[clientMsg1.length]; byte in1[] = new byte[clientMsg1.length];
ReadStrategy reader = readStrategyClass.newInstance(); ReadStrategy reader = readStrategyClass.newInstance();
reader.init(conn); reader.init(conn);
@ -459,7 +462,8 @@ public class TestDomainSocket {
Thread clientThread = new Thread() { Thread clientThread = new Thread() {
public void run(){ public void run(){
try { try {
DomainSocket client = DomainSocket.connect(TEST_PATH); DomainSocket client = preConnectedSockets != null ?
preConnectedSockets[1] : DomainSocket.connect(TEST_PATH);
WriteStrategy writer = writeStrategyClass.newInstance(); WriteStrategy writer = writeStrategyClass.newInstance();
writer.init(client); writer.init(client);
writer.write(clientMsg1); writer.write(clientMsg1);
@ -487,25 +491,45 @@ public class TestDomainSocket {
} }
serverThread.join(120000); serverThread.join(120000);
clientThread.join(120000); clientThread.join(120000);
if (serv != null) {
serv.close(); serv.close();
} }
}
@Test(timeout=180000) @Test(timeout=180000)
public void testClientServerOutStreamInStream() throws Exception { public void testClientServerOutStreamInStream() throws Exception {
testClientServer1(OutputStreamWriteStrategy.class, testClientServer1(OutputStreamWriteStrategy.class,
InputStreamReadStrategy.class); InputStreamReadStrategy.class, null);
}
@Test(timeout=180000)
public void testClientServerOutStreamInStreamWithSocketpair() throws Exception {
testClientServer1(OutputStreamWriteStrategy.class,
InputStreamReadStrategy.class, DomainSocket.socketpair());
} }
@Test(timeout=180000) @Test(timeout=180000)
public void testClientServerOutStreamInDbb() throws Exception { public void testClientServerOutStreamInDbb() throws Exception {
testClientServer1(OutputStreamWriteStrategy.class, testClientServer1(OutputStreamWriteStrategy.class,
DirectByteBufferReadStrategy.class); DirectByteBufferReadStrategy.class, null);
}
@Test(timeout=180000)
public void testClientServerOutStreamInDbbWithSocketpair() throws Exception {
testClientServer1(OutputStreamWriteStrategy.class,
DirectByteBufferReadStrategy.class, DomainSocket.socketpair());
} }
@Test(timeout=180000) @Test(timeout=180000)
public void testClientServerOutStreamInAbb() throws Exception { public void testClientServerOutStreamInAbb() throws Exception {
testClientServer1(OutputStreamWriteStrategy.class, testClientServer1(OutputStreamWriteStrategy.class,
ArrayBackedByteBufferReadStrategy.class); ArrayBackedByteBufferReadStrategy.class, null);
}
@Test(timeout=180000)
public void testClientServerOutStreamInAbbWithSocketpair() throws Exception {
testClientServer1(OutputStreamWriteStrategy.class,
ArrayBackedByteBufferReadStrategy.class, DomainSocket.socketpair());
} }
static private class PassedFile { static private class PassedFile {