diff --git a/src/java.base/unix/classes/sun/nio/ch/NativeThread.java b/src/java.base/unix/classes/sun/nio/ch/NativeThread.java index 2ec67cc7d5c..22e79091eee 100644 --- a/src/java.base/unix/classes/sun/nio/ch/NativeThread.java +++ b/src/java.base/unix/classes/sun/nio/ch/NativeThread.java @@ -78,6 +78,17 @@ static boolean isVirtualThread(long tid) { return (tid == VIRTUAL_THREAD_ID); } + /** + * Return true if the operating system supports pending signals. If a signal is sent + * to a thread but cannot be delivered immediately then it will be delivered when the + * thread is in the appropriate state. + */ + static boolean supportPendingSignals() { + return supportPendingSignals0(); + } + + private static native boolean supportPendingSignals0(); + // Returns an opaque token representing the native thread underlying the // invoking Java thread. On systems that do not require signalling, this // method always returns 0. diff --git a/src/java.base/unix/classes/sun/nio/ch/UnixDispatcher.java b/src/java.base/unix/classes/sun/nio/ch/UnixDispatcher.java index fcd2d88d7a6..4cdd0c400ec 100644 --- a/src/java.base/unix/classes/sun/nio/ch/UnixDispatcher.java +++ b/src/java.base/unix/classes/sun/nio/ch/UnixDispatcher.java @@ -29,21 +29,31 @@ import java.io.IOException; abstract class UnixDispatcher extends NativeDispatcher { + private static final boolean SUPPORTS_PENDING_SIGNALS = NativeThread.supportPendingSignals(); @Override void close(FileDescriptor fd) throws IOException { close0(fd); } - @Override - void implPreClose(FileDescriptor fd, long reader, long writer) throws IOException { - preClose0(fd); + private void signalThreads(long reader, long writer) { if (NativeThread.isNativeThread(reader)) NativeThread.signal(reader); if (NativeThread.isNativeThread(writer)) NativeThread.signal(writer); } + @Override + void implPreClose(FileDescriptor fd, long reader, long writer) throws IOException { + if (SUPPORTS_PENDING_SIGNALS) { + signalThreads(reader, writer); + } + preClose0(fd); + if (!SUPPORTS_PENDING_SIGNALS) { + signalThreads(reader, writer); + } + } + private static native void close0(FileDescriptor fd) throws IOException; private static native void preClose0(FileDescriptor fd) throws IOException; diff --git a/src/java.base/unix/native/libnio/ch/NativeThread.c b/src/java.base/unix/native/libnio/ch/NativeThread.c index f273b951569..006d2f19b06 100644 --- a/src/java.base/unix/native/libnio/ch/NativeThread.c +++ b/src/java.base/unix/native/libnio/ch/NativeThread.c @@ -88,3 +88,12 @@ Java_sun_nio_ch_NativeThread_signal0(JNIEnv *env, jclass cl, jlong thread) #endif JNU_ThrowIOExceptionWithLastError(env, "Thread signal failed"); } + +JNIEXPORT jboolean JNICALL +Java_sun_nio_ch_NativeThread_supportPendingSignals0(JNIEnv *env, jclass cl) { +#if defined(_AIX) + return JNI_TRUE; +#else + return JNI_FALSE; +#endif +}