comparison src/share/vm/prims/jvm.cpp @ 2162:ccfcb502af3f

6566340: Restore use of stillborn flag to signify a thread that was stopped before it started Summary: Restore use of stillborn flag Reviewed-by: acorn, alanb
author dholmes
date Tue, 25 Jan 2011 00:14:21 -0500
parents 828eafbd85cc
children 3582bf76420e
comparison
equal deleted inserted replaced
2157:d535bf4c1235 2162:ccfcb502af3f
1 /* 1 /*
2 * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. 2 * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 * 4 *
5 * This code is free software; you can redistribute it and/or modify it 5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as 6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
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))