src/java.base/share/classes/sun/nio/ch/NioSocketImpl.java
branchniosocketimpl-branch
changeset 57207 30695f27d7ea
parent 57189 c56554b46dec
child 57211 4503441bec2e
equal deleted inserted replaced
57203:a2529b040b48 57207:30695f27d7ea
     1 /*
     1 /*
     2  * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
     2  * Copyright (c) 2018, 2019, 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
   246             Util.offerFirstTemporaryDirectBuffer(dst);
   246             Util.offerFirstTemporaryDirectBuffer(dst);
   247         }
   247         }
   248     }
   248     }
   249 
   249 
   250     /**
   250     /**
       
   251      * Reads bytes from the socket into the given byte array with a timeout.
       
   252      * @throws SocketTimeoutException if the read timeout elapses
       
   253      */
       
   254     private int timedRead(FileDescriptor fd, byte[] b, int off, int len, int millis)
       
   255         throws IOException
       
   256     {
       
   257         long nanos = NANOSECONDS.convert(millis, TimeUnit.MILLISECONDS);
       
   258         long remainingNanos = nanos;
       
   259         long startNanos = System.nanoTime();
       
   260         int n;
       
   261         do {
       
   262             park(fd, Net.POLLIN, remainingNanos);
       
   263             n = tryRead(fd, b, off, len);
       
   264             if (n == IOStatus.UNAVAILABLE) {
       
   265                 remainingNanos = nanos - (System.nanoTime() - startNanos);
       
   266                 if (remainingNanos <= 0) {
       
   267                     throw new SocketTimeoutException("Read timed out");
       
   268                 }
       
   269             }
       
   270         } while (n == IOStatus.UNAVAILABLE && isOpen());
       
   271         return n;
       
   272     }
       
   273 
       
   274     /**
   251      * Reads bytes from the socket into the given byte array.
   275      * Reads bytes from the socket into the given byte array.
   252      * @return the number of bytes read
   276      * @return the number of bytes read
   253      * @throws IOException if the socket is closed or an I/O occurs
   277      * @throws IOException if the socket is closed or an I/O occurs
   254      * @throws SocketTimeoutException if the read timeout elapses
   278      * @throws SocketTimeoutException if the read timeout elapses
   255      */
   279      */
   256     private int read(byte[] b, int off, int len) throws IOException {
   280     private int read(byte[] b, int off, int len) throws IOException {
   257         readLock.lock();
   281         readLock.lock();
   258         try {
   282         try {
   259             int timeout = this.timeout;
       
   260             int n = 0;
   283             int n = 0;
   261             FileDescriptor fd = beginRead();
   284             FileDescriptor fd = beginRead();
   262             try {
   285             try {
   263                 if (isInputClosed)
   286                 if (isInputClosed)
   264                     return IOStatus.EOF;
   287                     return IOStatus.EOF;
       
   288                 int timeout = this.timeout;
   265                 configureNonBlockingIfNeeded(fd, timeout);
   289                 configureNonBlockingIfNeeded(fd, timeout);
   266                 n = tryRead(fd, b, off, len);
   290                 n = tryRead(fd, b, off, len);
   267                 if (IOStatus.okayToRetry(n) && isOpen()) {
   291                 if (IOStatus.okayToRetry(n) && isOpen()) {
   268                     if (timeout > 0) {
   292                     if (timeout > 0) {
   269                         // read with timeout
   293                         // read with timeout
   270                         long nanos = NANOSECONDS.convert(timeout, TimeUnit.MILLISECONDS);
   294                         n = timedRead(fd, b, off, len, timeout);
   271                         do {
       
   272                             long startTime = System.nanoTime();
       
   273                             park(fd, Net.POLLIN, nanos);
       
   274                             n = tryRead(fd, b, off, len);
       
   275                             if (n == IOStatus.UNAVAILABLE) {
       
   276                                 nanos -= System.nanoTime() - startTime;
       
   277                                 if (nanos <= 0)
       
   278                                     throw new SocketTimeoutException("Read timed out");
       
   279                             }
       
   280                         } while (n == IOStatus.UNAVAILABLE && isOpen());
       
   281                     } else {
   295                     } else {
   282                         // read, no timeout
   296                         // read, no timeout
   283                         do {
   297                         do {
   284                             park(fd, Net.POLLIN);
   298                             park(fd, Net.POLLIN);
   285                             n = tryRead(fd, b, off, len);
   299                             n = tryRead(fd, b, off, len);
   521                 localport = Net.localAddress(fd).getPort();
   535                 localport = Net.localAddress(fd).getPort();
   522             } else if (!completed && state >= ST_CLOSING) {
   536             } else if (!completed && state >= ST_CLOSING) {
   523                 throw new SocketException("Socket closed");
   537                 throw new SocketException("Socket closed");
   524             }
   538             }
   525         }
   539         }
       
   540     }
       
   541 
       
   542     /**
       
   543      * Waits for a connection attempt to finish with a timeout
       
   544      * @throws SocketTimeoutException if the connect timeout elapses
       
   545      */
       
   546     private int timedFinishConnect(FileDescriptor fd, int millis) throws IOException {
       
   547         long nanos = NANOSECONDS.convert(millis, TimeUnit.MILLISECONDS);
       
   548         long remainingNanos = nanos;
       
   549         long startNanos = System.nanoTime();
       
   550         int n;
       
   551         do {
       
   552             park(fd, Net.POLLOUT, remainingNanos);
       
   553             n = Net.pollConnectNow(fd);
       
   554             if (n == 0) {
       
   555                 remainingNanos = nanos - (System.nanoTime() - startNanos);
       
   556                 if (remainingNanos <= 0) {
       
   557                     throw new SocketTimeoutException("Connect timed out");
       
   558                 }
       
   559             }
       
   560         } while (n == 0 && isOpen());
       
   561         return n;
   526     }
   562     }
   527 
   563 
   528     /**
   564     /**
   529      * Connect the socket. Closes the socket if connection cannot be established.
   565      * Connect the socket. Closes the socket if connection cannot be established.
   530      * @throws IllegalArgumentException if the address is not an InetSocketAddress
   566      * @throws IllegalArgumentException if the address is not an InetSocketAddress
   553                 try {
   589                 try {
   554                     configureNonBlockingIfNeeded(fd, millis);
   590                     configureNonBlockingIfNeeded(fd, millis);
   555                     int n = Net.connect(fd, address, port);
   591                     int n = Net.connect(fd, address, port);
   556                     if (IOStatus.okayToRetry(n) && isOpen()) {
   592                     if (IOStatus.okayToRetry(n) && isOpen()) {
   557                         if (millis > 0) {
   593                         if (millis > 0) {
   558                             // connect with timeout
   594                             // finish connect with timeout
   559                             assert nonBlocking;
   595                             n = timedFinishConnect(fd, millis);
   560                             long nanos = NANOSECONDS.convert(millis, MILLISECONDS);
       
   561                             do {
       
   562                                 long startTime = System.nanoTime();
       
   563                                 park(fd, Net.POLLOUT, nanos);
       
   564                                 n = Net.pollConnectNow(fd);
       
   565                                 if (n == 0) {
       
   566                                     nanos -= System.nanoTime() - startTime;
       
   567                                     if (nanos <= 0)
       
   568                                         throw new SocketTimeoutException("Connect timed out");
       
   569                                 }
       
   570                             } while (n == 0 && isOpen());
       
   571                         } else {
   596                         } else {
   572                             // connect, no timeout
   597                             // finish connect, no timeout
   573                             do {
   598                             do {
   574                                 park(fd, Net.POLLOUT);
   599                                 park(fd, Net.POLLOUT);
   575                                 n = Net.pollConnectNow(fd);
   600                                 n = Net.pollConnectNow(fd);
   576                             } while (n == 0 && isOpen());
   601                             } while (n == 0 && isOpen());
   577                         }
   602                         }
   657             if (state == ST_CLOSING)
   682             if (state == ST_CLOSING)
   658                 stateLock.notifyAll();
   683                 stateLock.notifyAll();
   659             if (!completed && state >= ST_CLOSING)
   684             if (!completed && state >= ST_CLOSING)
   660                 throw new SocketException("Socket closed");
   685                 throw new SocketException("Socket closed");
   661         }
   686         }
       
   687     }
       
   688 
       
   689     /**
       
   690      * Accepts a new connection with a timeout
       
   691      * @throws SocketTimeoutException if the accept timeout elapses
       
   692      */
       
   693     private int timedAccept(FileDescriptor fd,
       
   694                             FileDescriptor newfd,
       
   695                             InetSocketAddress[] isaa,
       
   696                             int millis)
       
   697         throws IOException
       
   698     {
       
   699         long nanos = NANOSECONDS.convert(millis, TimeUnit.MILLISECONDS);
       
   700         long remainingNanos = nanos;
       
   701         long startNanos = System.nanoTime();
       
   702         int n;
       
   703         do {
       
   704             park(fd, Net.POLLIN, remainingNanos);
       
   705             n = ServerSocketChannelImpl.accept0(fd, newfd, isaa);
       
   706             if (n == IOStatus.UNAVAILABLE) {
       
   707                 remainingNanos = nanos - (System.nanoTime() - startNanos);
       
   708                 if (remainingNanos <= 0) {
       
   709                     throw new SocketTimeoutException("Accept timed out");
       
   710                 }
       
   711             }
       
   712         } while (n == IOStatus.UNAVAILABLE && isOpen());
       
   713         return n;
   662     }
   714     }
   663 
   715 
   664     @Override
   716     @Override
   665     protected void accept(SocketImpl si) throws IOException {
   717     protected void accept(SocketImpl si) throws IOException {
   666         // accept a connection
   718         // accept a connection
   677                 configureNonBlockingIfNeeded(fd, timeout);
   729                 configureNonBlockingIfNeeded(fd, timeout);
   678                 n = ServerSocketChannelImpl.accept0(fd, newfd, isaa);
   730                 n = ServerSocketChannelImpl.accept0(fd, newfd, isaa);
   679                 if (IOStatus.okayToRetry(n) && isOpen()) {
   731                 if (IOStatus.okayToRetry(n) && isOpen()) {
   680                     if (timeout > 0) {
   732                     if (timeout > 0) {
   681                         // accept with timeout
   733                         // accept with timeout
   682                         assert nonBlocking;
   734                         n = timedAccept(fd, newfd, isaa, timeout);
   683                         long nanos = NANOSECONDS.convert(timeout, TimeUnit.MILLISECONDS);
       
   684                         do {
       
   685                             long startTime = System.nanoTime();
       
   686                             park(fd, Net.POLLIN, nanos);
       
   687                             n = ServerSocketChannelImpl.accept0(fd, newfd, isaa);
       
   688                             if (n == IOStatus.UNAVAILABLE) {
       
   689                                 nanos -= System.nanoTime() - startTime;
       
   690                                 if (nanos <= 0)
       
   691                                     throw new SocketTimeoutException("Accept timed out");
       
   692                             }
       
   693                         } while (n == IOStatus.UNAVAILABLE && isOpen());
       
   694                     } else {
   735                     } else {
   695                         // accept, no timeout
   736                         // accept, no timeout
   696                         do {
   737                         do {
   697                             park(fd, Net.POLLIN);
   738                             park(fd, Net.POLLIN);
   698                             n = ServerSocketChannelImpl.accept0(fd, newfd, isaa);
   739                             n = ServerSocketChannelImpl.accept0(fd, newfd, isaa);
   754             public int read(byte[] b, int off, int len) throws IOException {
   795             public int read(byte[] b, int off, int len) throws IOException {
   755                 Objects.checkFromIndexSize(off, len, b.length);
   796                 Objects.checkFromIndexSize(off, len, b.length);
   756                 if (eof) {
   797                 if (eof) {
   757                     return -1;
   798                     return -1;
   758                 } else if (reset) {
   799                 } else if (reset) {
       
   800                     NioSocketImpl.this.ensureOpen();
   759                     throw new SocketException("Connection reset");
   801                     throw new SocketException("Connection reset");
   760                 } else if (len == 0) {
   802                 } else if (len == 0) {
   761                     return 0;
   803                     return 0;
   762                 } else {
   804                 } else {
   763                     try {
   805                     try {
  1151             try {
  1193             try {
  1152                 do {
  1194                 do {
  1153                     n = Net.sendOOB(fd, (byte) data);
  1195                     n = Net.sendOOB(fd, (byte) data);
  1154                 } while (n == IOStatus.INTERRUPTED && isOpen());
  1196                 } while (n == IOStatus.INTERRUPTED && isOpen());
  1155                 if (n == IOStatus.UNAVAILABLE) {
  1197                 if (n == IOStatus.UNAVAILABLE) {
  1156                     throw new RuntimeException("not implemented yet");
  1198                     throw new SocketException("No buffer space available");
  1157                 }
  1199                 }
  1158             } finally {
  1200             } finally {
  1159                 endWrite(n > 0);
  1201                 endWrite(n > 0);
  1160             }
  1202             }
  1161         } finally {
  1203         } finally {