--- old/src/windows/classes/sun/nio/ch/PipeImpl.java 2012-12-19 22:03:20.252405761 -0800 +++ new/src/windows/classes/sun/nio/ch/PipeImpl.java 2012-12-19 22:03:19.744405776 -0800 @@ -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,99 @@ 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 - for (;;) { - sc2 = ssc.accept(); - bb.clear(); - sc2.read(bb); - bb.rewind(); - if (bb.getLong() == secret) + 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; - sc2.close(); + } 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; - // 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) + // 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 +176,6 @@ } } - public SourceChannel source() { return source; }