6346658: (se) Selector briefly spins when asynchronously closing a registered channel [win]
authoralanb
Mon, 20 Feb 2012 18:55:10 +0000
changeset 11909 a1a7165ac1fa
parent 11908 384d1c31d539
child 11910 5ebe67376f05
6346658: (se) Selector briefly spins when asynchronously closing a registered channel [win] Reviewed-by: chegar, coffeys
jdk/src/share/classes/sun/nio/ch/NativeThreadSet.java
jdk/src/windows/classes/sun/nio/ch/NativeThread.java
jdk/src/windows/classes/sun/nio/ch/SocketDispatcher.java
jdk/src/windows/native/sun/nio/ch/SocketDispatcher.c
--- 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");
+    }
+}