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() {