--- a/jdk/src/java.base/share/classes/java/net/SocketInputStream.java Tue Sep 13 00:20:17 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/net/SocketInputStream.java Tue Sep 13 11:59:56 2016 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1995, 2016, 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
@@ -155,11 +155,12 @@
}
// bounds check
- if (length <= 0 || off < 0 || off + length > b.length) {
+ if (length <= 0 || off < 0 || length > b.length - off) {
if (length == 0) {
return 0;
}
- throw new ArrayIndexOutOfBoundsException();
+ throw new ArrayIndexOutOfBoundsException("length == " + length
+ + " off == " + off + " buffer length == " + b.length);
}
boolean gotReset = false;
--- a/jdk/src/java.base/share/classes/java/net/SocketOutputStream.java Tue Sep 13 00:20:17 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/net/SocketOutputStream.java Tue Sep 13 11:59:56 2016 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1995, 2016, 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
@@ -97,11 +97,13 @@
*/
private void socketWrite(byte b[], int off, int len) throws IOException {
- if (len <= 0 || off < 0 || off + len > b.length) {
+
+ if (len <= 0 || off < 0 || len > b.length - off) {
if (len == 0) {
return;
}
- throw new ArrayIndexOutOfBoundsException();
+ throw new ArrayIndexOutOfBoundsException("len == " + len
+ + " off == " + off + " buffer length == " + b.length);
}
FileDescriptor fd = impl.acquireFD();
--- a/jdk/src/java.base/unix/native/libnet/SocketOutputStream.c Tue Sep 13 00:20:17 2016 +0000
+++ b/jdk/src/java.base/unix/native/libnet/SocketOutputStream.c Tue Sep 13 11:59:56 2016 +0100
@@ -98,27 +98,31 @@
int llen = chunkLen;
(*env)->GetByteArrayRegion(env, data, off, chunkLen, (jbyte *)bufP);
- while(llen > 0) {
- int n = NET_Send(fd, bufP + loff, llen, 0);
- if (n > 0) {
- llen -= n;
- loff += n;
- continue;
+ if ((*env)->ExceptionCheck(env)) {
+ break;
+ } else {
+ while(llen > 0) {
+ int n = NET_Send(fd, bufP + loff, llen, 0);
+ if (n > 0) {
+ llen -= n;
+ loff += n;
+ continue;
+ }
+ if (errno == ECONNRESET) {
+ JNU_ThrowByName(env, "sun/net/ConnectionResetException",
+ "Connection reset");
+ } else {
+ JNU_ThrowByNameWithMessageAndLastError
+ (env, "java/net/SocketException", "Write failed");
+ }
+ if (bufP != BUF) {
+ free(bufP);
+ }
+ return;
}
- if (errno == ECONNRESET) {
- JNU_ThrowByName(env, "sun/net/ConnectionResetException",
- "Connection reset");
- } else {
- JNU_ThrowByNameWithMessageAndLastError
- (env, "java/net/SocketException", "Write failed");
- }
- if (bufP != BUF) {
- free(bufP);
- }
- return;
+ len -= chunkLen;
+ off += chunkLen;
}
- len -= chunkLen;
- off += chunkLen;
}
if (bufP != BUF) {
--- a/jdk/src/java.base/windows/native/libnet/SocketOutputStream.c Tue Sep 13 00:20:17 2016 +0000
+++ b/jdk/src/java.base/windows/native/libnet/SocketOutputStream.c Tue Sep 13 11:59:56 2016 +0100
@@ -92,66 +92,69 @@
int retry = 0;
(*env)->GetByteArrayRegion(env, data, off, chunkLen, (jbyte *)bufP);
-
- while(llen > 0) {
- int n = send(fd, bufP + loff, llen, 0);
- if (n > 0) {
- llen -= n;
- loff += n;
- continue;
- }
-
- /*
- * Due to a bug in Windows Sockets (observed on NT and Windows
- * 2000) it may be necessary to retry the send. The issue is that
- * on blocking sockets send/WSASend is supposed to block if there
- * is insufficient buffer space available. If there are a large
- * number of threads blocked on write due to congestion then it's
- * possile to hit the NT/2000 bug whereby send returns WSAENOBUFS.
- * The workaround we use is to retry the send. If we have a
- * large buffer to send (>2k) then we retry with a maximum of
- * 2k buffer. If we hit the issue with <=2k buffer then we backoff
- * for 1 second and retry again. We repeat this up to a reasonable
- * limit before bailing out and throwing an exception. In load
- * conditions we've observed that the send will succeed after 2-3
- * attempts but this depends on network buffers associated with
- * other sockets draining.
- */
- if (WSAGetLastError() == WSAENOBUFS) {
- if (llen > MAX_BUFFER_LEN) {
- buflen = MAX_BUFFER_LEN;
- chunkLen = MAX_BUFFER_LEN;
- llen = MAX_BUFFER_LEN;
+ if ((*env)->ExceptionCheck(env)) {
+ break;
+ } else {
+ while(llen > 0) {
+ int n = send(fd, bufP + loff, llen, 0);
+ if (n > 0) {
+ llen -= n;
+ loff += n;
continue;
}
- if (retry >= 30) {
- JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
- "No buffer space available - exhausted attempts to queue buffer");
- if (bufP != BUF) {
- free(bufP);
- }
- return;
- }
- Sleep(1000);
- retry++;
- continue;
- }
- /*
- * Send failed - can be caused by close or write error.
- */
- if (WSAGetLastError() == WSAENOTSOCK) {
- JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Socket closed");
- } else {
- NET_ThrowCurrent(env, "socket write error");
+ /*
+ * Due to a bug in Windows Sockets (observed on NT and Windows
+ * 2000) it may be necessary to retry the send. The issue is that
+ * on blocking sockets send/WSASend is supposed to block if there
+ * is insufficient buffer space available. If there are a large
+ * number of threads blocked on write due to congestion then it's
+ * possile to hit the NT/2000 bug whereby send returns WSAENOBUFS.
+ * The workaround we use is to retry the send. If we have a
+ * large buffer to send (>2k) then we retry with a maximum of
+ * 2k buffer. If we hit the issue with <=2k buffer then we backoff
+ * for 1 second and retry again. We repeat this up to a reasonable
+ * limit before bailing out and throwing an exception. In load
+ * conditions we've observed that the send will succeed after 2-3
+ * attempts but this depends on network buffers associated with
+ * other sockets draining.
+ */
+ if (WSAGetLastError() == WSAENOBUFS) {
+ if (llen > MAX_BUFFER_LEN) {
+ buflen = MAX_BUFFER_LEN;
+ chunkLen = MAX_BUFFER_LEN;
+ llen = MAX_BUFFER_LEN;
+ continue;
+ }
+ if (retry >= 30) {
+ JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
+ "No buffer space available - exhausted attempts to queue buffer");
+ if (bufP != BUF) {
+ free(bufP);
+ }
+ return;
+ }
+ Sleep(1000);
+ retry++;
+ continue;
+ }
+
+ /*
+ * Send failed - can be caused by close or write error.
+ */
+ if (WSAGetLastError() == WSAENOTSOCK) {
+ JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Socket closed");
+ } else {
+ NET_ThrowCurrent(env, "socket write error");
+ }
+ if (bufP != BUF) {
+ free(bufP);
+ }
+ return;
}
- if (bufP != BUF) {
- free(bufP);
- }
- return;
+ len -= chunkLen;
+ off += chunkLen;
}
- len -= chunkLen;
- off += chunkLen;
}
if (bufP != BUF) {