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,56 @@
implements PrivilegedExceptionAction<Void>
{
private final SelectorProvider sp;
+ private IOException ioe = null;
+
private Initializer(SelectorProvider sp) {
this.sp = sp;
}
+ @Override
public Void run() throws IOException {
+ boolean interrupted = false;
+
ServerSocketChannel ssc = null;
SocketChannel sc1 = null;
SocketChannel sc2 = null;
try {
// 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,23 +127,112 @@
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) {}
+
+ if (!(e instanceof ClosedByInterruptException))
+ throw new IOException("Unable to establish loopback"
+ + " connection", e);
+ interrupted = true;
+ Thread.interrupted();
} finally {
try {
if (ssc != null)
ssc.close();
- } catch (IOException e2) { }
+ } catch (IOException e2) {}
}
+
+ if (interrupted)
+ UninterruptibleConnect();
+
return null;
}
+
+ // Use short-lived uninterruptible thread to establish
+ // loopback connections
+ private void UninterruptibleConnect() throws IOException {
+ Thread connector = new Thread("UninterruptibleConnector") {
+ ServerSocketChannel ssc = null;
+ SocketChannel sc1 = null;
+ SocketChannel sc2 = null;
+
+ @Override
+ public void run() {
+ try {
+ // loopback address
+ InetAddress lb = InetAddress.getByName("127.0.0.1");
+ assert(lb.isLoopbackAddress());
+ 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());
+ }
+ assert(sa != null);
+
+ // Establish connection (assumes connections are
+ // eagerly accepted)
+ 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
+ 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);
+ } catch (IOException e) {
+ try {
+ if (sc1 != null)
+ sc1.close();
+ if (sc2 != null)
+ sc2.close();
+ } catch (IOException e2) {}
+ ioe = e;
+ } finally {
+ try {
+ if (ssc != null)
+ ssc.close();
+ } catch (IOException e2) {}
+ }
+ }
+
+ @Override
+ public void interrupt() {}
+ };
+ connector.start();
+ for(;;) {
+ try {
+ connector.join();
+ break;
+ } catch (InterruptedException ex) {}
+ }
+
+ Thread.currentThread().interrupt();
+
+ if (ioe != null || source == null || sink == null)
+ throw new IOException("Unable to establish loopback connection",
+ ioe);
+ }
}
PipeImpl(final SelectorProvider sp) throws IOException {
try {
AccessController.doPrivileged(new Initializer(sp));