changeset 6989:2fd7486b4b35

8012244: java/net/Socket/asyncClose/Race.java fails intermittently on Windows Reviewed-by: chegar
author mbankal
date Tue, 21 Jan 2014 07:53:24 -0800
parents 19cc3b567644
children 08ff8b738146
files src/windows/classes/java/net/DualStackPlainSocketImpl.java src/windows/native/java/net/SocketInputStream.c test/java/net/Socket/asyncClose/Race.java
diffstat 3 files changed, 34 insertions(+), 31 deletions(-) [+]
line wrap: on
line diff
--- a/src/windows/classes/java/net/DualStackPlainSocketImpl.java	Wed Jan 22 12:34:24 2014 -0800
+++ b/src/windows/classes/java/net/DualStackPlainSocketImpl.java	Tue Jan 21 07:53:24 2014 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2014, Oracle and/or its affiliates. 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
@@ -162,8 +162,9 @@
         if (!fd.valid())
             return;
 
-        close0(fdAccess.get(fd));
+        final int nativefd = fdAccess.get(fd);
         fdAccess.set(fd, -1);
+        close0(nativefd);
     }
 
     void socketShutdown(int howto) throws IOException {
--- a/src/windows/native/java/net/SocketInputStream.c	Wed Jan 22 12:34:24 2014 -0800
+++ b/src/windows/native/java/net/SocketInputStream.c	Tue Jan 21 07:53:24 2014 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2014, Oracle and/or its affiliates. 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
@@ -134,32 +134,34 @@
         (*env)->SetByteArrayRegion(env, data, off, nread, (jbyte *)bufP);
     } else {
         if (nread < 0) {
-            /*
-             * Recv failed.
-             */
-            switch (WSAGetLastError()) {
-                case WSAEINTR:
-                    JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
-                        "socket closed");
-                    break;
+            // Check if the socket has been closed since we last checked.
+            // This could be a reason for recv failing.
+            if ((*env)->GetIntField(env, fdObj, IO_fd_fdID) == -1) {
+                NET_ThrowSocketException(env, "Socket closed");
+            } else {
+                switch (WSAGetLastError()) {
+                    case WSAEINTR:
+                        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
+                            "socket closed");
+                        break;
+                    case WSAECONNRESET:
+                    case WSAESHUTDOWN:
+                        /*
+                         * Connection has been reset - Windows sometimes reports
+                         * the reset as a shutdown error.
+                         */
+                        JNU_ThrowByName(env, "sun/net/ConnectionResetException",
+                            "");
+                        break;
 
-                case WSAECONNRESET:
-                case WSAESHUTDOWN:
-                    /*
-                     * Connection has been reset - Windows sometimes reports
-                     * the reset as a shutdown error.
-                     */
-                    JNU_ThrowByName(env, "sun/net/ConnectionResetException",
-                        "");
-                    break;
+                    case WSAETIMEDOUT :
+                        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketTimeoutException",
+                                       "Read timed out");
+                        break;
 
-                case WSAETIMEDOUT :
-                    JNU_ThrowByName(env, JNU_JAVANETPKG "SocketTimeoutException",
-                                   "Read timed out");
-                    break;
-
-                default:
-                    NET_ThrowCurrent(env, "recv failed");
+                    default:
+                        NET_ThrowCurrent(env, "recv failed");
+                }
             }
         }
     }
--- a/test/java/net/Socket/asyncClose/Race.java	Wed Jan 22 12:34:24 2014 -0800
+++ b/test/java/net/Socket/asyncClose/Race.java	Tue Jan 21 07:53:24 2014 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. 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
@@ -23,8 +23,8 @@
 
 /*
  * @test
- * @bug 8006395
- * @summary Race in async socket close on Linux
+ * @bug 8006395 8012244
+ * @summary Tests racing code that reads and closes a Socket
  */
 
 import java.io.InputStream;
@@ -58,7 +58,7 @@
                                     Thread.sleep(50);
                             } catch (Exception x) {
                                 if (!(x instanceof SocketException
-                                      && x.getMessage().equals("Socket closed")))
+                                      && x.getMessage().equalsIgnoreCase("socket closed")))
                                     x.printStackTrace();
                                 // ok, expect Socket closed
                             }