You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by gs...@apache.org on 2007/05/23 23:14:45 UTC
svn commit: r541084 - in /harmony/enhanced/drlvm/trunk:
src/test/regression/H3894/ src/test/regression/excludes/
vm/vmcore/src/jvmti/ vm/vmcore/src/kernel_classes/javasrc/java/lang/
Author: gshimansky
Date: Wed May 23 14:14:44 2007
New Revision: 541084
URL: http://svn.apache.org/viewvc?view=rev&rev=541084
Log:
Applied patch and regression test from HARMONY-3894 [drlvm][jvmti] JVMTI function GetThreadGroupChildren() return no more than 10 child threds and groups
Added:
harmony/enhanced/drlvm/trunk/src/test/regression/H3894/
harmony/enhanced/drlvm/trunk/src/test/regression/H3894/ThreadGroupChildren.cpp (with props)
harmony/enhanced/drlvm/trunk/src/test/regression/H3894/ThreadGroupChildren.java (with props)
harmony/enhanced/drlvm/trunk/src/test/regression/H3894/run.test.xml (with props)
Modified:
harmony/enhanced/drlvm/trunk/src/test/regression/excludes/exclude.linux.x86_64
harmony/enhanced/drlvm/trunk/src/test/regression/excludes/exclude.windows.x86_64
harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_thread_group.cpp
harmony/enhanced/drlvm/trunk/vm/vmcore/src/kernel_classes/javasrc/java/lang/ThreadGroup.java
Added: harmony/enhanced/drlvm/trunk/src/test/regression/H3894/ThreadGroupChildren.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/src/test/regression/H3894/ThreadGroupChildren.cpp?view=auto&rev=541084
==============================================================================
--- harmony/enhanced/drlvm/trunk/src/test/regression/H3894/ThreadGroupChildren.cpp (added)
+++ harmony/enhanced/drlvm/trunk/src/test/regression/H3894/ThreadGroupChildren.cpp Wed May 23 14:14:44 2007
@@ -0,0 +1,253 @@
+/**
+ * Test case for GetThreadGroupChildren() jvmti function.
+ * Checks that the function may report more than 10 child theads.
+ * Checks that the function reports the same thread group children that were
+ * added by java application.
+ */
+
+#include <iostream>
+#include <jvmti.h>
+
+using namespace std;
+
+#define PACKAGE "org/apache/harmony/drlvm/tests/regression/h3894/"
+
+static const char* EXCEPTION_CLASS = "L" PACKAGE "InvokeAgentException;";
+
+#define TURN_EVENT(event, state) { \
+ jvmtiError err = turn_event(jvmti, event, state, #event); \
+ if (JVMTI_ERROR_NONE != err) return; \
+}
+
+#define CHECK_RESULT(func) \
+ if (JVMTI_ERROR_NONE != err) { \
+ cerr << "[JvmtiAgent] ERROR: " << #func << " failed with error: " << err << endl; \
+ return; \
+ }
+
+#define CHECK_JNI3(result, func, error_code) { \
+ if (jni->ExceptionCheck()) { \
+ cerr << "[JvmtiAgent] ERROR: unexpected exception in " << #func << endl; \
+ jni->ExceptionDescribe(); \
+ return error_code; \
+ } \
+ if (! (result)) { \
+ cerr << "[JvmtiAgent] ERROR: get NULL in " << #func << endl; \
+ return error_code; \
+ } \
+}
+
+#define CHECK_JNI(result, func) CHECK_JNI3(result, func, )
+
+static void set_passed_state(JNIEnv* jni)
+{
+ cerr << endl << "TEST PASSED" << endl << endl;
+
+ jclass cl = jni->FindClass(PACKAGE "Status");
+ CHECK_JNI(cl, FindClass);
+
+ jfieldID testGroup_field = jni->GetStaticFieldID(cl, "status", "Z");
+ CHECK_JNI(testGroup_field, GetStaticFieldID);
+
+ jni->SetStaticBooleanField(cl, testGroup_field, JNI_TRUE);
+ CHECK_JNI(true, SetStaticBooleanField);
+}
+
+static jvmtiError turn_event(jvmtiEnv* jvmti, jvmtiEvent event, bool state,
+ const char* event_name)
+{
+ jvmtiError err;
+ err = jvmti->SetEventNotificationMode(state ? JVMTI_ENABLE : JVMTI_DISABLE,
+ event, NULL);
+ if (JVMTI_ERROR_NONE != err) {
+ cerr << "[JvmtiAgent] ERROR: unable to " << (state ? "en" : "dis")
+ << "able " << event_name
+ << endl;
+ }
+
+ return err;
+}
+
+static void JNICALL VMInit(jvmtiEnv* jvmti, JNIEnv* jni, jthread thread)
+{
+ cerr << endl << "==> VM Init callback" << endl;
+
+ TURN_EVENT(JVMTI_EVENT_EXCEPTION, true);
+}
+
+static bool check_array(jvmtiEnv* jvmti,
+ JNIEnv* jni,
+ jobject* array,
+ int array_length,
+ jobject object,
+ jclass clazz,
+ const char* field_name,
+ const char* field_sig)
+{
+ jfieldID field = jni->GetFieldID(clazz, field_name, field_sig);
+ CHECK_JNI3(field, GetFieldID, false);
+
+ jobjectArray expected = jni->GetObjectField(object, field);
+ CHECK_JNI3(expected, GetObjectField, false);
+
+ jint expected_length = jni->GetArrayLength(expected);
+ CHECK_JNI3(expected_length, GetArrayLength, false);
+
+ cerr << "Array length: \t" << array_length << endl
+ << "Expected length:\t" << expected_length << endl;
+
+ if (array_length != expected_length) {
+ cerr << "Array length doesn't match expected" << endl;
+ return false;
+ }
+
+ for (jint j = 0; j < expected_length; j++) {
+ jobject entry = jni->GetObjectArrayElement(expected, j);
+ CHECK_JNI3(entry, GetObjectArrayElement, false);
+
+ bool found = false;
+ for (int i = 0; i < array_length; i++) {
+ jboolean is_same = jni->IsSameObject(entry, array[i]);
+ CHECK_JNI3(true, IsSameObject, false);
+
+ if (is_same)
+ found = ! found;
+ }
+
+ if (! found) {
+ cerr << "Expected element not found" << endl;
+ return false;
+ }
+
+ }
+
+ return true;
+
+}
+
+static void JNICALL
+Exception(jvmtiEnv *jvmti,
+ JNIEnv* jni,
+ jthread thread,
+ jmethodID method,
+ jlocation location,
+ jobject exception,
+ jmethodID catch_method,
+ jlocation catch_location)
+{
+ jvmtiError err;
+
+ jclass exn_class = jni->GetObjectClass(exception);
+ CHECK_JNI(exn_class, GetObjectClass);
+
+ char* class_name = NULL;
+ err = jvmti->GetClassSignature(exn_class, &class_name, NULL);
+ CHECK_RESULT(GetClassSignature);
+
+ if (0 != strcmp(EXCEPTION_CLASS, class_name))
+ return;
+
+ cerr << endl << "==> Exception callback" << endl;
+ cerr << " for class: " << class_name << endl;
+
+ TURN_EVENT(JVMTI_EVENT_EXCEPTION, false);
+
+ jfieldID testGroup_field = jni->GetFieldID(exn_class, "testGroup",
+ "Ljava/lang/ThreadGroup;");
+ CHECK_JNI(testGroup_field, GetFieldID);
+
+ jthreadGroup group = jni->GetObjectField(exception, testGroup_field);
+ CHECK_JNI(group, GetObjectField);
+
+ jint thread_count;
+ jthread* threads;
+ jint group_count;
+ jthreadGroup* groups;
+
+ err = jvmti->GetThreadGroupChildren(group, &thread_count, &threads,
+ &group_count, &groups);
+ CHECK_RESULT(GetThreadGroupChildren);
+
+ cerr << endl << "Child threads:" << endl;
+ for (int i = 0; i < thread_count; i++) {
+ jvmtiThreadInfo info;
+
+ err = jvmti->GetThreadInfo(threads[i], &info);
+ CHECK_RESULT(GetThreadInfo);
+
+ cerr << i << ":\t" << info.name << endl;
+ }
+
+ cerr << endl << "Child groups:" << endl;
+ for (int i = 0; i < group_count; i++) {
+ jvmtiThreadGroupInfo info;
+
+ err = jvmti->GetThreadGroupInfo(groups[i], &info);
+ CHECK_RESULT(GetThreadDroupInfo);
+
+ cerr << i << ":\t" << info.name << endl;
+ }
+
+ cerr << endl << "Checking threads..." << endl;
+ if (! check_array(jvmti, jni, threads, thread_count, exception, exn_class,
+ "childThreads", "[Ljava/lang/Thread;")) {
+ return;
+ }
+
+ cerr << endl << "Checking groups..." << endl;
+ if (! check_array(jvmti, jni, groups, group_count, exception, exn_class,
+ "childGroups", "[Ljava/lang/ThreadGroup;")) {
+ return;
+ }
+
+
+ set_passed_state(jni);
+}
+
+JNIEXPORT jint JNICALL Agent_OnLoad(JavaVM *vm, char *options, void *reserved)
+{
+ jvmtiEnv *jvmti = NULL;
+ jvmtiError err;
+
+ // Get JVMTI interface pointer
+ jint iRes = vm->GetEnv((void**)&jvmti, JVMTI_VERSION);
+ if (JNI_OK != iRes) {
+ cerr << "[JvmtiAgent] ERROR: unable to get JVMTI environment" << endl;
+ return -1;
+ }
+
+ // Set events callbacks
+ jvmtiEventCallbacks callbacks;
+ memset(&callbacks, 0, sizeof(jvmtiEventCallbacks));
+
+ callbacks.VMInit = VMInit;
+ callbacks.Exception = Exception;
+
+ err = jvmti->SetEventCallbacks(&callbacks, sizeof(jvmtiEventCallbacks));
+ if (JVMTI_ERROR_NONE != err) {
+ cerr << "[JvmtiAgent] ERROR: unable to register event callbacks" << endl;
+ return -1;
+ }
+
+ err = jvmti->SetEventNotificationMode(JVMTI_ENABLE,
+ JVMTI_EVENT_VM_INIT, NULL);
+ if (JVMTI_ERROR_NONE != err) {
+ cerr << "[JvmtiAgent] ERROR: unable to enable VMInit event"
+ << endl;
+ return -1;
+ }
+
+ // Set capabilities
+ jvmtiCapabilities capabilities;
+ memset(&capabilities, 0, sizeof(jvmtiCapabilities));
+ capabilities.can_generate_exception_events = 1;
+
+ err = jvmti->AddCapabilities(&capabilities);
+ if (JVMTI_ERROR_NONE != err) {
+ cerr << "[JvmtiAgent] ERROR: unable to possess capabilities" << endl;
+ return -1;
+ }
+
+ // Agent initialized successfully
+ return 0;
+}
Propchange: harmony/enhanced/drlvm/trunk/src/test/regression/H3894/ThreadGroupChildren.cpp
------------------------------------------------------------------------------
svn:eol-style = native
Added: harmony/enhanced/drlvm/trunk/src/test/regression/H3894/ThreadGroupChildren.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/src/test/regression/H3894/ThreadGroupChildren.java?view=auto&rev=541084
==============================================================================
--- harmony/enhanced/drlvm/trunk/src/test/regression/H3894/ThreadGroupChildren.java (added)
+++ harmony/enhanced/drlvm/trunk/src/test/regression/H3894/ThreadGroupChildren.java Wed May 23 14:14:44 2007
@@ -0,0 +1,139 @@
+package org.apache.harmony.drlvm.tests.regression.h3894;
+
+import junit.framework.TestCase;
+import java.util.HashSet;
+
+/**
+ * Test case for GetThreadGroupChildren() jvmti function.
+ * Checks that the function may report more than 10 child theads.
+ * Checks that the function reports the same thread group children that were
+ * added by java application.
+ * Checks that not started threads are not reported.
+ * Checks that grand children are not reported.
+ */
+public class ThreadGroupChildren extends TestCase {
+
+ static final int CHILD_THREADS = 15;
+ static final int NOT_STARTED_CHILD_THREADS = 2;
+ static final int CHILD_GROUPS = 15;
+ static final int EMPTY_CHILD_GROUPS = 2;
+ static final int GRAND_CHILD_THREADS = 2;
+ static final int GRAND_CHILD_GROUPS = 2;
+
+ public static void main(String args[]) {
+ (new ThreadGroupChildren()).test();
+ }
+
+ public void test() {
+ // this collection should hold references to created Thead and
+ // ThreadGroup objects to avoid their elimination by garbage collector
+ HashSet<Object> set = new HashSet<Object>();
+
+ ThreadGroup testGroup = new ThreadGroup("test group");
+
+ Thread[] childThreads = new Thread[CHILD_THREADS];
+
+ for (int i = 0; i < CHILD_THREADS; i++) {
+ Thread thread = new TestThread(testGroup, "child thread " + i);
+ childThreads[i] = thread;
+ set.add(thread);
+ thread.start();
+ }
+
+ for (int i = 0; i < NOT_STARTED_CHILD_THREADS; i++) {
+ Thread thread = new TestThread(testGroup,
+ "not started child thread " + i);
+ set.add(thread);
+ }
+
+ ThreadGroup[] childGroups = new ThreadGroup[CHILD_GROUPS +
+ EMPTY_CHILD_GROUPS];
+ int childGroupsIndex = 0;
+
+ for (int i = 0; i < EMPTY_CHILD_GROUPS; i++) {
+ ThreadGroup group = new ThreadGroup(testGroup, "empty child group "
+ + i);
+ childGroups[childGroupsIndex ++] = group;
+ set.add(group);
+ }
+
+ for (int i = 0; i < CHILD_GROUPS; i++) {
+ ThreadGroup group = new ThreadGroup(testGroup, "child group " + i);
+ childGroups[childGroupsIndex ++] = group;
+ set.add(group);
+
+ for (int j = 0; j < GRAND_CHILD_THREADS; j++) {
+ Thread thread = new TestThread(group, "grand child thread "
+ + j);
+ set.add(thread);
+ thread.start();
+ }
+
+ for (int j = 0; j < GRAND_CHILD_GROUPS; j++) {
+ ThreadGroup subGroup = new ThreadGroup(group,
+ "empty grand child group " + j);
+ set.add(subGroup);
+ }
+ }
+
+ try {
+ System.err.println("[Java]: Throwing an exception");
+ // pass execution to the agent
+ throw new InvokeAgentException(testGroup, childThreads,
+ childGroups);
+ } catch (Exception e) {
+ System.err.println("[Java]: Exception caught");
+ }
+
+ synchronized (TestThread.class) {
+ try {
+ TestThread.class.notifyAll();
+ } catch (Throwable exc) {
+ exc.printStackTrace();
+ }
+ }
+
+ System.err.println("[Java]: test done");
+ assertTrue(Status.status);
+ }
+}
+
+class TestThread extends Thread {
+
+ public TestThread(ThreadGroup group, String name) {
+ super(group, name);
+ }
+
+ public void run() {
+ System.err.println("Thread started: " + getName());
+
+ synchronized (TestThread.class) {
+ try {
+ TestThread.class.wait();
+ } catch (Throwable exc) {
+ exc.printStackTrace();
+ }
+ }
+
+ System.err.println("Thread finished: " + getName());
+ }
+}
+
+class InvokeAgentException extends Exception {
+
+ ThreadGroup testGroup;
+ Thread[] childThreads;
+ ThreadGroup[] childGroups;
+
+ InvokeAgentException(ThreadGroup group, Thread[] threads,
+ ThreadGroup[] groups) {
+ testGroup = group;
+ childThreads = threads;
+ childGroups = groups;
+ }
+}
+
+class Status {
+ /** the field should be modified by jvmti agent to determine test result. */
+ public static boolean status = false;
+}
Propchange: harmony/enhanced/drlvm/trunk/src/test/regression/H3894/ThreadGroupChildren.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: harmony/enhanced/drlvm/trunk/src/test/regression/H3894/run.test.xml
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/src/test/regression/H3894/run.test.xml?view=auto&rev=541084
==============================================================================
--- harmony/enhanced/drlvm/trunk/src/test/regression/H3894/run.test.xml (added)
+++ harmony/enhanced/drlvm/trunk/src/test/regression/H3894/run.test.xml Wed May 23 14:14:44 2007
@@ -0,0 +1,9 @@
+<project name="RUN HARMONY-3894 Regression Test">
+ <target name="run-test">
+ <!-- use special launcher for JVMTI tests -->
+ <run-jvmti-test
+ test="org.apache.harmony.drlvm.tests.regression.h3894.ThreadGroupChildren"
+ agent="ThreadGroupChildren"/>
+ </target>
+</project>
+
Propchange: harmony/enhanced/drlvm/trunk/src/test/regression/H3894/run.test.xml
------------------------------------------------------------------------------
svn:eol-style = native
Modified: harmony/enhanced/drlvm/trunk/src/test/regression/excludes/exclude.linux.x86_64
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/src/test/regression/excludes/exclude.linux.x86_64?view=diff&rev=541084&r1=541083&r2=541084
==============================================================================
--- harmony/enhanced/drlvm/trunk/src/test/regression/excludes/exclude.linux.x86_64 (original)
+++ harmony/enhanced/drlvm/trunk/src/test/regression/excludes/exclude.linux.x86_64 Wed May 23 14:14:44 2007
@@ -7,4 +7,6 @@
H3730
# Exclude this test because JVMTI is not implemented for x86_64 in JIT mode yet
H3698
+# Exclude this test because JVMTI is not implemented for x86_64 in JIT mode yet
+H3894
Modified: harmony/enhanced/drlvm/trunk/src/test/regression/excludes/exclude.windows.x86_64
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/src/test/regression/excludes/exclude.windows.x86_64?view=diff&rev=541084&r1=541083&r2=541084
==============================================================================
--- harmony/enhanced/drlvm/trunk/src/test/regression/excludes/exclude.windows.x86_64 (original)
+++ harmony/enhanced/drlvm/trunk/src/test/regression/excludes/exclude.windows.x86_64 Wed May 23 14:14:44 2007
@@ -4,4 +4,6 @@
H3730
# Exclude this test because JVMTI is not implemented for x86_64 in JIT mode yet
H3698
+# Exclude this test because JVMTI is not implemented for x86_64 in JIT mode yet
+H3894
Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_thread_group.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_thread_group.cpp?view=diff&rev=541084&r1=541083&r2=541084
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_thread_group.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_thread_group.cpp Wed May 23 14:14:44 2007
@@ -14,10 +14,10 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-/**
+/**
* @author Gregory Shimansky
* @version $Revision: 1.1.2.1.4.4 $
- */
+ */
/*
* JVMTI thread group APIO
*/
@@ -29,6 +29,7 @@
#include "cxxlog.h"
#include "suspend_checker.h"
#include "environment.h"
+#include "exceptions.h"
#include "Class.h"
#define jvmti_test_jenv (p_TLS_vmthread->jni_env)
@@ -148,6 +149,45 @@
return JVMTI_ERROR_NONE;
}
+/**
+ * This function extracts element specified by 'index' from 'pair' array.
+ * Extracted element assumed to be an jobjectArray and is converted to native
+ * array of jobject that is returned via 'array_ptr' ant 'count_ptr' args.
+ */
+static jvmtiError read_array(jvmtiEnv* env,
+ jobjectArray pair,
+ jint index,
+ jint* count_ptr,
+ jobject** array_ptr)
+{
+ jint count = 0;
+ jobjectArray object_array = NULL;
+
+ if (NULL != pair) {
+ object_array = jvmti_test_jenv->GetObjectArrayElement(pair, index);
+
+ if (NULL != object_array)
+ count = jvmti_test_jenv->GetArrayLength(object_array);
+ }
+
+ jvmtiError err;
+
+ jobject* native_array = NULL;
+ err = _allocate(sizeof(jobject) * count, (unsigned char**) &native_array);
+
+ if (JVMTI_ERROR_NONE != err)
+ return err;
+
+ for (int i = 0; i < count; i++)
+ native_array[i] = jvmti_test_jenv->
+ GetObjectArrayElement(object_array, i);
+
+ *count_ptr = count;
+ *array_ptr = native_array;
+
+ return JVMTI_ERROR_NONE;
+}
+
/*
* Get Thread Group Children
*
@@ -183,57 +223,38 @@
return JVMTI_ERROR_NULL_POINTER;
}
- ti->setLocallyDisabled();//-----------------------------------V
-
- jclass cl = GetObjectClass(jvmti_test_jenv, group);
- jobjectArray jg = jvmti_test_jenv -> NewObjectArray(10, cl, 0);
- jmethodID id = jvmti_test_jenv -> GetMethodID(cl, "enumerate","([Ljava/lang/ThreadGroup;)I");
- int cc = jvmti_test_jenv -> CallIntMethod (group, id, jg);
- jthreadGroup* groups = NULL;
- jvmtiError jvmti_error = _allocate(sizeof(jthreadGroup) * cc,
- (unsigned char **)&groups);
+ jclass thread_group_class = GetObjectClass(jvmti_test_jenv, group);
+ jmethodID method = jvmti_test_jenv -> GetMethodID(thread_group_class,
+ "getActiveChildren","()[Ljava/lang/Object;");
+ assert(method);
- if (JVMTI_ERROR_NONE != jvmti_error)
- {
-
- ti->setLocallyEnabled();//-----------------------------------^
- return jvmti_error;
- }
+ ti->setLocallyDisabled();//-----------------------------------V
- int i; // Visual C++ 6.0 does not treat "for" as C++ scope
+ // by contract this method returns Object[2] array.
+ // First element is Object[] array of child Thread objects.
+ // Second element is Object[] array of child ThreadGroup objects.
+ jobjectArray result = jvmti_test_jenv->CallObjectMethod(group, method);
- for (i = 0; i < cc; i++)
- {
- groups[i] = jvmti_test_jenv -> GetObjectArrayElement(jg, i);
- }
+ ti->setLocallyEnabled();//-----------------------------------^
- *group_count_ptr = cc;
- *groups_ptr = groups;
+ if (exn_raised())
+ return JVMTI_ERROR_INTERNAL;
- jclass cll = struct_Class_to_java_lang_Class_Handle(VM_Global_State::loader_env->java_lang_Thread_Class);
- jobjectArray jt = jvmti_test_jenv -> NewObjectArray(10, cll, 0);
- id = jvmti_test_jenv -> GetMethodID(cl, "enumerate","([Ljava/lang/Thread;Z)I");
- cc = jvmti_test_jenv -> CallIntMethod (group, id, jt, JNI_FALSE);
+ jvmtiError err;
- ti->setLocallyEnabled();//-----------------------------------^
+ // extract child threads array
+ err = read_array(env, result, 0, thread_count_ptr, threads_ptr);
- jthread * threads = NULL;
- jvmti_error = _allocate(sizeof(jthread) * cc, (unsigned char **)&threads);
+ if (JVMTI_ERROR_NONE != err)
+ return err;
- if (JVMTI_ERROR_NONE != jvmti_error)
- {
- return jvmti_error;
- }
+ // extract child groups array
+ err = read_array(env, result, 1, group_count_ptr, groups_ptr);
- for (i = 0; i < cc; i++)
- {
- threads[i] = jvmti_test_jenv -> GetObjectArrayElement(jt, i);
+ if (JVMTI_ERROR_NONE != err) {
+ _deallocate((unsigned char*) *threads_ptr);
+ return err;
}
- *thread_count_ptr = cc;
- *threads_ptr = threads;
-
return JVMTI_ERROR_NONE;
-}
-
-
+} // jvmtiGetThreadGroupChildren
Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/kernel_classes/javasrc/java/lang/ThreadGroup.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/kernel_classes/javasrc/java/lang/ThreadGroup.java?view=diff&rev=541084&r1=541083&r2=541084
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/kernel_classes/javasrc/java/lang/ThreadGroup.java (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/kernel_classes/javasrc/java/lang/ThreadGroup.java Wed May 23 14:14:44 2007
@@ -22,13 +22,14 @@
package java.lang;
import java.util.List;
+import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Iterator;
import java.util.WeakHashMap;
import java.util.ConcurrentModificationException;
/**
- * @com.intel.drl.spec_ref
+ * @com.intel.drl.spec_ref
*/
public class ThreadGroup implements Thread.UncaughtExceptionHandler{
@@ -66,7 +67,7 @@
/**
* Parent thread group of this thread group.
*
- * FIXME: this field must be private. It is changed to package-private
+ * FIXME: this field must be private. It is changed to package-private
* to be accessible from FT SecurityManager class. Both SecurityManager
* and ThreadGroup are considered as non-Kernel by FT, but ThreadGroup
* is Kernel now in DRL.
@@ -125,13 +126,13 @@
threadsCopy = copyThreads();
groupsListCopy = (List)groups.clone();
}
-
+
for (int i = 0; i < threadsCopy.length; i++) {
if (((Thread) threadsCopy[i]).isAlive()) {
count++;
}
}
-
+
for (Iterator it = groupsListCopy.iterator(); it.hasNext();) {
count += ((ThreadGroup)it.next()).activeCount();
}
@@ -185,7 +186,7 @@
"The thread group " + name + " is already destroyed!");
}
if (!nonsecureDestroy()) {
- throw new IllegalThreadStateException("The thread group " + name +
+ throw new IllegalThreadStateException("The thread group " + name +
" is not empty");
} else {
if (parent != null) {
@@ -314,7 +315,7 @@
*/
public synchronized final void setMaxPriority(int priority) {
checkAccess();
-
+
/*
* GMJ : note that this is to match a known bug in the RI
* http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4708197
@@ -364,7 +365,7 @@
if(parent != null){
parent.uncaughtException(thread, throwable);
return;
- }
+ }
Thread.UncaughtExceptionHandler defaultHandler = Thread.getDefaultUncaughtExceptionHandler();
if(defaultHandler != null){
defaultHandler.uncaughtException(thread, throwable);
@@ -416,7 +417,7 @@
}
groups.add(group);
}
-
+
/**
* Copies this ThreadGroup's threads to an array which is used in iteration
* over threads because iteration over a WeakHashMap object can lead to
@@ -433,11 +434,46 @@
}
/**
+ * Used by GetThreadGroupChildren() jvmti function.
+ * @return Object[] array of 2 elements: first - Object[] array of active
+ * child threads; second - Object[] array of child groups.
+ */
+ private Object[] getActiveChildren() {
+ ArrayList<Thread> threadsCopy = new ArrayList<Thread>(threads.size());
+ ArrayList<ThreadGroup> groupsCopy = new ArrayList<ThreadGroup>(groups.size());
+
+ synchronized (this) {
+ if (destroyed) {
+ return new Object[] {null, null};
+ }
+
+ for (Thread thread : threads.keySet()) {
+ threadsCopy.add(thread);
+ }
+
+ for (ThreadGroup group : groups) {
+ groupsCopy.add(group);
+ }
+ }
+
+ ArrayList<Thread> activeThreads = new ArrayList<Thread>(threadsCopy.size());
+
+ // filter out alive threads
+ for (Thread thread : threadsCopy) {
+ if (thread.isAlive()) {
+ activeThreads.add(thread);
+ }
+ }
+
+ return new Object[] {activeThreads.toArray(), groupsCopy.toArray()};
+ }
+
+ /**
* Copies all the threads contained in the snapshot of this thread group to
* the array specified starting from the specified position. <br>
* If the specified array is not long enough to take all the threads of this
* thread group, the exta threads are silently ignored. <br>
- *
+ *
* @param list an array to copy threads to
* @param offset position in this array to start copying from
* @param recurse indicates if the threads contained in the subgroups of
@@ -480,7 +516,7 @@
* to the array specified starting from the specified position. <br>
* If the specified array is not long enough to take all the subgroups of
* this thread group, the exta subgroups are silently ignored. <br>
- *
+ *
* @param list an array to copy subgroups to
* @param offset position in this array to start copying from
* @param recurse indicates if the subgroups contained in the subgroups of
@@ -537,7 +573,7 @@
* Destroys this thread group without any security checks. We add this
* method to avoid calls to the checkAccess() method on subgroups.
* All non-empty subgroups are removed recursievely.
- * If at least one subgroup is not empty, IllegalThreadStateException
+ * If at least one subgroup is not empty, IllegalThreadStateException
* will be thrown.
* @return false if this ThreadGroup is not empty
*/
@@ -628,7 +664,7 @@
/**
* Removes the specified thread group from this group.
- *
+ *
* @param group group to be removed from this one
*/
private synchronized void remove(ThreadGroup group) {