diff --git a/src/hotspot/share/prims/jvm.cpp b/src/hotspot/share/prims/jvm.cpp index 13d89b396fa40..66f2a6da7a6b0 100644 --- a/src/hotspot/share/prims/jvm.cpp +++ b/src/hotspot/share/prims/jvm.cpp @@ -2893,15 +2893,16 @@ JVM_ENTRY(void, JVM_SleepNanos(JNIEnv* env, jclass threadClass, jlong nanos)) } else { ThreadState old_state = thread->osthread()->get_state(); thread->osthread()->set_state(SLEEPING); - if (!thread->sleep_nanos(nanos)) { // interrupted + if (!thread->sleep_nanos(nanos)) { // interrupted or async exception was installed // An asynchronous exception could have been thrown on // us while we were sleeping. We do not overwrite those. if (!HAS_PENDING_EXCEPTION) { HOTSPOT_THREAD_SLEEP_END(1); - - // TODO-FIXME: THROW_MSG returns which means we will not call set_state() - // to properly restore the thread state. That's likely wrong. - THROW_MSG(vmSymbols::java_lang_InterruptedException(), "sleep interrupted"); + if (!thread->has_async_exception_condition()) { + // TODO-FIXME: THROW_MSG returns which means we will not call set_state() + // to properly restore the thread state. That's likely wrong. + THROW_MSG(vmSymbols::java_lang_InterruptedException(), "sleep interrupted"); + } } } thread->osthread()->set_state(old_state); diff --git a/src/hotspot/share/runtime/javaThread.cpp b/src/hotspot/share/runtime/javaThread.cpp index b84cf6e901113..3d9421fc94c78 100644 --- a/src/hotspot/share/runtime/javaThread.cpp +++ b/src/hotspot/share/runtime/javaThread.cpp @@ -1146,7 +1146,6 @@ void JavaThread::install_async_exception(AsyncExceptionHandshakeClosure* aehc) { oop vt_oop = vthread(); if (vt_oop == nullptr || !vt_oop->is_a(vmClasses::BaseVirtualThread_klass())) { // Interrupt thread so it will wake up from a potential wait()/sleep()/park() - java_lang_Thread::set_interrupted(threadObj(), true); this->interrupt(); } } @@ -2098,7 +2097,7 @@ bool JavaThread::sleep(jlong millis) { // java.lang.Thread.sleep support // Returns true if sleep time elapsed as expected, and false -// if the thread was interrupted. +// if the thread was interrupted or async exception was installed. bool JavaThread::sleep_nanos(jlong nanos) { assert(this == Thread::current(), "thread consistency check"); assert(nanos >= 0, "nanos are in range"); @@ -2118,6 +2117,9 @@ bool JavaThread::sleep_nanos(jlong nanos) { jlong nanos_remaining = nanos; for (;;) { + if (has_async_exception_condition()) { + return false; + } // interruption has precedence over timing out if (this->is_interrupted(true)) { return false; diff --git a/test/hotspot/jtreg/serviceability/jvmti/vthread/StopThreadTest/StopThreadTest.java b/test/hotspot/jtreg/serviceability/jvmti/vthread/StopThreadTest/StopThreadTest.java index 4693040fa6b11..e130c3c7e6bef 100644 --- a/test/hotspot/jtreg/serviceability/jvmti/vthread/StopThreadTest/StopThreadTest.java +++ b/test/hotspot/jtreg/serviceability/jvmti/vthread/StopThreadTest/StopThreadTest.java @@ -211,7 +211,6 @@ public void run() { log("TestTask.run: caught expected AssertionError from method A()"); seenExceptionFromA = true; } - Thread.interrupted(); if (!seenExceptionFromA && !preemptableVirtualThread()) { StopThreadTest.setFailed("TestTask.run: expected AssertionError from method A()"); } @@ -224,7 +223,6 @@ public void run() { log("TestTask.run: caught expected AssertionError from method B()"); seenExceptionFromB = true; } - Thread.interrupted(); if (!seenExceptionFromB) { StopThreadTest.setFailed("TestTask.run: expected AssertionError from method B()"); } @@ -237,7 +235,6 @@ public void run() { log("TestTask.run: caught expected AssertionError from method C()"); seenExceptionFromC = true; } - Thread.interrupted(); if (!seenExceptionFromC) { StopThreadTest.setFailed("TestTask.run: expected AssertionError from method C()"); }