8012244: java/net/Socket/asyncClose/Race.java fails intermittently on Windows
Reviewed-by: alanb, dsamersoff
--- a/jdk/src/windows/classes/java/net/DualStackPlainSocketImpl.java Tue Apr 16 12:51:22 2013 +0100
+++ b/jdk/src/windows/classes/java/net/DualStackPlainSocketImpl.java Tue Apr 16 13:26:30 2013 +0100
@@ -152,8 +152,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/jdk/src/windows/native/java/net/SocketInputStream.c Tue Apr 16 12:51:22 2013 +0100
+++ b/jdk/src/windows/native/java/net/SocketInputStream.c Tue Apr 16 13:26:30 2013 +0100
@@ -134,32 +134,35 @@
(*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/jdk/test/java/net/Socket/asyncClose/Race.java Tue Apr 16 12:51:22 2013 +0100
+++ b/jdk/test/java/net/Socket/asyncClose/Race.java Tue Apr 16 13:26:30 2013 +0100
@@ -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
}