jdk/src/windows/classes/sun/nio/ch/PipeImpl.java
changeset 15007 31d8a6072b16
parent 5506 202f599c92aa
child 19607 bee007586d06
equal deleted inserted replaced
15006:10d6aacdd67f 15007:31d8a6072b16
     1 /*
     1 /*
     2  * Copyright (c) 2002, 2008, Oracle and/or its affiliates. All rights reserved.
     2  * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.  Oracle designates this
     7  * published by the Free Software Foundation.  Oracle designates this
    70         implements PrivilegedExceptionAction<Void>
    70         implements PrivilegedExceptionAction<Void>
    71     {
    71     {
    72 
    72 
    73         private final SelectorProvider sp;
    73         private final SelectorProvider sp;
    74 
    74 
       
    75         private IOException ioe = null;
       
    76 
    75         private Initializer(SelectorProvider sp) {
    77         private Initializer(SelectorProvider sp) {
    76             this.sp = sp;
    78             this.sp = sp;
    77         }
    79         }
    78 
    80 
       
    81         @Override
    79         public Void run() throws IOException {
    82         public Void run() throws IOException {
    80             ServerSocketChannel ssc = null;
    83             LoopbackConnector connector = new LoopbackConnector();
    81             SocketChannel sc1 = null;
    84             connector.run();
    82             SocketChannel sc2 = null;
    85             if (ioe instanceof ClosedByInterruptException) {
       
    86                 ioe = null;
       
    87                 Thread connThread = new Thread(connector) {
       
    88                     @Override
       
    89                     public void interrupt() {}
       
    90                 };
       
    91                 connThread.start();
       
    92                 for (;;) {
       
    93                     try {
       
    94                         connThread.join();
       
    95                         break;
       
    96                     } catch (InterruptedException ex) {}
       
    97                 }
       
    98                 Thread.currentThread().interrupt();
       
    99             }
    83 
   100 
    84             try {
   101             if (ioe != null)
    85                 // loopback address
   102                 throw new IOException("Unable to establish loopback connection", ioe);
    86                 InetAddress lb = InetAddress.getByName("127.0.0.1");
       
    87                 assert(lb.isLoopbackAddress());
       
    88 
   103 
    89                 // bind ServerSocketChannel to a port on the loopback address
   104             return null;
    90                 ssc = ServerSocketChannel.open();
   105         }
    91                 ssc.socket().bind(new InetSocketAddress(lb, 0));
       
    92 
   106 
    93                 // Establish connection (assumes connections are eagerly
   107         private class LoopbackConnector implements Runnable {
    94                 // accepted)
       
    95                 InetSocketAddress sa
       
    96                     = new InetSocketAddress(lb, ssc.socket().getLocalPort());
       
    97                 sc1 = SocketChannel.open(sa);
       
    98 
   108 
    99                 ByteBuffer bb = ByteBuffer.allocate(8);
   109             @Override
   100                 long secret = rnd.nextLong();
   110             public void run() {
   101                 bb.putLong(secret).flip();
   111                 ServerSocketChannel ssc = null;
   102                 sc1.write(bb);
   112                 SocketChannel sc1 = null;
       
   113                 SocketChannel sc2 = null;
   103 
   114 
   104                 // Get a connection and verify it is legitimate
   115                 try {
   105                 for (;;) {
   116                     // Loopback address
   106                     sc2 = ssc.accept();
   117                     InetAddress lb = InetAddress.getByName("127.0.0.1");
   107                     bb.clear();
   118                     assert(lb.isLoopbackAddress());
   108                     sc2.read(bb);
   119                     InetSocketAddress sa = null;
   109                     bb.rewind();
   120                     for(;;) {
   110                     if (bb.getLong() == secret)
   121                         // Bind ServerSocketChannel to a port on the loopback
   111                         break;
   122                         // address
   112                     sc2.close();
   123                         if (ssc == null || !ssc.isOpen()) {
       
   124                             ssc = ServerSocketChannel.open();
       
   125                             ssc.socket().bind(new InetSocketAddress(lb, 0));
       
   126                             sa = new InetSocketAddress(lb, ssc.socket().getLocalPort());
       
   127                         }
       
   128 
       
   129                         // Establish connection (assume connections are eagerly
       
   130                         // accepted)
       
   131                         sc1 = SocketChannel.open(sa);
       
   132                         ByteBuffer bb = ByteBuffer.allocate(8);
       
   133                         long secret = rnd.nextLong();
       
   134                         bb.putLong(secret).flip();
       
   135                         sc1.write(bb);
       
   136 
       
   137                         // Get a connection and verify it is legitimate
       
   138                         sc2 = ssc.accept();
       
   139                         bb.clear();
       
   140                         sc2.read(bb);
       
   141                         bb.rewind();
       
   142                         if (bb.getLong() == secret)
       
   143                             break;
       
   144                         sc2.close();
       
   145                         sc1.close();
       
   146                     }
       
   147 
       
   148                     // Create source and sink channels
       
   149                     source = new SourceChannelImpl(sp, sc1);
       
   150                     sink = new SinkChannelImpl(sp, sc2);
       
   151                 } catch (IOException e) {
       
   152                     try {
       
   153                         if (sc1 != null)
       
   154                             sc1.close();
       
   155                         if (sc2 != null)
       
   156                             sc2.close();
       
   157                     } catch (IOException e2) {}
       
   158                     ioe = e;
       
   159                 } finally {
       
   160                     try {
       
   161                         if (ssc != null)
       
   162                             ssc.close();
       
   163                     } catch (IOException e2) {}
   113                 }
   164                 }
   114 
       
   115                 // Create source and sink channels
       
   116                 source = new SourceChannelImpl(sp, sc1);
       
   117                 sink = new SinkChannelImpl(sp, sc2);
       
   118             } catch (IOException e) {
       
   119                 try {
       
   120                     if (sc1 != null)
       
   121                         sc1.close();
       
   122                     if (sc2 != null)
       
   123                         sc2.close();
       
   124                 } catch (IOException e2) { }
       
   125                 IOException x = new IOException("Unable to establish"
       
   126                                                 + " loopback connection");
       
   127                 x.initCause(e);
       
   128                 throw x;
       
   129             } finally {
       
   130                 try {
       
   131                     if (ssc != null)
       
   132                         ssc.close();
       
   133                 } catch (IOException e2) { }
       
   134             }
   165             }
   135             return null;
       
   136         }
   166         }
   137     }
   167     }
   138 
   168 
   139     PipeImpl(final SelectorProvider sp) throws IOException {
   169     PipeImpl(final SelectorProvider sp) throws IOException {
   140         try {
   170         try {
   142         } catch (PrivilegedActionException x) {
   172         } catch (PrivilegedActionException x) {
   143             throw (IOException)x.getCause();
   173             throw (IOException)x.getCause();
   144         }
   174         }
   145     }
   175     }
   146 
   176 
   147 
       
   148     public SourceChannel source() {
   177     public SourceChannel source() {
   149         return source;
   178         return source;
   150     }
   179     }
   151 
   180 
   152     public SinkChannel sink() {
   181     public SinkChannel sink() {