8159461: bigapps/Kitchensink/stressExitCode hits assert: Must be VMThread or JavaThread

Reviewed-by: fparain, simonis, dcubed
This commit is contained in:
David Holmes 2016-08-12 00:19:44 -04:00
parent 19d25373bf
commit 74e840d64c
4 changed files with 54 additions and 10 deletions

View file

@ -2686,7 +2686,8 @@ void os::hint_no_preempt() {}
// - sets target osthread state to continue
// - sends signal to end the sigsuspend loop in the SR_handler
//
// Note that the SR_lock plays no role in this suspend/resume protocol.
// Note that the SR_lock plays no role in this suspend/resume protocol,
// but is checked for NULL in SR_handler as a thread termination indicator.
//
static void resume_clear_context(OSThread *osthread) {
@ -2718,10 +2719,23 @@ static void SR_handler(int sig, siginfo_t* siginfo, ucontext_t* context) {
// after sigsuspend.
int old_errno = errno;
Thread* thread = Thread::current();
OSThread* osthread = thread->osthread();
Thread* thread = Thread::current_or_null_safe();
assert(thread != NULL, "Missing current thread in SR_handler");
// On some systems we have seen signal delivery get "stuck" until the signal
// mask is changed as part of thread termination. Check that the current thread
// has not already terminated (via SR_lock()) - else the following assertion
// will fail because the thread is no longer a JavaThread as the ~JavaThread
// destructor has completed.
if (thread->SR_lock() == NULL) {
return;
}
assert(thread->is_VM_thread() || thread->is_Java_thread(), "Must be VMThread or JavaThread");
OSThread* osthread = thread->osthread();
os::SuspendResume::State current = osthread->sr.state();
if (current == os::SuspendResume::SR_SUSPEND_REQUEST) {
suspend_save_context(osthread, siginfo, context);

View file

@ -2716,7 +2716,8 @@ void os::hint_no_preempt() {}
// - sets target osthread state to continue
// - sends signal to end the sigsuspend loop in the SR_handler
//
// Note that the SR_lock plays no role in this suspend/resume protocol.
// Note that the SR_lock plays no role in this suspend/resume protocol,
// but is checked for NULL in SR_handler as a thread termination indicator.
static void resume_clear_context(OSThread *osthread) {
osthread->set_ucontext(NULL);
@ -2746,10 +2747,23 @@ static void SR_handler(int sig, siginfo_t* siginfo, ucontext_t* context) {
// after sigsuspend.
int old_errno = errno;
Thread* thread = Thread::current();
OSThread* osthread = thread->osthread();
Thread* thread = Thread::current_or_null_safe();
assert(thread != NULL, "Missing current thread in SR_handler");
// On some systems we have seen signal delivery get "stuck" until the signal
// mask is changed as part of thread termination. Check that the current thread
// has not already terminated (via SR_lock()) - else the following assertion
// will fail because the thread is no longer a JavaThread as the ~JavaThread
// destructor has completed.
if (thread->SR_lock() == NULL) {
return;
}
assert(thread->is_VM_thread() || thread->is_Java_thread(), "Must be VMThread or JavaThread");
OSThread* osthread = thread->osthread();
os::SuspendResume::State current = osthread->sr.state();
if (current == os::SuspendResume::SR_SUSPEND_REQUEST) {
suspend_save_context(osthread, siginfo, context);

View file

@ -3971,7 +3971,8 @@ void os::hint_no_preempt() {}
// - sets target osthread state to continue
// - sends signal to end the sigsuspend loop in the SR_handler
//
// Note that the SR_lock plays no role in this suspend/resume protocol.
// Note that the SR_lock plays no role in this suspend/resume protocol,
// but is checked for NULL in SR_handler as a thread termination indicator.
static void resume_clear_context(OSThread *osthread) {
osthread->set_ucontext(NULL);
@ -4004,9 +4005,21 @@ static void SR_handler(int sig, siginfo_t* siginfo, ucontext_t* context) {
Thread* thread = Thread::current_or_null_safe();
assert(thread != NULL, "Missing current thread in SR_handler");
OSThread* osthread = thread->osthread();
// On some systems we have seen signal delivery get "stuck" until the signal
// mask is changed as part of thread termination. Check that the current thread
// has not already terminated (via SR_lock()) - else the following assertion
// will fail because the thread is no longer a JavaThread as the ~JavaThread
// destructor has completed.
if (thread->SR_lock() == NULL) {
return;
}
assert(thread->is_VM_thread() || thread->is_Java_thread(), "Must be VMThread or JavaThread");
OSThread* osthread = thread->osthread();
os::SuspendResume::State current = osthread->sr.state();
if (current == os::SuspendResume::SR_SUSPEND_REQUEST) {
suspend_save_context(osthread, siginfo, context);

View file

@ -374,11 +374,14 @@ Thread::~Thread() {
delete handle_area();
delete metadata_handles();
// SR_handler uses this as a termination indicator -
// needs to happen before os::free_thread()
delete _SR_lock;
_SR_lock = NULL;
// osthread() can be NULL, if creation of thread failed.
if (osthread() != NULL) os::free_thread(osthread());
delete _SR_lock;
// clear Thread::current if thread is deleting itself.
// Needed to ensure JNI correctly detects non-attached threads.
if (this == Thread::current()) {