diff options
author | alanb <none@none> | 2010-06-17 17:49:59 +0100 |
---|---|---|
committer | alanb <none@none> | 2010-06-17 17:49:59 +0100 |
commit | 70b15e0ebbf9b3eaeb999e8419bb2a679617fab9 (patch) | |
tree | 2e71894256904ec8d83031be88d5ea225594252d /src | |
parent | d9e5053acb1490c3ff60b46b033ca3de28755295 (diff) |
6395224: (so) SocketChannel writer blocked on large buffer is not preempted by close method (vista)
Reviewed-by: chegar
Diffstat (limited to 'src')
-rw-r--r-- | src/windows/native/sun/nio/ch/SocketDispatcher.c | 30 | ||||
-rw-r--r-- | src/windows/native/sun/nio/ch/nio_util.h | 8 |
2 files changed, 36 insertions, 2 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(); |