6346658: (se) Selector briefly spins when asynchronously closing a registered channel [win]

Reviewed-by: chegar, coffeys
This commit is contained in:
Alan Bateman 2012-02-20 18:55:10 +00:00
parent 2995eff3e3
commit 86410b610b
4 changed files with 30 additions and 21 deletions

View File

@ -44,8 +44,9 @@ class NativeThreadSet {
// //
int add() { int add() {
long th = NativeThread.current(); long th = NativeThread.current();
if (th == -1) // 0 and -1 are treated as placeholders, not real thread handles
return -1; if (th == 0)
th = -1;
synchronized (this) { synchronized (this) {
int start = 0; int start = 0;
if (used >= elts.length) { if (used >= elts.length) {
@ -71,8 +72,6 @@ class NativeThreadSet {
// Removes the thread at the given index. // Removes the thread at the given index.
// //
void remove(int i) { void remove(int i) {
if (i < 0)
return;
synchronized (this) { synchronized (this) {
elts[i] = 0; elts[i] = 0;
used--; used--;
@ -91,7 +90,8 @@ class NativeThreadSet {
long th = elts[i]; long th = elts[i];
if (th == 0) if (th == 0)
continue; continue;
NativeThread.signal(th); if (th != -1)
NativeThread.signal(th);
if (--u == 0) if (--u == 0)
break; break;
} }

View File

@ -31,7 +31,11 @@ package sun.nio.ch;
class NativeThread { 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) { } static void signal(long nt) { }

View File

@ -55,10 +55,11 @@ class SocketDispatcher extends NativeDispatcher
return writev0(fd, address, len); 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); close0(fd);
} }
@ -75,5 +76,7 @@ class SocketDispatcher extends NativeDispatcher
static native long writev0(FileDescriptor fd, long address, int len) static native long writev0(FileDescriptor fd, long address, int len)
throws IOException; throws IOException;
static native void preClose0(FileDescriptor fd) throws IOException;
static native void close0(FileDescriptor fd) throws IOException; static native void close0(FileDescriptor fd) throws IOException;
} }

View File

@ -238,23 +238,25 @@ Java_sun_nio_ch_SocketDispatcher_writev0(JNIEnv *env, jclass clazz,
} }
JNIEXPORT void JNICALL JNIEXPORT void JNICALL
Java_sun_nio_ch_SocketDispatcher_close0(JNIEnv *env, jclass clazz, Java_sun_nio_ch_SocketDispatcher_preClose0(JNIEnv *env, jclass clazz,
jobject fdo) jobject fdo)
{ {
jint fd = fdval(env, fdo); jint fd = fdval(env, fdo);
struct linger l; struct linger l;
int len = sizeof(l); int len = sizeof(l);
if (getsockopt(fd, SOL_SOCKET, SO_LINGER, (char *)&l, &len) == 0) {
if (fd != -1) { if (l.l_onoff == 0) {
int result = 0; WSASendDisconnect(fd, NULL);
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");
} }
} }
} }
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");
}
}