< 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 >