src/java.base/share/classes/java/net/ServerSocket.java
branchniosocketimpl-branch
changeset 57260 bb5198288772
parent 57252 d70fc9bc1430
child 57268 adcdd45830a0
equal deleted inserted replaced
57252:d70fc9bc1430 57260:bb5198288772
   556         if (si instanceof DelegatingSocketImpl) {
   556         if (si instanceof DelegatingSocketImpl) {
   557             si = ((DelegatingSocketImpl) si).delegate();
   557             si = ((DelegatingSocketImpl) si).delegate();
   558             assert si instanceof PlatformSocketImpl;
   558             assert si instanceof PlatformSocketImpl;
   559         }
   559         }
   560 
   560 
   561         // accept connection with a platform or custom SocketImpl
   561         // Accept connection with a platform or custom SocketImpl.
       
   562         // For the platform SocketImpl case:
       
   563         // - the connection is accepted with a new SocketImpl
       
   564         // - the SO_TIMEOUT socket option is copied to the new SocketImpl
       
   565         // - the Socket is connected to the new SocketImpl
       
   566         // - the existing/old SocketImpl is closed
       
   567         // For the custom SocketImpl case, the connection is accepted with the
       
   568         // existing custom SocketImpl.
   562         ensureCompatible(si);
   569         ensureCompatible(si);
   563         if (impl instanceof PlatformSocketImpl) {
   570         if (impl instanceof PlatformSocketImpl) {
   564             SocketImpl psi = platformImplAccept();
   571             SocketImpl psi = platformImplAccept();
   565             tryCopyOptions(si, psi);
   572             si.copyOptionsTo(psi);
   566             s.setImpl(psi);
   573             s.setImpl(psi);
   567             close(si);
   574             si.closeQuietly();
   568         } else {
   575         } else {
   569             customImplAccept(s, si);
   576             s.impl = null; // temporarily break connection to impl
   570             assert s.impl == si;
   577             try {
       
   578                 customImplAccept(si);
       
   579             } finally {
       
   580                 s.impl = si;  // restore connection to impl
       
   581             }
   571         }
   582         }
   572         s.postAccept();
   583         s.postAccept();
   573     }
   584     }
   574 
   585 
   575     /**
   586     /**
   578      */
   589      */
   579     private SocketImpl implAccept() throws IOException {
   590     private SocketImpl implAccept() throws IOException {
   580         if (impl instanceof PlatformSocketImpl) {
   591         if (impl instanceof PlatformSocketImpl) {
   581             return platformImplAccept();
   592             return platformImplAccept();
   582         } else {
   593         } else {
   583             // custom server SocketImpl, client socket SocketImpl must be set
   594             // custom server SocketImpl, client SocketImplFactory must be set
   584             SocketImplFactory factory = Socket.socketImplFactory();
   595             SocketImplFactory factory = Socket.socketImplFactory();
   585             if (factory == null) {
   596             if (factory == null) {
   586                 throw new IOException("An instance of " + impl.getClass() +
   597                 throw new IOException("An instance of " + impl.getClass() +
   587                     " cannot accept connection with 'null' SocketImpl:" +
   598                     " cannot accept connection with 'null' SocketImpl:" +
   588                     " client socket implementation factory not set");
   599                     " client socket implementation factory not set");
   589             }
   600             }
   590             SocketImpl si = factory.createSocketImpl();
   601             SocketImpl si = factory.createSocketImpl();
   591             implAccept(si);
   602             customImplAccept(si);
   592             return si;
   603             return si;
   593         }
   604         }
   594     }
   605     }
   595 
   606 
   596     /**
   607     /**
   605         implAccept(psi);
   616         implAccept(psi);
   606         return psi;
   617         return psi;
   607     }
   618     }
   608 
   619 
   609     /**
   620     /**
   610      * Accepts a new connection with a custom SocketImpl.
   621      * Accepts a new connection with the given custom SocketImpl.
   611      */
   622      */
   612     private void customImplAccept(Socket s, SocketImpl si) throws IOException {
   623     private void customImplAccept(SocketImpl si) throws IOException {
   613         assert !(impl instanceof PlatformSocketImpl)
   624         assert !(impl instanceof PlatformSocketImpl)
   614                 && !(si instanceof PlatformSocketImpl);
   625                 && !(si instanceof PlatformSocketImpl);
   615 
   626 
   616         s.impl = null; // break connection to impl
       
   617         si.reset();
   627         si.reset();
   618         try {
   628         try {
       
   629             // custom SocketImpl may expect fd/address objects to be created
       
   630             si.fd = new FileDescriptor();
       
   631             si.address = new InetAddress();
   619             implAccept(si);
   632             implAccept(si);
   620         } catch (Exception e) {
   633         } catch (Exception e) {
   621             si.reset();
   634             si.reset();
   622             throw e;
   635             throw e;
   623         } finally {
       
   624             s.impl = si;  // restore connection to impl
       
   625         }
   636         }
   626     }
   637     }
   627 
   638 
   628     /**
   639     /**
   629      * Accepts a new connection so that the given SocketImpl is connected to
   640      * Accepts a new connection so that the given SocketImpl is connected to
   632      * @throws IOException if an I/O error occurs
   643      * @throws IOException if an I/O error occurs
   633      * @throws SecurityException if the security manager's checkAccept method fails
   644      * @throws SecurityException if the security manager's checkAccept method fails
   634      */
   645      */
   635     private void implAccept(SocketImpl si) throws IOException {
   646     private void implAccept(SocketImpl si) throws IOException {
   636         assert !(si instanceof DelegatingSocketImpl);
   647         assert !(si instanceof DelegatingSocketImpl);
   637 
       
   638         // custom SocketImpl may expect fd/address objects to be created
       
   639         if (!(si instanceof PlatformSocketImpl)) {
       
   640             si.fd = new FileDescriptor();
       
   641             si.address = new InetAddress();
       
   642         }
       
   643 
   648 
   644         // accept a connection
   649         // accept a connection
   645         impl.accept(si);
   650         impl.accept(si);
   646 
   651 
   647         // check permission, close SocketImpl/connection if denied
   652         // check permission, close SocketImpl/connection if denied
   652             } catch (SecurityException se) {
   657             } catch (SecurityException se) {
   653                 si.close();
   658                 si.close();
   654                 throw se;
   659                 throw se;
   655             }
   660             }
   656         }
   661         }
   657     }
       
   658 
       
   659     /**
       
   660      * Attempts to copy socket options from an old/existing SocketImpl to a new
       
   661      * SocketImpl. At this time, only the SO_TIMEOUT make sense to copy.
       
   662      */
       
   663     private void tryCopyOptions(SocketImpl oldImpl, SocketImpl newImpl) {
       
   664         try {
       
   665             Object timeout = oldImpl.getOption(SocketOptions.SO_TIMEOUT);
       
   666             if (timeout instanceof Integer) {
       
   667                 newImpl.setOption(SocketOptions.SO_TIMEOUT, timeout);
       
   668             }
       
   669         } catch (IOException ignore) { }
       
   670     }
       
   671 
       
   672     /**
       
   673      * Close the given SocketImpl.
       
   674      */
       
   675     private void close(SocketImpl si) {
       
   676         try {
       
   677             si.close();
       
   678         } catch (IOException ignore) { }
       
   679     }
   662     }
   680 
   663 
   681     /**
   664     /**
   682      * Throws IOException if the server SocketImpl and the given client
   665      * Throws IOException if the server SocketImpl and the given client
   683      * SocketImpl are not both platform or custom SocketImpls.
   666      * SocketImpl are not both platform or custom SocketImpls.