# HG changeset patch # User alanb # Date 1276793399 -3600 # Node ID faf9bd47d6ced1a81f491fc25d735c783a5c1ad3 # Parent c3ddaebe216bca339fa81c4f22eb8a754c95e952 6395224: (so) SocketChannel writer blocked on large buffer is not preempted by close method (vista) Reviewed-by: chegar diff -r c3ddaebe216b -r faf9bd47d6ce jdk/src/windows/native/sun/nio/ch/SocketDispatcher.c --- a/jdk/src/windows/native/sun/nio/ch/SocketDispatcher.c Wed Jun 16 23:27:41 2010 -0700 +++ b/jdk/src/windows/native/sun/nio/ch/SocketDispatcher.c Thu Jun 17 17:49:59 2010 +0100 @@ -50,6 +50,10 @@ 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 @@ 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 @@ /* copy iovec into WSABUF */ for(i=0; i 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 @@ 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 @@ 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 @@ /* copy iovec into WSABUF */ for(i=0; i 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 -r c3ddaebe216b -r faf9bd47d6ce jdk/src/windows/native/sun/nio/ch/nio_util.h --- a/jdk/src/windows/native/sun/nio/ch/nio_util.h Wed Jun 16 23:27:41 2010 -0700 +++ b/jdk/src/windows/native/sun/nio/ch/nio_util.h Thu Jun 17 17:49:59 2010 +0100 @@ -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 -r c3ddaebe216b -r faf9bd47d6ce jdk/test/ProblemList.txt --- a/jdk/test/ProblemList.txt Wed Jun 16 23:27:41 2010 -0700 +++ b/jdk/test/ProblemList.txt Thu Jun 17 17:49:59 2010 +0100 @@ -772,9 +772,6 @@ # 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 -r c3ddaebe216b -r faf9bd47d6ce jdk/test/java/nio/channels/AsyncCloseAndInterrupt.java --- a/jdk/test/java/nio/channels/AsyncCloseAndInterrupt.java Wed Jun 16 23:27:41 2010 -0700 +++ b/jdk/test/java/nio/channels/AsyncCloseAndInterrupt.java Thu Jun 17 17:49:59 2010 +0100 @@ -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 @@ } 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 @@ = 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 @@ wildcardAddress = new InetSocketAddress(InetAddress.getLocalHost(), 0); initAcceptor(); - initRefuser(); + if (!TestUtil.onWindows()) + initRefuser(); initPipes(); initFile(); @@ -658,8 +662,15 @@ // 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);