6346658: (se) Selector briefly spins when asynchronously closing a registered channel [win]
Reviewed-by: chegar, coffeys
--- a/jdk/src/share/classes/sun/nio/ch/NativeThreadSet.java Mon Feb 20 11:24:06 2012 +0800
+++ b/jdk/src/share/classes/sun/nio/ch/NativeThreadSet.java Mon Feb 20 18:55:10 2012 +0000
@@ -44,8 +44,9 @@
//
int add() {
long th = NativeThread.current();
- if (th == -1)
- return -1;
+ // 0 and -1 are treated as placeholders, not real thread handles
+ if (th == 0)
+ th = -1;
synchronized (this) {
int start = 0;
if (used >= elts.length) {
@@ -71,8 +72,6 @@
// Removes the thread at the given index.
//
void remove(int i) {
- if (i < 0)
- return;
synchronized (this) {
elts[i] = 0;
used--;
@@ -91,7 +90,8 @@
long th = elts[i];
if (th == 0)
continue;
- NativeThread.signal(th);
+ if (th != -1)
+ NativeThread.signal(th);
if (--u == 0)
break;
}
--- a/jdk/src/windows/classes/sun/nio/ch/NativeThread.java Mon Feb 20 11:24:06 2012 +0800
+++ b/jdk/src/windows/classes/sun/nio/ch/NativeThread.java Mon Feb 20 18:55:10 2012 +0000
@@ -31,7 +31,11 @@
class NativeThread {
- static long current() { return -1; }
+ static long current() {
+ // return 0 to ensure that async close of blocking sockets will close
+ // the underlying socket.
+ return 0;
+ }
static void signal(long nt) { }
--- a/jdk/src/windows/classes/sun/nio/ch/SocketDispatcher.java Mon Feb 20 11:24:06 2012 +0800
+++ b/jdk/src/windows/classes/sun/nio/ch/SocketDispatcher.java Mon Feb 20 18:55:10 2012 +0000
@@ -55,10 +55,11 @@
return writev0(fd, address, len);
}
- void close(FileDescriptor fd) throws IOException {
+ void preClose(FileDescriptor fd) throws IOException {
+ preClose0(fd);
}
- void preClose(FileDescriptor fd) throws IOException {
+ void close(FileDescriptor fd) throws IOException {
close0(fd);
}
@@ -75,5 +76,7 @@
static native long writev0(FileDescriptor fd, long address, int len)
throws IOException;
+ static native void preClose0(FileDescriptor fd) throws IOException;
+
static native void close0(FileDescriptor fd) throws IOException;
}
--- a/jdk/src/windows/native/sun/nio/ch/SocketDispatcher.c Mon Feb 20 11:24:06 2012 +0800
+++ b/jdk/src/windows/native/sun/nio/ch/SocketDispatcher.c Mon Feb 20 18:55:10 2012 +0000
@@ -238,23 +238,25 @@
}
JNIEXPORT void JNICALL
-Java_sun_nio_ch_SocketDispatcher_close0(JNIEnv *env, jclass clazz,
- jobject fdo)
+Java_sun_nio_ch_SocketDispatcher_preClose0(JNIEnv *env, jclass clazz,
+ jobject fdo)
{
jint fd = fdval(env, fdo);
struct linger l;
int len = sizeof(l);
-
- if (fd != -1) {
- int result = 0;
- if (getsockopt(fd, SOL_SOCKET, SO_LINGER, (char *)&l, &len) == 0) {
- if (l.l_onoff == 0) {
- WSASendDisconnect(fd, NULL);
- }
- }
- result = closesocket(fd);
- if (result == SOCKET_ERROR) {
- JNU_ThrowIOExceptionWithLastError(env, "Socket close failed");
+ if (getsockopt(fd, SOL_SOCKET, SO_LINGER, (char *)&l, &len) == 0) {
+ if (l.l_onoff == 0) {
+ WSASendDisconnect(fd, NULL);
}
}
}
+
+JNIEXPORT void JNICALL
+Java_sun_nio_ch_SocketDispatcher_close0(JNIEnv *env, jclass clazz,
+ jobject fdo)
+{
+ jint fd = fdval(env, fdo);
+ if (closesocket(fd) == SOCKET_ERROR) {
+ JNU_ThrowIOExceptionWithLastError(env, "Socket close failed");
+ }
+}