8233430: (sc) Socket adaptor restoring of blocking mode can override exception if socket closed
authoralanb
Sun, 03 Nov 2019 14:07:43 +0000
changeset 58900 434329f6f456
parent 58899 5573a7098439
child 58901 2700c409ff10
8233430: (sc) Socket adaptor restoring of blocking mode can override exception if socket closed Reviewed-by: dfuchs, chegar
src/java.base/share/classes/sun/nio/ch/DummySocketImpl.java
src/java.base/share/classes/sun/nio/ch/ServerSocketChannelImpl.java
src/java.base/share/classes/sun/nio/ch/SocketChannelImpl.java
--- a/src/java.base/share/classes/sun/nio/ch/DummySocketImpl.java	Sat Nov 02 10:02:18 2019 +0000
+++ b/src/java.base/share/classes/sun/nio/ch/DummySocketImpl.java	Sun Nov 03 14:07:43 2019 +0000
@@ -31,8 +31,6 @@
 import java.net.SocketAddress;
 import java.net.SocketImpl;
 import java.net.SocketOption;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
 import java.util.Set;
 
 /**
@@ -41,12 +39,10 @@
  */
 
 class DummySocketImpl extends SocketImpl {
-    private static final PrivilegedAction<SocketImpl> NEW = DummySocketImpl::new;
-
     private DummySocketImpl() { }
 
     static SocketImpl create() {
-        return AccessController.doPrivileged(NEW);
+        return new DummySocketImpl();
     }
 
     private static <T> T shouldNotGetHere() {
--- a/src/java.base/share/classes/sun/nio/ch/ServerSocketChannelImpl.java	Sat Nov 02 10:02:18 2019 +0000
+++ b/src/java.base/share/classes/sun/nio/ch/ServerSocketChannelImpl.java	Sun Nov 03 14:07:43 2019 +0000
@@ -332,8 +332,8 @@
                         n = Net.accept(fd, newfd, isaa);
                     }
                 } finally {
-                    // restore socket to blocking mode
-                    lockedConfigureBlocking(true);
+                    // restore socket to blocking mode (if channel is open)
+                    tryLockedConfigureBlocking(true);
                 }
             } finally {
                 end(true, n > 0);
@@ -376,7 +376,7 @@
     }
 
     /**
-     * Adjust the blocking mode while holding acceptLock.
+     * Adjust the blocking. acceptLock must already be held.
      */
     private void lockedConfigureBlocking(boolean block) throws IOException {
         assert acceptLock.isHeldByCurrentThread();
@@ -387,6 +387,25 @@
     }
 
     /**
+     * Adjusts the blocking mode if the channel is open. acceptLock must already
+     * be held.
+     *
+     * @return {@code true} if the blocking mode was adjusted, {@code false} if
+     *         the blocking mode was not adjusted because the channel is closed
+     */
+    private boolean tryLockedConfigureBlocking(boolean block) throws IOException {
+        assert acceptLock.isHeldByCurrentThread();
+        synchronized (stateLock) {
+            if (isOpen()) {
+                IOUtil.configureBlocking(fd, block);
+                return true;
+            } else {
+                return false;
+            }
+        }
+    }
+
+    /**
      * Closes the socket if there are no accept in progress and the channel is
      * not registered with a Selector.
      */
--- a/src/java.base/share/classes/sun/nio/ch/SocketChannelImpl.java	Sat Nov 02 10:02:18 2019 +0000
+++ b/src/java.base/share/classes/sun/nio/ch/SocketChannelImpl.java	Sun Nov 03 14:07:43 2019 +0000
@@ -573,7 +573,7 @@
     }
 
     /**
-     * Adjust the blocking mode while holding the readLock or writeLock.
+     * Adjusts the blocking mode. readLock or writeLock must already be held.
      */
     private void lockedConfigureBlocking(boolean block) throws IOException {
         assert readLock.isHeldByCurrentThread() || writeLock.isHeldByCurrentThread();
@@ -584,6 +584,25 @@
     }
 
     /**
+     * Adjusts the blocking mode if the channel is open. readLock or writeLock
+     * must already be held.
+     *
+     * @return {@code true} if the blocking mode was adjusted, {@code false} if
+     *         the blocking mode was not adjusted because the channel is closed
+     */
+    private boolean tryLockedConfigureBlocking(boolean block) throws IOException {
+        assert readLock.isHeldByCurrentThread() || writeLock.isHeldByCurrentThread();
+        synchronized (stateLock) {
+            if (isOpen()) {
+                IOUtil.configureBlocking(fd, block);
+                return true;
+            } else {
+                return false;
+            }
+        }
+    }
+
+    /**
      * Returns the local address, or null if not bound
      */
     InetSocketAddress localAddress() {
@@ -1051,8 +1070,8 @@
                             int n = Net.connect(fd, isa.getAddress(), isa.getPort());
                             connected = (n > 0) ? true : finishTimedConnect(nanos);
                         } finally {
-                            // restore socket to blocking mode
-                            lockedConfigureBlocking(true);
+                            // restore socket to blocking mode (if channel is open)
+                            tryLockedConfigureBlocking(true);
                         }
                     } finally {
                         endConnect(true, connected);
@@ -1144,8 +1163,8 @@
                     try {
                         n = timedRead(b, off, len, nanos);
                     } finally {
-                        // restore socket to blocking mode
-                        lockedConfigureBlocking(true);
+                        // restore socket to blocking mode (if channel is open)
+                        tryLockedConfigureBlocking(true);
                     }
                 } else {
                     // read, no timeout