aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/windows/native/sun/nio/ch/SocketDispatcher.c30
-rw-r--r--src/windows/native/sun/nio/ch/nio_util.h8
-rw-r--r--test/ProblemList.txt3
-rw-r--r--test/java/nio/channels/AsyncCloseAndInterrupt.java25
4 files changed, 54 insertions, 12 deletions
diff --git a/src/windows/native/sun/nio/ch/SocketDispatcher.c b/src/windows/native/sun/nio/ch/SocketDispatcher.c
index 78265a069..0fa7c35a9 100644
--- a/src/windows/native/sun/nio/ch/SocketDispatcher.c
+++ b/src/windows/native/sun/nio/ch/SocketDispatcher.c
@@ -50,6 +50,10 @@ Java_sun_nio_ch_SocketDispatcher_read0(JNIEnv *env, jclass clazz, jobject fdo,
jint fd = fdval(env, fdo);
WSABUF buf;
+ /* limit size */
+ if (len > MAX_BUFFER_SIZE)
+ len = MAX_BUFFER_SIZE;
+
/* destination buffer and size */
buf.buf = (char *)address;
buf.len = (u_long)len;
@@ -86,6 +90,7 @@ Java_sun_nio_ch_SocketDispatcher_readv0(JNIEnv *env, jclass clazz, jobject fdo,
jint fd = fdval(env, fdo);
struct iovec *iovp = (struct iovec *)address;
WSABUF *bufs = malloc(len * sizeof(WSABUF));
+ jint rem = MAX_BUFFER_SIZE;
if (bufs == 0) {
JNU_ThrowOutOfMemoryError(env, 0);
@@ -98,8 +103,16 @@ Java_sun_nio_ch_SocketDispatcher_readv0(JNIEnv *env, jclass clazz, jobject fdo,
/* copy iovec into WSABUF */
for(i=0; i<len; i++) {
+ jint iov_len = iovp[i].iov_len;
+ if (iov_len > rem)
+ iov_len = rem;
bufs[i].buf = (char *)iovp[i].iov_base;
- bufs[i].len = (u_long)iovp[i].iov_len;
+ bufs[i].len = (u_long)iov_len;
+ rem -= iov_len;
+ if (rem == 0) {
+ len = i+1;
+ break;
+ }
}
/* read into the buffers */
@@ -136,6 +149,10 @@ Java_sun_nio_ch_SocketDispatcher_write0(JNIEnv *env, jclass clazz, jobject fdo,
jint fd = fdval(env, fdo);
WSABUF buf;
+ /* limit size */
+ if (len > MAX_BUFFER_SIZE)
+ len = MAX_BUFFER_SIZE;
+
/* copy iovec into WSABUF */
buf.buf = (char *)address;
buf.len = (u_long)len;
@@ -171,6 +188,7 @@ Java_sun_nio_ch_SocketDispatcher_writev0(JNIEnv *env, jclass clazz,
jint fd = fdval(env, fdo);
struct iovec *iovp = (struct iovec *)address;
WSABUF *bufs = malloc(len * sizeof(WSABUF));
+ jint rem = MAX_BUFFER_SIZE;
if (bufs == 0) {
JNU_ThrowOutOfMemoryError(env, 0);
@@ -183,8 +201,16 @@ Java_sun_nio_ch_SocketDispatcher_writev0(JNIEnv *env, jclass clazz,
/* copy iovec into WSABUF */
for(i=0; i<len; i++) {
+ jint iov_len = iovp[i].iov_len;
+ if (iov_len > rem)
+ iov_len = rem;
bufs[i].buf = (char *)iovp[i].iov_base;
- bufs[i].len = (u_long)iovp[i].iov_len;
+ bufs[i].len = (u_long)iov_len;
+ rem -= iov_len;
+ if (rem == 0) {
+ len = i+1;
+ break;
+ }
}
/* read into the buffers */
diff --git a/src/windows/native/sun/nio/ch/nio_util.h b/src/windows/native/sun/nio/ch/nio_util.h
index 9c7a6d958..963e93ef0 100644
--- a/src/windows/native/sun/nio/ch/nio_util.h
+++ b/src/windows/native/sun/nio/ch/nio_util.h
@@ -25,6 +25,14 @@
#include "jni.h"
+/**
+ * The maximum buffer size for WSASend/WSARecv. Microsoft recommendation for
+ * blocking operations is to use buffers no larger than 64k. We need the
+ * maximum to be less than 128k to support asynchronous close on Windows
+ * Server 2003 and newer editions of Windows.
+ */
+#define MAX_BUFFER_SIZE ((128*1024)-1)
+
jint fdval(JNIEnv *env, jobject fdo);
jlong handleval(JNIEnv *env, jobject fdo);
jboolean isNT();
diff --git a/test/ProblemList.txt b/test/ProblemList.txt
index 70ffffbec..089cc18f4 100644
--- a/test/ProblemList.txt
+++ b/test/ProblemList.txt
@@ -772,9 +772,6 @@ com/sun/nio/sctp/SctpMultiChannel/SocketOptionTests.java generic-all
# Linux 64bit failures. too many files open
java/nio/channels/Selector/HelperSlowToDie.java generic-all
-# Timeouts etc. on Window
-java/nio/channels/AsyncCloseAndInterrupt.java windows-all
-
# Gets java.lang.ExceptionInInitializerError on Windows 2000 (need XP or newer)
java/nio/channels/AsynchronousChannelGroup/Basic.java windows-5.0
java/nio/channels/AsynchronousChannelGroup/GroupOfOne.java windows-5.0
diff --git a/test/java/nio/channels/AsyncCloseAndInterrupt.java b/test/java/nio/channels/AsyncCloseAndInterrupt.java
index a18a936cc..b0fb0cfa3 100644
--- a/test/java/nio/channels/AsyncCloseAndInterrupt.java
+++ b/test/java/nio/channels/AsyncCloseAndInterrupt.java
@@ -22,7 +22,7 @@
*/
/* @test
- * @bug 4460583 4470470 4840199 6419424 6710579 6596323 6824135
+ * @bug 4460583 4470470 4840199 6419424 6710579 6596323 6824135 6395224
* @summary Comprehensive test of asynchronous closing and interruption
* @author Mark Reinhold
*/
@@ -88,6 +88,9 @@ public class AsyncCloseAndInterrupt {
}
private static void pumpRefuser(String msg) throws IOException {
+ // Can't reliably saturate connection backlog on Windows Server editions
+ assert !TestUtil.onWindows();
+
log.print(msg);
int n = refuserClients.size();
@@ -203,9 +206,9 @@ public class AsyncCloseAndInterrupt {
= new ChannelFactory("DatagramChannel") {
InterruptibleChannel create() throws IOException {
DatagramChannel dc = DatagramChannel.open();
- dc.socket().bind(wildcardAddress);
- InetAddress ia = InetAddress.getByName("127.0.0.1");
- dc.connect(new InetSocketAddress(ia, 80));
+ InetAddress lb = InetAddress.getByName("127.0.0.1");
+ dc.bind(new InetSocketAddress(lb, 0));
+ dc.connect(new InetSocketAddress(lb, 80));
return dc;
}
};
@@ -636,7 +639,8 @@ public class AsyncCloseAndInterrupt {
wildcardAddress = new InetSocketAddress(InetAddress.getLocalHost(), 0);
initAcceptor();
- initRefuser();
+ if (!TestUtil.onWindows())
+ initRefuser();
initPipes();
initFile();
@@ -658,8 +662,15 @@ public class AsyncCloseAndInterrupt {
// unclear under what conditions mmap(2) will actually block.
test(connectedSocketChannelFactory);
- test(socketChannelFactory, CONNECT);
- test(socketChannelFactory, FINISH_CONNECT);
+
+ if (TestUtil.onWindows()) {
+ log.println("WARNING Cannot reliably test connect/finishConnect"
+ + " operations on Windows");
+ } else {
+ test(socketChannelFactory, CONNECT);
+ test(socketChannelFactory, FINISH_CONNECT);
+ }
+
test(serverSocketChannelFactory, ACCEPT);
test(datagramChannelFactory);
test(pipeSourceChannelFactory);