src/windows/classes/sun/nio/ch/PipeImpl.java
Print this page
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2002, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
@@ -70,48 +70,83 @@
implements PrivilegedExceptionAction<Void>
{
private final SelectorProvider sp;
+ private IOException ioe = null;
+
private Initializer(SelectorProvider sp) {
this.sp = sp;
}
+ @Override
public Void run() throws IOException {
+ LoopbackConnector connector = new LoopbackConnector();
+ connector.run();
+ if (ioe instanceof ClosedByInterruptException) {
+ ioe = null;
+ Thread connThread = new Thread(connector) {
+ @Override
+ public void interrupt() {}
+ };
+ connThread.start();
+ for(;;) {
+ try {
+ connThread.join();
+ break;
+ } catch (InterruptedException ex) {}
+ }
+ Thread.currentThread().interrupt();
+ }
+
+ if (ioe != null || source == null || sink == null)
+ throw new IOException("Unable to establish loopback connection",
+ ioe);
+
+ return null;
+ }
+
+ private class LoopbackConnector implements Runnable {
+
+ @Override
+ public void run() {
ServerSocketChannel ssc = null;
SocketChannel sc1 = null;
SocketChannel sc2 = null;
try {
- // loopback address
+ // Loopback address
InetAddress lb = InetAddress.getByName("127.0.0.1");
assert(lb.isLoopbackAddress());
-
- // bind ServerSocketChannel to a port on the loopback address
+ InetSocketAddress sa = null;
+ for(;;) {
+ // Bind ServerSocketChannel to a port on the loopback
+ // address
+ if (ssc == null || !ssc.isOpen()) {
ssc = ServerSocketChannel.open();
ssc.socket().bind(new InetSocketAddress(lb, 0));
+ sa = new InetSocketAddress(lb,
+ ssc.socket().getLocalPort());
+ }
- // Establish connection (assumes connections are eagerly
+ // Establish connection (assume connections are eagerly
// accepted)
- InetSocketAddress sa
- = new InetSocketAddress(lb, ssc.socket().getLocalPort());
sc1 = SocketChannel.open(sa);
-
ByteBuffer bb = ByteBuffer.allocate(8);
long secret = rnd.nextLong();
bb.putLong(secret).flip();
sc1.write(bb);
// Get a connection and verify it is legitimate
- for (;;) {
sc2 = ssc.accept();
bb.clear();
sc2.read(bb);
bb.rewind();
if (bb.getLong() == secret)
break;
sc2.close();
+ sc1.close();
}
// Create source and sink channels
source = new SourceChannelImpl(sp, sc1);
sink = new SinkChannelImpl(sp, sc2);
@@ -119,22 +154,19 @@
try {
if (sc1 != null)
sc1.close();
if (sc2 != null)
sc2.close();
- } catch (IOException e2) { }
- IOException x = new IOException("Unable to establish"
- + " loopback connection");
- x.initCause(e);
- throw x;
+ } catch (IOException e2) {}
+ ioe = e;
} finally {
try {
if (ssc != null)
ssc.close();
- } catch (IOException e2) { }
+ } catch (IOException e2) {}
+ }
}
- return null;
}
}
PipeImpl(final SelectorProvider sp) throws IOException {
try {
@@ -142,11 +174,10 @@
} catch (PrivilegedActionException x) {
throw (IOException)x.getCause();
}
}
-
public SourceChannel source() {
return source;
}
public SinkChannel sink() {