提交 a830a508 编写于 作者: A alanb

6395224: (so) SocketChannel writer blocked on large buffer is not preempted by close method (vista)

Reviewed-by: chegar
上级 39a75741
...@@ -50,6 +50,10 @@ Java_sun_nio_ch_SocketDispatcher_read0(JNIEnv *env, jclass clazz, jobject fdo, ...@@ -50,6 +50,10 @@ Java_sun_nio_ch_SocketDispatcher_read0(JNIEnv *env, jclass clazz, jobject fdo,
jint fd = fdval(env, fdo); jint fd = fdval(env, fdo);
WSABUF buf; WSABUF buf;
/* limit size */
if (len > MAX_BUFFER_SIZE)
len = MAX_BUFFER_SIZE;
/* destination buffer and size */ /* destination buffer and size */
buf.buf = (char *)address; buf.buf = (char *)address;
buf.len = (u_long)len; buf.len = (u_long)len;
...@@ -86,6 +90,7 @@ Java_sun_nio_ch_SocketDispatcher_readv0(JNIEnv *env, jclass clazz, jobject fdo, ...@@ -86,6 +90,7 @@ Java_sun_nio_ch_SocketDispatcher_readv0(JNIEnv *env, jclass clazz, jobject fdo,
jint fd = fdval(env, fdo); jint fd = fdval(env, fdo);
struct iovec *iovp = (struct iovec *)address; struct iovec *iovp = (struct iovec *)address;
WSABUF *bufs = malloc(len * sizeof(WSABUF)); WSABUF *bufs = malloc(len * sizeof(WSABUF));
jint rem = MAX_BUFFER_SIZE;
if (bufs == 0) { if (bufs == 0) {
JNU_ThrowOutOfMemoryError(env, 0); JNU_ThrowOutOfMemoryError(env, 0);
...@@ -98,8 +103,16 @@ Java_sun_nio_ch_SocketDispatcher_readv0(JNIEnv *env, jclass clazz, jobject fdo, ...@@ -98,8 +103,16 @@ Java_sun_nio_ch_SocketDispatcher_readv0(JNIEnv *env, jclass clazz, jobject fdo,
/* copy iovec into WSABUF */ /* copy iovec into WSABUF */
for(i=0; i<len; i++) { 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].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 */ /* read into the buffers */
...@@ -136,6 +149,10 @@ Java_sun_nio_ch_SocketDispatcher_write0(JNIEnv *env, jclass clazz, jobject fdo, ...@@ -136,6 +149,10 @@ Java_sun_nio_ch_SocketDispatcher_write0(JNIEnv *env, jclass clazz, jobject fdo,
jint fd = fdval(env, fdo); jint fd = fdval(env, fdo);
WSABUF buf; WSABUF buf;
/* limit size */
if (len > MAX_BUFFER_SIZE)
len = MAX_BUFFER_SIZE;
/* copy iovec into WSABUF */ /* copy iovec into WSABUF */
buf.buf = (char *)address; buf.buf = (char *)address;
buf.len = (u_long)len; buf.len = (u_long)len;
...@@ -171,6 +188,7 @@ Java_sun_nio_ch_SocketDispatcher_writev0(JNIEnv *env, jclass clazz, ...@@ -171,6 +188,7 @@ Java_sun_nio_ch_SocketDispatcher_writev0(JNIEnv *env, jclass clazz,
jint fd = fdval(env, fdo); jint fd = fdval(env, fdo);
struct iovec *iovp = (struct iovec *)address; struct iovec *iovp = (struct iovec *)address;
WSABUF *bufs = malloc(len * sizeof(WSABUF)); WSABUF *bufs = malloc(len * sizeof(WSABUF));
jint rem = MAX_BUFFER_SIZE;
if (bufs == 0) { if (bufs == 0) {
JNU_ThrowOutOfMemoryError(env, 0); JNU_ThrowOutOfMemoryError(env, 0);
...@@ -183,8 +201,16 @@ Java_sun_nio_ch_SocketDispatcher_writev0(JNIEnv *env, jclass clazz, ...@@ -183,8 +201,16 @@ Java_sun_nio_ch_SocketDispatcher_writev0(JNIEnv *env, jclass clazz,
/* copy iovec into WSABUF */ /* copy iovec into WSABUF */
for(i=0; i<len; i++) { 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].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 */ /* read into the buffers */
......
...@@ -25,6 +25,14 @@ ...@@ -25,6 +25,14 @@
#include "jni.h" #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); jint fdval(JNIEnv *env, jobject fdo);
jlong handleval(JNIEnv *env, jobject fdo); jlong handleval(JNIEnv *env, jobject fdo);
jboolean isNT(); jboolean isNT();
......
...@@ -772,9 +772,6 @@ com/sun/nio/sctp/SctpMultiChannel/SocketOptionTests.java generic-all ...@@ -772,9 +772,6 @@ com/sun/nio/sctp/SctpMultiChannel/SocketOptionTests.java generic-all
# Linux 64bit failures. too many files open # Linux 64bit failures. too many files open
java/nio/channels/Selector/HelperSlowToDie.java generic-all 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) # Gets java.lang.ExceptionInInitializerError on Windows 2000 (need XP or newer)
java/nio/channels/AsynchronousChannelGroup/Basic.java windows-5.0 java/nio/channels/AsynchronousChannelGroup/Basic.java windows-5.0
java/nio/channels/AsynchronousChannelGroup/GroupOfOne.java windows-5.0 java/nio/channels/AsynchronousChannelGroup/GroupOfOne.java windows-5.0
......
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
*/ */
/* @test /* @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 * @summary Comprehensive test of asynchronous closing and interruption
* @author Mark Reinhold * @author Mark Reinhold
*/ */
...@@ -88,6 +88,9 @@ public class AsyncCloseAndInterrupt { ...@@ -88,6 +88,9 @@ public class AsyncCloseAndInterrupt {
} }
private static void pumpRefuser(String msg) throws IOException { private static void pumpRefuser(String msg) throws IOException {
// Can't reliably saturate connection backlog on Windows Server editions
assert !TestUtil.onWindows();
log.print(msg); log.print(msg);
int n = refuserClients.size(); int n = refuserClients.size();
...@@ -203,9 +206,9 @@ public class AsyncCloseAndInterrupt { ...@@ -203,9 +206,9 @@ public class AsyncCloseAndInterrupt {
= new ChannelFactory("DatagramChannel") { = new ChannelFactory("DatagramChannel") {
InterruptibleChannel create() throws IOException { InterruptibleChannel create() throws IOException {
DatagramChannel dc = DatagramChannel.open(); DatagramChannel dc = DatagramChannel.open();
dc.socket().bind(wildcardAddress); InetAddress lb = InetAddress.getByName("127.0.0.1");
InetAddress ia = InetAddress.getByName("127.0.0.1"); dc.bind(new InetSocketAddress(lb, 0));
dc.connect(new InetSocketAddress(ia, 80)); dc.connect(new InetSocketAddress(lb, 80));
return dc; return dc;
} }
}; };
...@@ -636,7 +639,8 @@ public class AsyncCloseAndInterrupt { ...@@ -636,7 +639,8 @@ public class AsyncCloseAndInterrupt {
wildcardAddress = new InetSocketAddress(InetAddress.getLocalHost(), 0); wildcardAddress = new InetSocketAddress(InetAddress.getLocalHost(), 0);
initAcceptor(); initAcceptor();
initRefuser(); if (!TestUtil.onWindows())
initRefuser();
initPipes(); initPipes();
initFile(); initFile();
...@@ -658,8 +662,15 @@ public class AsyncCloseAndInterrupt { ...@@ -658,8 +662,15 @@ public class AsyncCloseAndInterrupt {
// unclear under what conditions mmap(2) will actually block. // unclear under what conditions mmap(2) will actually block.
test(connectedSocketChannelFactory); 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(serverSocketChannelFactory, ACCEPT);
test(datagramChannelFactory); test(datagramChannelFactory);
test(pipeSourceChannelFactory); test(pipeSourceChannelFactory);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册