4516760: (so) Intermittent SocketException: Transport endpoint is not connected (lnx)
authoralanb
Tue, 11 Aug 2009 12:37:02 +0100
changeset 3486 0e14ae32369e
parent 3485 bc05765c365a
child 3487 e0d89f22e6ef
4516760: (so) Intermittent SocketException: Transport endpoint is not connected (lnx) Reviewed-by: sherman
jdk/src/solaris/native/sun/nio/ch/Net.c
jdk/test/java/nio/channels/SocketChannel/Shutdown.java
--- a/jdk/src/solaris/native/sun/nio/ch/Net.c	Tue Aug 11 18:27:01 2009 +0800
+++ b/jdk/src/solaris/native/sun/nio/ch/Net.c	Tue Aug 11 12:37:02 2009 +0100
@@ -541,7 +541,7 @@
 {
     int how = (jhow == sun_nio_ch_Net_SHUT_RD) ? SHUT_RD :
         (jhow == sun_nio_ch_Net_SHUT_WR) ? SHUT_WR : SHUT_RDWR;
-    if (shutdown(fdval(env, fdo), how) < 0)
+    if ((shutdown(fdval(env, fdo), how) < 0) && (errno != ENOTCONN))
         handleSocketError(env, errno);
 }
 
--- a/jdk/test/java/nio/channels/SocketChannel/Shutdown.java	Tue Aug 11 18:27:01 2009 +0800
+++ b/jdk/test/java/nio/channels/SocketChannel/Shutdown.java	Tue Aug 11 12:37:02 2009 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright 2002 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2002-2009 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -22,26 +22,65 @@
  */
 
 /* @test
- * @bug 4618960
- * @summary Test isInputShutdown
- * @library ..
+ * @bug 4618960 4516760
+ * @summary Test shutdownXXX and isInputShutdown
  */
 
+import java.io.IOException;
 import java.net.*;
-import java.nio.*;
+import java.nio.ByteBuffer;
 import java.nio.channels.*;
 
 public class Shutdown {
 
-    public static void main(String args[]) throws Exception {
-        InetSocketAddress sa = new InetSocketAddress(
-                                InetAddress.getByName(TestUtil.HOST), 23);
-        SocketChannel sc = SocketChannel.open(sa);
-        boolean before = sc.socket().isInputShutdown();
-        sc.socket().shutdownInput();
-        boolean after = sc.socket().isInputShutdown();
-        sc.close();
-        if (before || !after)
-            throw new Exception("Test failed");
+    /**
+     * Accept a connection, and close it immediately causing a hard reset.
+     */
+    static void acceptAndReset(ServerSocketChannel ssc) throws IOException {
+        SocketChannel peer = ssc.accept();
+        try {
+            peer.setOption(StandardSocketOption.SO_LINGER, 0);
+            peer.configureBlocking(false);
+            peer.write(ByteBuffer.wrap(new byte[128*1024]));
+        } finally {
+            peer.close();
+        }
+    }
+
+    public static void main(String[] args) throws Exception {
+        ServerSocketChannel ssc = ServerSocketChannel.open()
+            .bind(new InetSocketAddress(0));
+        try {
+            InetAddress lh = InetAddress.getLocalHost();
+            int port = ((InetSocketAddress)(ssc.getLocalAddress())).getPort();
+            SocketAddress remote = new InetSocketAddress(lh, port);
+
+            // Test SocketChannel shutdownXXX
+            SocketChannel sc;
+            sc = SocketChannel.open(remote);
+            try {
+                acceptAndReset(ssc);
+                sc.shutdownInput();
+                sc.shutdownOutput();
+            } finally {
+                sc.close();
+            }
+
+            // Test Socket adapter shutdownXXX and isShutdownInput
+            sc = SocketChannel.open(remote);
+            try {
+                acceptAndReset(ssc);
+                boolean before = sc.socket().isInputShutdown();
+                sc.socket().shutdownInput();
+                boolean after = sc.socket().isInputShutdown();
+                if (before || !after)
+                    throw new RuntimeException("Before and after test failed");
+                sc.socket().shutdownOutput();
+            } finally {
+                sc.close();
+            }
+        } finally {
+            ssc.close();
+        }
     }
 }