< prev index next >

src/java.base/share/classes/java/net/Socket.java

Print this page
*** 26,10 ***
--- 26,11 ---
  package java.net;
  
  import sun.security.util.SecurityConstants;
  
  import java.io.InputStream;
+ import java.io.InterruptedIOException;
  import java.io.OutputStream;
  import java.io.IOException;
  import java.lang.invoke.MethodHandles;
  import java.lang.invoke.VarHandle;
  import java.nio.channels.SocketChannel;

*** 568,10 ***
--- 569,15 ---
      }
  
      /**
       * Connects this socket to the server.
       *
+      * <p> For the system-default socket implementation at least, if a
+      * {@linkplain Thread#isVirtual() virtual thread} blocked in {@code connect}
+      * is {@linkplain Thread#interrupt() interrupted} then the socket is closed
+      * and {@link SocketException} is thrown with the interrupt status set.
+      *
       * @param   endpoint the {@code SocketAddress}
       * @throws  IOException if an error occurs during the connection
       * @throws  java.nio.channels.IllegalBlockingModeException
       *          if this socket has an associated channel,
       *          and the channel is in non-blocking mode

*** 586,10 ***
--- 592,15 ---
      /**
       * Connects this socket to the server with a specified timeout value.
       * A timeout of zero is interpreted as an infinite timeout. The connection
       * will then block until established or an error occurs.
       *
+      * <p> For the system-default socket implementation at least, if a
+      * {@linkplain Thread#isVirtual() virtual thread} blocked in {@code connect}
+      * is {@linkplain Thread#interrupt() interrupted} then the socket is closed
+      * and {@link SocketException} is thrown with the interrupt status set.
+      *
       * @param   endpoint the {@code SocketAddress}
       * @param   timeout  the timeout value to be used in milliseconds.
       * @throws  IOException if an error occurs during the connection
       * @throws  SocketTimeoutException if timeout expires before connecting
       * @throws  java.nio.channels.IllegalBlockingModeException

*** 628,11 ***
              else
                  security.checkConnect(addr.getHostAddress(), port);
          }
          if (!created)
              createImpl(true);
!         impl.connect(epoint, timeout);
          connected = true;
          /*
           * If the socket was not bound before the connect, it is now because
           * the kernel will have picked an ephemeral port & a local address
           */
--- 639,22 ---
              else
                  security.checkConnect(addr.getHostAddress(), port);
          }
          if (!created)
              createImpl(true);
!         try {
+             impl.connect(epoint, timeout);
+         } catch (SocketTimeoutException e) {
+             throw e;
+         } catch (InterruptedIOException e) {
+             Thread thread = Thread.currentThread();
+             if (thread.isVirtual() && thread.isInterrupted()) {
+                 close();
+                 throw new SocketException("Closed by interrupt");
+             }
+             throw e;
+         }
          connected = true;
          /*
           * If the socket was not bound before the connect, it is now because
           * the kernel will have picked an ephemeral port & a local address
           */

*** 909,10 ***
--- 931,15 ---
       *   {@link java.io.InputStream#available available} will
       *   return {@code 0}.
       *
       * </ul>
       *
+      * <p> For the system-default socket implementation at least, if a
+      * {@linkplain Thread#isVirtual() virtual thread} blocked in {@code read}
+      * is {@linkplain Thread#interrupt() interrupted} then the socket is closed
+      * and {@link SocketException} is thrown with the interrupt status set.
+      *
       * <p> Closing the returned {@link java.io.InputStream InputStream}
       * will close the associated socket.
       *
       * @return     an input stream for reading bytes from this socket.
       * @throws     IOException  if an I/O error occurs when creating the

*** 948,11 ***
       * I/O events.
       */
      private static class SocketInputStream extends InputStream {
          private final Socket parent;
          private final InputStream in;
- 
          SocketInputStream(Socket parent, InputStream in) {
              this.parent = parent;
              this.in = in;
          }
          @Override
--- 975,10 ---

*** 961,17 ***
              int n = read(a, 0, 1);
              return (n > 0) ? (a[0] & 0xff) : -1;
          }
          @Override
          public int read(byte[] b, int off, int len) throws IOException {
!             return in.read(b, off, len);
          }
          @Override
          public int available() throws IOException {
              return in.available();
          }
- 
          @Override
          public void close() throws IOException {
              parent.close();
          }
      }
--- 987,27 ---
              int n = read(a, 0, 1);
              return (n > 0) ? (a[0] & 0xff) : -1;
          }
          @Override
          public int read(byte[] b, int off, int len) throws IOException {
!             try {
+                 return in.read(b, off, len);
+             } catch (SocketTimeoutException e) {
+                 throw e;
+             } catch (InterruptedIOException e) {
+                 Thread thread = Thread.currentThread();
+                 if (thread.isVirtual() && thread.isInterrupted()) {
+                     close();
+                     throw new SocketException("Closed by interrupt");
+                 }
+                 throw e;
+             }
          }
          @Override
          public int available() throws IOException {
              return in.available();
          }
          @Override
          public void close() throws IOException {
              parent.close();
          }
      }

*** 983,10 ***
--- 1019,15 ---
       * stream delegates all of its operations to the channel.  If the channel
       * is in non-blocking mode then the output stream's {@code write}
       * operations will throw an {@link
       * java.nio.channels.IllegalBlockingModeException}.
       *
+      * <p> For the system-default socket implementation at least, if a
+      * {@linkplain Thread#isVirtual() virtual thread} blocked in {@code write}
+      * is {@linkplain Thread#interrupt() interrupted} then the socket is closed
+      * and {@link SocketException} is thrown with the interrupt status set.
+      *
       * <p> Closing the returned {@link java.io.OutputStream OutputStream}
       * will close the associated socket.
       *
       * @return     an output stream for writing bytes to this socket.
       * @throws     IOException  if an I/O error occurs when creating the

*** 1030,13 ***
              byte[] a = new byte[] { (byte) b };
              write(a, 0, 1);
          }
          @Override
          public void write(byte[] b, int off, int len) throws IOException {
!             out.write(b, off, len);
          }
- 
          @Override
          public void close() throws IOException {
              parent.close();
          }
      }
--- 1071,21 ---
              byte[] a = new byte[] { (byte) b };
              write(a, 0, 1);
          }
          @Override
          public void write(byte[] b, int off, int len) throws IOException {
!             try {
+                 out.write(b, off, len);
+             } catch (InterruptedIOException e) {
+                 Thread thread = Thread.currentThread();
+                 if (thread.isVirtual() && thread.isInterrupted()) {
+                     close();
+                     throw new SocketException("Closed by interrupt");
+                 }
+                 throw e;
+             }
          }
          @Override
          public void close() throws IOException {
              parent.close();
          }
      }
< prev index next >