From f2f6f9278953d6e33ba0d868f5464ecdf39b888d Mon Sep 17 00:00:00 2001 From: alanb Date: Wed, 22 Jan 2014 09:36:11 +0000 Subject: [PATCH] 7133499: (fc) FileChannel.read not preempted by asynchronous close on OS X Reviewed-by: chegar --- .../classes/sun/nio/ch/FileChannelImpl.java | 2 +- .../classes/sun/nio/ch/NativeThreadSet.java | 22 ++++----- .../ch/SimpleAsynchronousFileChannelImpl.java | 1 - src/solaris/native/sun/nio/ch/NativeThread.c | 45 +++++++++++-------- test/ProblemList.txt | 5 --- 5 files changed, 38 insertions(+), 37 deletions(-) diff --git a/src/share/classes/sun/nio/ch/FileChannelImpl.java b/src/share/classes/sun/nio/ch/FileChannelImpl.java index 703f59826..4f03216f4 100644 --- a/src/share/classes/sun/nio/ch/FileChannelImpl.java +++ b/src/share/classes/sun/nio/ch/FileChannelImpl.java @@ -110,7 +110,7 @@ public class FileChannelImpl } } - nd.preClose(fd); + // signal any threads blocked on this channel threads.signalAndWait(); if (parent != null) { diff --git a/src/share/classes/sun/nio/ch/NativeThreadSet.java b/src/share/classes/sun/nio/ch/NativeThreadSet.java index d6d4c5c9a..5eb90af87 100644 --- a/src/share/classes/sun/nio/ch/NativeThreadSet.java +++ b/src/share/classes/sun/nio/ch/NativeThreadSet.java @@ -82,8 +82,9 @@ class NativeThreadSet { // Signals all threads in this set. // - void signalAndWait() { - synchronized (this) { + synchronized void signalAndWait() { + boolean interrupted = false; + while (used > 0) { int u = used; int n = elts.length; for (int i = 0; i < n; i++) { @@ -96,16 +97,15 @@ class NativeThreadSet { break; } waitingToEmpty = true; - boolean interrupted = false; - while (used > 0) { - try { - wait(); - } catch (InterruptedException e) { - interrupted = true; - } + try { + wait(50); + } catch (InterruptedException e) { + interrupted = true; + } finally { + waitingToEmpty = false; } - if (interrupted) - Thread.currentThread().interrupt(); } + if (interrupted) + Thread.currentThread().interrupt(); } } diff --git a/src/share/classes/sun/nio/ch/SimpleAsynchronousFileChannelImpl.java b/src/share/classes/sun/nio/ch/SimpleAsynchronousFileChannelImpl.java index d0813390a..565848055 100644 --- a/src/share/classes/sun/nio/ch/SimpleAsynchronousFileChannelImpl.java +++ b/src/share/classes/sun/nio/ch/SimpleAsynchronousFileChannelImpl.java @@ -88,7 +88,6 @@ public class SimpleAsynchronousFileChannelImpl invalidateAllLocks(); // signal any threads blocked on this channel - nd.preClose(fdObj); threads.signalAndWait(); // wait until all async I/O operations have completely gracefully diff --git a/src/solaris/native/sun/nio/ch/NativeThread.c b/src/solaris/native/sun/nio/ch/NativeThread.c index 79a91a068..5e2a78b7a 100644 --- a/src/solaris/native/sun/nio/ch/NativeThread.c +++ b/src/solaris/native/sun/nio/ch/NativeThread.c @@ -32,27 +32,32 @@ #include "sun_nio_ch_NativeThread.h" #include "nio_util.h" - #ifdef __linux__ -#include -#include - -/* Also defined in src/solaris/native/java/net/linux_close.c */ -#define INTERRUPT_SIGNAL (__SIGRTMAX - 2) + #include + #include + /* Also defined in net/linux_close.c */ + #define INTERRUPT_SIGNAL (__SIGRTMAX - 2) +#elif __solaris__ + #include + #include + #define INTERRUPT_SIGNAL (SIGRTMAX - 2) +#elif _ALLBSD_SOURCE + #include + #include + /* Also defined in net/bsd_close.c */ + #define INTERRUPT_SIGNAL SIGIO +#else + #error "missing platform-specific definition here" +#endif static void nullHandler(int sig) { } -#endif - - JNIEXPORT void JNICALL Java_sun_nio_ch_NativeThread_init(JNIEnv *env, jclass cl) { -#ifdef __linux__ - /* Install the null handler for INTERRUPT_SIGNAL. This might overwrite the * handler previously installed by java/net/linux_close.c, but that's okay * since neither handler actually does anything. We install our own @@ -67,25 +72,27 @@ Java_sun_nio_ch_NativeThread_init(JNIEnv *env, jclass cl) sigemptyset(&sa.sa_mask); if (sigaction(INTERRUPT_SIGNAL, &sa, &osa) < 0) JNU_ThrowIOExceptionWithLastError(env, "sigaction"); - -#endif } JNIEXPORT jlong JNICALL Java_sun_nio_ch_NativeThread_current(JNIEnv *env, jclass cl) { -#ifdef __linux__ - return (long)pthread_self(); +#ifdef __solaris__ + return (jlong)thr_self(); #else - return -1; + return (jlong)pthread_self(); #endif } JNIEXPORT void JNICALL Java_sun_nio_ch_NativeThread_signal(JNIEnv *env, jclass cl, jlong thread) { -#ifdef __linux__ - if (pthread_kill((pthread_t)thread, INTERRUPT_SIGNAL)) - JNU_ThrowIOExceptionWithLastError(env, "Thread signal failed"); + int ret; +#ifdef __solaris__ + ret = thr_kill((thread_t)thread, INTERRUPT_SIGNAL); +#else + ret = pthread_kill((pthread_t)thread, INTERRUPT_SIGNAL); #endif + if (ret != 0) + JNU_ThrowIOExceptionWithLastError(env, "Thread signal failed"); } diff --git a/test/ProblemList.txt b/test/ProblemList.txt index e7c3ecd0f..1d9efbc98 100644 --- a/test/ProblemList.txt +++ b/test/ProblemList.txt @@ -183,11 +183,6 @@ java/net/DatagramSocket/SendDatagramToBadAddress.java macosx-all # 6963118 java/nio/channels/Selector/Wakeup.java windows-all -# 7133499, 7133497 -java/nio/channels/AsyncCloseAndInterrupt.java macosx-all -java/nio/channels/AsynchronousFileChannel/Lock.java macosx-all -java/nio/channels/FileChannel/Transfer.java macosx-all - # 7141822 java/nio/channels/DatagramChannel/ChangingAddress.java macosx-all -- GitLab