--- a/jdk/src/windows/classes/sun/nio/ch/PipeImpl.java Tue Jan 08 14:54:56 2013 +0800
+++ b/jdk/src/windows/classes/sun/nio/ch/PipeImpl.java Tue Jan 08 20:37:27 2013 +0000
@@ -1,5 +1,5 @@
/*
- * 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
@@ -72,67 +72,97 @@
private final SelectorProvider sp;
+ private IOException ioe = null;
+
private Initializer(SelectorProvider sp) {
this.sp = sp;
}
+ @Override
public Void run() throws IOException {
- 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
- ssc = ServerSocketChannel.open();
- ssc.socket().bind(new InetSocketAddress(lb, 0));
-
- // Establish connection (assumes 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
+ LoopbackConnector connector = new LoopbackConnector();
+ connector.run();
+ if (ioe instanceof ClosedByInterruptException) {
+ ioe = null;
+ Thread connThread = new Thread(connector) {
+ @Override
+ public void interrupt() {}
+ };
+ connThread.start();
for (;;) {
- sc2 = ssc.accept();
- bb.clear();
- sc2.read(bb);
- bb.rewind();
- if (bb.getLong() == secret)
+ try {
+ connThread.join();
break;
- sc2.close();
+ } catch (InterruptedException ex) {}
}
+ Thread.currentThread().interrupt();
+ }
+
+ if (ioe != null)
+ throw new IOException("Unable to establish loopback connection", ioe);
- // Create source and sink channels
- source = new SourceChannelImpl(sp, sc1);
- sink = new SinkChannelImpl(sp, sc2);
- } catch (IOException e) {
+ return null;
+ }
+
+ private class LoopbackConnector implements Runnable {
+
+ @Override
+ public void run() {
+ ServerSocketChannel ssc = null;
+ SocketChannel sc1 = null;
+ SocketChannel sc2 = null;
+
try {
- if (sc1 != null)
- sc1.close();
- if (sc2 != null)
+ // 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());
+ }
+
+ // Establish connection (assume 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();
- } catch (IOException e2) { }
- IOException x = new IOException("Unable to establish"
- + " loopback connection");
- x.initCause(e);
- throw x;
- } finally {
- try {
- if (ssc != null)
- ssc.close();
- } catch (IOException e2) { }
+ 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) {}
+ }
}
- return null;
}
}
@@ -144,7 +174,6 @@
}
}
-
public SourceChannel source() {
return source;
}