hotspot/src/os/bsd/vm/os_bsd.cpp
changeset 40377 b77bf599c11b
parent 40010 e32d5e545789
child 40655 9f644073d3a0
--- a/hotspot/src/os/bsd/vm/os_bsd.cpp	Thu Aug 11 16:22:08 2016 -0700
+++ b/hotspot/src/os/bsd/vm/os_bsd.cpp	Fri Aug 12 00:19:44 2016 -0400
@@ -2716,7 +2716,8 @@
 //      - 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,9 +2747,22 @@
   // after sigsuspend.
   int old_errno = errno;
 
-  Thread* thread = Thread::current();
+  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();
-  assert(thread->is_VM_thread() || thread->is_Java_thread(), "Must be VMThread or JavaThread");
 
   os::SuspendResume::State current = osthread->sr.state();
   if (current == os::SuspendResume::SR_SUSPEND_REQUEST) {