src/java.base/share/classes/sun/nio/ch/SocketChannelImpl.java
changeset 54246 f04e3492fd88
parent 53445 c96f9aa1f3d8
child 54620 13b67c1420b8
child 57278 bf925a3ee68a
--- a/src/java.base/share/classes/sun/nio/ch/SocketChannelImpl.java	Fri Mar 22 13:42:45 2019 +0530
+++ b/src/java.base/share/classes/sun/nio/ch/SocketChannelImpl.java	Fri Mar 22 11:35:35 2019 +0000
@@ -32,6 +32,7 @@
 import java.net.ProtocolFamily;
 import java.net.Socket;
 import java.net.SocketAddress;
+import java.net.SocketException;
 import java.net.SocketOption;
 import java.net.StandardProtocolFamily;
 import java.net.StandardSocketOptions;
@@ -52,6 +53,7 @@
 import java.util.Set;
 import java.util.concurrent.locks.ReentrantLock;
 
+import sun.net.ConnectionResetException;
 import sun.net.NetHooks;
 import sun.net.ext.ExtendedSocketOptions;
 import sun.net.util.SocketExceptions;
@@ -85,6 +87,9 @@
     private volatile boolean isInputClosed;
     private volatile boolean isOutputClosed;
 
+    // Connection reset protected by readLock
+    private boolean connectionReset;
+
     // -- The following fields are protected by stateLock
 
     // set true when exclusive binding is on and SO_REUSEADDR is emulated
@@ -230,7 +235,7 @@
             }
 
             // no options that require special handling
-            Net.setSocketOption(fd, Net.UNSPEC, name, value);
+            Net.setSocketOption(fd, name, value);
             return this;
         }
     }
@@ -260,7 +265,7 @@
             }
 
             // no options that require special handling
-            return (T) Net.getSocketOption(fd, Net.UNSPEC, name);
+            return (T) Net.getSocketOption(fd, name);
         }
     }
 
@@ -334,6 +339,10 @@
         }
     }
 
+    private void throwConnectionReset() throws SocketException {
+        throw new SocketException("Connection reset");
+    }
+
     @Override
     public int read(ByteBuffer buf) throws IOException {
         Objects.requireNonNull(buf);
@@ -345,6 +354,10 @@
             try {
                 beginRead(blocking);
 
+                // check if connection has been reset
+                if (connectionReset)
+                    throwConnectionReset();
+
                 // check if input is shutdown
                 if (isInputClosed)
                     return IOStatus.EOF;
@@ -356,6 +369,9 @@
                 } else {
                     n = IOUtil.read(fd, buf, -1, nd);
                 }
+            } catch (ConnectionResetException e) {
+                connectionReset = true;
+                throwConnectionReset();
             } finally {
                 endRead(blocking, n > 0);
                 if (n <= 0 && isInputClosed)
@@ -380,6 +396,10 @@
             try {
                 beginRead(blocking);
 
+                // check if connection has been reset
+                if (connectionReset)
+                    throwConnectionReset();
+
                 // check if input is shutdown
                 if (isInputClosed)
                     return IOStatus.EOF;
@@ -391,6 +411,9 @@
                 } else {
                     n = IOUtil.read(fd, dsts, offset, length, nd);
                 }
+            } catch (ConnectionResetException e) {
+                connectionReset = true;
+                throwConnectionReset();
             } finally {
                 endRead(blocking, n > 0);
                 if (n <= 0 && isInputClosed)
@@ -769,15 +792,13 @@
                     boolean connected = false;
                     try {
                         beginFinishConnect(blocking);
-                        int n = 0;
                         if (blocking) {
                             do {
-                                n = Net.pollConnect(fd, -1);
-                            } while ((n == 0 || n == IOStatus.INTERRUPTED) && isOpen());
+                                connected = Net.pollConnect(fd, -1);
+                            } while (!connected && isOpen());
                         } else {
-                            n = Net.pollConnect(fd, 0);
+                            connected = Net.pollConnect(fd, 0);
                         }
-                        connected = (n > 0);
                     } finally {
                         endFinishConnect(blocking, connected);
                     }
@@ -1007,6 +1028,20 @@
     }
 
     /**
+     * Return the number of bytes in the socket input buffer.
+     */
+    int available() throws IOException {
+        synchronized (stateLock) {
+            ensureOpenAndConnected();
+            if (isInputClosed) {
+                return 0;
+            } else {
+                return Net.available(fd);
+            }
+        }
+    }
+
+    /**
      * Translates native poll revent ops into a ready operation ops
      */
     public boolean translateReadyOps(int ops, int initialOps, SelectionKeyImpl ski) {