changeset 57104:9170826a3d76

8234613: JavaThread can escape back to Java from an ongoing handshake Summary: Check again if we have a pending/in-progress handshake operation after executing ~ThreadInVMForHandshake() Reviewed-by: coleenp, dcubed, dholmes, rehn
author pchilanomate
date Tue, 26 Nov 2019 15:21:37 +0000
parents d5a1c6545a2b
children eb3e2a5c2bcd
files src/hotspot/share/runtime/handshake.cpp
diffstat 1 files changed, 17 insertions(+), 13 deletions(-) [+]
line wrap: on
line diff
--- a/src/hotspot/share/runtime/handshake.cpp	Tue Nov 26 14:48:04 2019 +0100
+++ b/src/hotspot/share/runtime/handshake.cpp	Tue Nov 26 15:21:37 2019 +0000
@@ -289,20 +289,24 @@
 void HandshakeState::process_self_inner(JavaThread* thread) {
   assert(Thread::current() == thread, "should call from thread");
   assert(!thread->is_terminated(), "should not be a terminated thread");
+  assert(thread->thread_state() != _thread_blocked, "should not be in a blocked state");
+  assert(thread->thread_state() != _thread_in_native, "should not be in native");
 
-  ThreadInVMForHandshake tivm(thread);
-  if (!_semaphore.trywait()) {
-    _semaphore.wait_with_safepoint_check(thread);
-  }
-  HandshakeOperation* op = Atomic::load_acquire(&_operation);
-  if (op != NULL) {
-    HandleMark hm(thread);
-    CautiouslyPreserveExceptionMark pem(thread);
-    // Disarm before execute the operation
-    clear_handshake(thread);
-    op->do_handshake(thread);
-  }
-  _semaphore.signal();
+  do {
+    ThreadInVMForHandshake tivm(thread);
+    if (!_semaphore.trywait()) {
+      _semaphore.wait_with_safepoint_check(thread);
+    }
+    HandshakeOperation* op = Atomic::load_acquire(&_operation);
+    if (op != NULL) {
+      HandleMark hm(thread);
+      CautiouslyPreserveExceptionMark pem(thread);
+      // Disarm before execute the operation
+      clear_handshake(thread);
+      op->do_handshake(thread);
+    }
+    _semaphore.signal();
+  } while (has_operation());
 }
 
 bool HandshakeState::vmthread_can_process_handshake(JavaThread* target) {