Top


定義場所(file name)

hotspot/src/share/vm/prims/jvm.cpp

説明(description)

// JVM_Stop is implemented using a VM_Operation, so threads are forced to safepoints
// before the quasi-asynchronous exception is delivered.  This is a little obtrusive,
// but is thought to be reliable and simple. In the case, where the receiver is the
// same thread as the sender, no safepoint is needed.

名前(function name)

JVM_ENTRY(void, JVM_StopThread(JNIEnv* env, jobject jthread, jobject throwable))

本体部(body)

  {- -------------------------------------------
  (1) (トレース出力) (See: JVMWrapper)
      ---------------------------------------- -}

      JVMWrapper("JVM_StopThread");

  {- -------------------------------------------
  (1) 引数が NULL だった場合は, NullPointerException
      ---------------------------------------- -}

      oop java_throwable = JNIHandles::resolve(throwable);
      if (java_throwable == NULL) {
        THROW(vmSymbols::java_lang_NullPointerException());
      }

  {- -------------------------------------------
  (1) (変数宣言など)
      ---------------------------------------- -}

      oop java_thread = JNIHandles::resolve_non_null(jthread);
      JavaThread* receiver = java_lang_Thread::thread(java_thread);

  {- -------------------------------------------
  (1) (デバッグ用の処理) (See: Events)
      ---------------------------------------- -}

      Events::log("JVM_StopThread thread JavaThread " INTPTR_FORMAT " as oop " INTPTR_FORMAT " [exception " INTPTR_FORMAT "]", receiver, (address)java_thread, throwable);

  {- -------------------------------------------
  (1) 以下のようにして処理対象を停止させる(処理対象のスレッド内で例外を引き起こす).
      * 処理対象がいない場合 (まだ開始していない or もう死んでいる)
        まだ開始していないケースのために, java_lang_Thread::set_stillborn() を呼んでおく.
        (これを呼ばれたスレッドは, java.lang.Thread.run() メソッドの中身を実行することなく終了する.
         See: JavaThread::thread_main_inner())
        (当たり前だけど, もう死んでいるケースについては何も対処することはない.)
      * 処理対象が自分自身の場合
        THROW_OOP() マクロで, 引数で指定された例外(java_throwable)を投げるだけ.
      * 処理対象が自分以外の場合
        Thread::send_async_exception() を呼んで, 対象のスレッド内に
        引数で指定された例外(throwable)を発生させる.
      ---------------------------------------- -}

      // First check if thread is alive
      if (receiver != NULL) {
        // Check if exception is getting thrown at self (use oop equality, since the
        // target object might exit)
        if (java_thread == thread->threadObj()) {
          THROW_OOP(java_throwable);
        } else {
          // Enques a VM_Operation to stop all threads and then deliver the exception...
          Thread::send_async_exception(java_thread, JNIHandles::resolve(throwable));
        }
      }
      else {
        // Either:
        // - target thread has not been started before being stopped, or
        // - target thread already terminated
        // We could read the threadStatus to determine which case it is
        // but that is overkill as it doesn't matter. We must set the
        // stillborn flag for the first case, and if the thread has already
        // exited setting this flag has no affect
        java_lang_Thread::set_stillborn(java_thread);
      }
    JVM_END

This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.