2649 { |
2649 { |
2650 // Ensure that the C++ Thread and OSThread structures aren't freed before |
2650 // Ensure that the C++ Thread and OSThread structures aren't freed before |
2651 // we operate. |
2651 // we operate. |
2652 MutexLocker mu(Threads_lock); |
2652 MutexLocker mu(Threads_lock); |
2653 |
2653 |
2654 // Check to see if we're running a thread that's already exited or was |
2654 // Since JDK 5 the java.lang.Thread threadStatus is used to prevent |
2655 // stopped (is_stillborn) or is still active (thread is not NULL). |
2655 // re-starting an already started thread, so we should usually find |
2656 if (java_lang_Thread::is_stillborn(JNIHandles::resolve_non_null(jthread)) || |
2656 // that the JavaThread is null. However for a JNI attached thread |
2657 java_lang_Thread::thread(JNIHandles::resolve_non_null(jthread)) != NULL) { |
2657 // there is a small window between the Thread object being created |
2658 throw_illegal_thread_state = true; |
2658 // (with its JavaThread set) and the update to its threadStatus, so we |
|
2659 // have to check for this |
|
2660 if (java_lang_Thread::thread(JNIHandles::resolve_non_null(jthread)) != NULL) { |
|
2661 throw_illegal_thread_state = true; |
2659 } else { |
2662 } else { |
|
2663 // We could also check the stillborn flag to see if this thread was already stopped, but |
|
2664 // for historical reasons we let the thread detect that itself when it starts running |
|
2665 |
2660 jlong size = |
2666 jlong size = |
2661 java_lang_Thread::stackSize(JNIHandles::resolve_non_null(jthread)); |
2667 java_lang_Thread::stackSize(JNIHandles::resolve_non_null(jthread)); |
2662 // Allocate the C++ Thread structure and create the native thread. The |
2668 // Allocate the C++ Thread structure and create the native thread. The |
2663 // stack size retrieved from java is signed, but the constructor takes |
2669 // stack size retrieved from java is signed, but the constructor takes |
2664 // size_t (an unsigned type), so avoid passing negative values which would |
2670 // size_t (an unsigned type), so avoid passing negative values which would |
2702 JVM_END |
2708 JVM_END |
2703 |
2709 |
2704 // JVM_Stop is implemented using a VM_Operation, so threads are forced to safepoints |
2710 // JVM_Stop is implemented using a VM_Operation, so threads are forced to safepoints |
2705 // before the quasi-asynchronous exception is delivered. This is a little obtrusive, |
2711 // before the quasi-asynchronous exception is delivered. This is a little obtrusive, |
2706 // but is thought to be reliable and simple. In the case, where the receiver is the |
2712 // but is thought to be reliable and simple. In the case, where the receiver is the |
2707 // save thread as the sender, no safepoint is needed. |
2713 // same thread as the sender, no safepoint is needed. |
2708 JVM_ENTRY(void, JVM_StopThread(JNIEnv* env, jobject jthread, jobject throwable)) |
2714 JVM_ENTRY(void, JVM_StopThread(JNIEnv* env, jobject jthread, jobject throwable)) |
2709 JVMWrapper("JVM_StopThread"); |
2715 JVMWrapper("JVM_StopThread"); |
2710 |
2716 |
2711 oop java_throwable = JNIHandles::resolve(throwable); |
2717 oop java_throwable = JNIHandles::resolve(throwable); |
2712 if (java_throwable == NULL) { |
2718 if (java_throwable == NULL) { |
2713 THROW(vmSymbols::java_lang_NullPointerException()); |
2719 THROW(vmSymbols::java_lang_NullPointerException()); |
2714 } |
2720 } |
2715 oop java_thread = JNIHandles::resolve_non_null(jthread); |
2721 oop java_thread = JNIHandles::resolve_non_null(jthread); |
2716 JavaThread* receiver = java_lang_Thread::thread(java_thread); |
2722 JavaThread* receiver = java_lang_Thread::thread(java_thread); |
2717 Events::log("JVM_StopThread thread JavaThread " INTPTR_FORMAT " as oop " INTPTR_FORMAT " [exception " INTPTR_FORMAT "]", receiver, (address)java_thread, throwable); |
2723 Events::log("JVM_StopThread thread JavaThread " INTPTR_FORMAT " as oop " INTPTR_FORMAT " [exception " INTPTR_FORMAT "]", receiver, (address)java_thread, throwable); |
2718 // First check if thread already exited |
2724 // First check if thread is alive |
2719 if (receiver != NULL) { |
2725 if (receiver != NULL) { |
2720 // Check if exception is getting thrown at self (use oop equality, since the |
2726 // Check if exception is getting thrown at self (use oop equality, since the |
2721 // target object might exit) |
2727 // target object might exit) |
2722 if (java_thread == thread->threadObj()) { |
2728 if (java_thread == thread->threadObj()) { |
2723 // This is a change from JDK 1.1, but JDK 1.2 will also do it: |
|
2724 // NOTE (from JDK 1.2): this is done solely to prevent stopped |
|
2725 // threads from being restarted. |
|
2726 // Fix for 4314342, 4145910, perhaps others: it now doesn't have |
|
2727 // any effect on the "liveness" of a thread; see |
|
2728 // JVM_IsThreadAlive, below. |
|
2729 if (java_throwable->is_a(SystemDictionary::ThreadDeath_klass())) { |
|
2730 java_lang_Thread::set_stillborn(java_thread); |
|
2731 } |
|
2732 THROW_OOP(java_throwable); |
2729 THROW_OOP(java_throwable); |
2733 } else { |
2730 } else { |
2734 // Enques a VM_Operation to stop all threads and then deliver the exception... |
2731 // Enques a VM_Operation to stop all threads and then deliver the exception... |
2735 Thread::send_async_exception(java_thread, JNIHandles::resolve(throwable)); |
2732 Thread::send_async_exception(java_thread, JNIHandles::resolve(throwable)); |
2736 } |
2733 } |
|
2734 } |
|
2735 else { |
|
2736 // Either: |
|
2737 // - target thread has not been started before being stopped, or |
|
2738 // - target thread already terminated |
|
2739 // We could read the threadStatus to determine which case it is |
|
2740 // but that is overkill as it doesn't matter. We must set the |
|
2741 // stillborn flag for the first case, and if the thread has already |
|
2742 // exited setting this flag has no affect |
|
2743 java_lang_Thread::set_stillborn(java_thread); |
2737 } |
2744 } |
2738 JVM_END |
2745 JVM_END |
2739 |
2746 |
2740 |
2747 |
2741 JVM_ENTRY(jboolean, JVM_IsThreadAlive(JNIEnv* env, jobject jthread)) |
2748 JVM_ENTRY(jboolean, JVM_IsThreadAlive(JNIEnv* env, jobject jthread)) |