src/java.base/share/classes/sun/nio/ch/ServerSocketChannelImpl.java
changeset 54154 1caf2daef7cf
parent 53419 eac105e3ec13
child 54620 13b67c1420b8
child 57268 adcdd45830a0
equal deleted inserted replaced
54153:4985c8ca55b9 54154:1caf2daef7cf
    56 class ServerSocketChannelImpl
    56 class ServerSocketChannelImpl
    57     extends ServerSocketChannel
    57     extends ServerSocketChannel
    58     implements SelChImpl
    58     implements SelChImpl
    59 {
    59 {
    60     // Used to make native close and configure calls
    60     // Used to make native close and configure calls
    61     private static NativeDispatcher nd;
    61     private static final NativeDispatcher nd = new SocketDispatcher();
    62 
    62 
    63     // Our file descriptor
    63     // Our file descriptor
    64     private final FileDescriptor fd;
    64     private final FileDescriptor fd;
    65     private final int fdVal;
    65     private final int fdVal;
    66 
    66 
    95     // -- End of fields protected by stateLock
    95     // -- End of fields protected by stateLock
    96 
    96 
    97 
    97 
    98     ServerSocketChannelImpl(SelectorProvider sp) throws IOException {
    98     ServerSocketChannelImpl(SelectorProvider sp) throws IOException {
    99         super(sp);
    99         super(sp);
   100         this.fd =  Net.serverSocket(true);
   100         this.fd = Net.serverSocket(true);
   101         this.fdVal = IOUtil.fdVal(fd);
   101         this.fdVal = IOUtil.fdVal(fd);
   102     }
   102     }
   103 
   103 
   104     ServerSocketChannelImpl(SelectorProvider sp, FileDescriptor fd, boolean bound)
   104     ServerSocketChannelImpl(SelectorProvider sp, FileDescriptor fd, boolean bound)
   105         throws IOException
   105         throws IOException
   259         }
   259         }
   260     }
   260     }
   261 
   261 
   262     @Override
   262     @Override
   263     public SocketChannel accept() throws IOException {
   263     public SocketChannel accept() throws IOException {
       
   264         int n = 0;
       
   265         FileDescriptor newfd = new FileDescriptor();
       
   266         InetSocketAddress[] isaa = new InetSocketAddress[1];
       
   267 
   264         acceptLock.lock();
   268         acceptLock.lock();
   265         try {
   269         try {
   266             int n = 0;
       
   267             FileDescriptor newfd = new FileDescriptor();
       
   268             InetSocketAddress[] isaa = new InetSocketAddress[1];
       
   269 
       
   270             boolean blocking = isBlocking();
   270             boolean blocking = isBlocking();
   271             try {
   271             try {
   272                 begin(blocking);
   272                 begin(blocking);
   273                 do {
   273                 do {
   274                     n = accept(this.fd, newfd, isaa);
   274                     n = Net.accept(this.fd, newfd, isaa);
   275                 } while (n == IOStatus.INTERRUPTED && isOpen());
   275                 } while (n == IOStatus.INTERRUPTED && isOpen());
   276             } finally {
   276             } finally {
   277                 end(blocking, n > 0);
   277                 end(blocking, n > 0);
   278                 assert IOStatus.check(n);
   278                 assert IOStatus.check(n);
   279             }
   279             }
   280 
   280 
   281             if (n < 1)
   281         } finally {
   282                 return null;
   282             acceptLock.unlock();
   283 
   283         }
       
   284 
       
   285         if (n < 1)
       
   286             return null;
       
   287 
       
   288         InetSocketAddress isa = isaa[0];
       
   289         try {
   284             // newly accepted socket is initially in blocking mode
   290             // newly accepted socket is initially in blocking mode
   285             IOUtil.configureBlocking(newfd, true);
   291             IOUtil.configureBlocking(newfd, true);
   286 
       
   287             InetSocketAddress isa = isaa[0];
       
   288             SocketChannel sc = new SocketChannelImpl(provider(), newfd, isa);
       
   289 
   292 
   290             // check permitted to accept connections from the remote address
   293             // check permitted to accept connections from the remote address
   291             SecurityManager sm = System.getSecurityManager();
   294             SecurityManager sm = System.getSecurityManager();
   292             if (sm != null) {
   295             if (sm != null) {
   293                 try {
   296                 sm.checkAccept(isa.getAddress().getHostAddress(), isa.getPort());
   294                     sm.checkAccept(isa.getAddress().getHostAddress(), isa.getPort());
   297             }
   295                 } catch (SecurityException x) {
   298             return new SocketChannelImpl(provider(), newfd, isa);
   296                     sc.close();
   299         } catch (Exception e) {
   297                     throw x;
   300             nd.close(newfd);
   298                 }
   301             throw e;
   299             }
       
   300             return sc;
       
   301 
       
   302         } finally {
       
   303             acceptLock.unlock();
       
   304         }
   302         }
   305     }
   303     }
   306 
   304 
   307     @Override
   305     @Override
   308     protected void implConfigureBlocking(boolean block) throws IOException {
   306     protected void implConfigureBlocking(boolean block) throws IOException {
   506             }
   504             }
   507         }
   505         }
   508         sb.append(']');
   506         sb.append(']');
   509         return sb.toString();
   507         return sb.toString();
   510     }
   508     }
   511 
       
   512     /**
       
   513      * Accept a connection on a socket.
       
   514      *
       
   515      * @implNote Wrap native call to allow instrumentation.
       
   516      */
       
   517     private int accept(FileDescriptor ssfd,
       
   518                        FileDescriptor newfd,
       
   519                        InetSocketAddress[] isaa)
       
   520         throws IOException
       
   521     {
       
   522         return accept0(ssfd, newfd, isaa);
       
   523     }
       
   524 
       
   525     // -- Native methods --
       
   526 
       
   527     // Accepts a new connection, setting the given file descriptor to refer to
       
   528     // the new socket and setting isaa[0] to the socket's remote address.
       
   529     // Returns 1 on success, or IOStatus.UNAVAILABLE (if non-blocking and no
       
   530     // connections are pending) or IOStatus.INTERRUPTED.
       
   531     //
       
   532     private native int accept0(FileDescriptor ssfd,
       
   533                                FileDescriptor newfd,
       
   534                                InetSocketAddress[] isaa)
       
   535         throws IOException;
       
   536 
       
   537     private static native void initIDs();
       
   538 
       
   539     static {
       
   540         IOUtil.load();
       
   541         initIDs();
       
   542         nd = new SocketDispatcher();
       
   543     }
       
   544 
       
   545 }
   509 }