< prev index next >

src/hotspot/share/runtime/thread.cpp

Print this page

        

*** 2270,2313 **** // 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); java_suspend_self(); // 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);) --- 2270,2296 ---- // 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())) { 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,2431 **** --- 2405,2415 ---- // 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 >