changeset 5027:f35dfb4114e7

6346658: (se) Selector briefly spins when asynchronously closing a registered channel [win] Reviewed-by: chegar, coffeys
author alanb
date Tue, 22 May 2012 17:54:46 +0100
parents 05c4a1c2ce25
children 5bf0eb7c560c
files src/share/classes/sun/nio/ch/NativeThreadSet.java src/windows/classes/sun/nio/ch/NativeThread.java src/windows/classes/sun/nio/ch/SocketDispatcher.java src/windows/native/sun/nio/ch/SocketDispatcher.c
diffstat 4 files changed, 31 insertions(+), 22 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/sun/nio/ch/NativeThreadSet.java	Mon May 21 19:28:41 2012 +0200
+++ b/src/share/classes/sun/nio/ch/NativeThreadSet.java	Tue May 22 17:54:46 2012 +0100
@@ -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/src/windows/classes/sun/nio/ch/NativeThread.java	Mon May 21 19:28:41 2012 +0200
+++ b/src/windows/classes/sun/nio/ch/NativeThread.java	Tue May 22 17:54:46 2012 +0100
@@ -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/src/windows/classes/sun/nio/ch/SocketDispatcher.java	Mon May 21 19:28:41 2012 +0200
+++ b/src/windows/classes/sun/nio/ch/SocketDispatcher.java	Tue May 22 17:54:46 2012 +0100
@@ -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/src/windows/native/sun/nio/ch/SocketDispatcher.c	Mon May 21 19:28:41 2012 +0200
+++ b/src/windows/native/sun/nio/ch/SocketDispatcher.c	Tue May 22 17:54:46 2012 +0100
@@ -238,23 +238,25 @@
 }
 
 JNIEXPORT void JNICALL
+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 (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);
-    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 (closesocket(fd) == SOCKET_ERROR) {
+        JNU_ThrowIOExceptionWithLastError(env, "Socket close failed");
     }
 }