< prev index next >

src/hotspot/share/runtime/thread.cpp

Print this page

        

@@ -2270,44 +2270,27 @@
   // thread is not the current thread. In older versions of jdbx, jdbx
   // threads could call into the VM with another thread's JNIEnv so we
   // can be here operating on behalf of a suspended thread (4432884).
   bool do_self_suspend = is_external_suspend_with_lock();
   if (do_self_suspend && (!AllowJNIEnvProxy || this == JavaThread::current())) {
-    //
-    // Because thread is external suspended the safepoint code will count
-    // thread as at a safepoint. This can be odd because we can be here
-    // as _thread_in_Java which would normally transition to _thread_blocked
-    // at a safepoint. We would like to mark the thread as _thread_blocked
-    // before calling java_suspend_self like all other callers of it but
-    // we must then observe proper safepoint protocol. (We can't leave
-    // _thread_blocked with a safepoint in progress). However we can be
-    // here as _thread_in_native_trans so we can't use a normal transition
-    // constructor/destructor pair because they assert on that type of
-    // transition. We could do something like:
-    //
-    // JavaThreadState state = thread_state();
-    // set_thread_state(_thread_in_vm);
-    // {
-    //   ThreadBlockInVM tbivm(this);
-    //   java_suspend_self()
-    // }
-    // set_thread_state(_thread_in_vm_trans);
-    // if (safepoint) block;
-    // set_thread_state(state);
-    //
-    // but that is pretty messy. Instead we just go with the way the
-    // code has worked before and note that this is the only path to
-    // java_suspend_self that doesn't put the thread in _thread_blocked
-    // mode.
-
     frame_anchor()->make_walkable(this);
+
+    // Because this thread is external suspended the safepoint code will
+    // count it as at a safepoint, regardless of what it's actual current
+    // thread-state is. But is_ext_suspend_completed() is waiting to see
+    // a thread transition from _thread_in_native_trans to _thread_blocked.
+    // So we simply set the thread directly to _thread_blocked before calling
+    // java_suspend_self(). This is consistent with what we do in
+    // check_safepoint_and_suspend_for_native_trans.
+    JavaThreadState state = thread_state();
+    set_thread_state(_thread_blocked);
     java_suspend_self();
+    set_thread_state(state);
+  }
 
     // We might be here for reasons in addition to the self-suspend request
     // so check for other async requests.
-  }
-
   if (check_asyncs) {
     check_and_handle_async_exceptions();
   }
 
   JFR_ONLY(SUSPEND_THREAD_CONDITIONAL(this);)

@@ -2422,10 +2405,11 @@
 //       thread. java_suspend_self() is the second stage of cooperative
 //       suspension for external suspend requests and should only be used
 //       to complete an external suspend request.
 //
 int JavaThread::java_suspend_self() {
+  assert(thread_state() == _thread_blocked, "wrong state for java_suspend_self()");
   int ret = 0;
 
   // we are in the process of exiting so don't suspend
   if (is_exiting()) {
     clear_external_suspend();
< prev index next >