From 291ad36e620374518a4ac361aac914363c20f51c Mon Sep 17 00:00:00 2001 From: Keith Seitz Date: Mon, 25 Sep 2006 17:08:05 +0000 Subject: * gnu/classpath/jdwp/VMVirtualMachine.java (_jdwp_suspend_counts): New private variable. * gnu/classpath/jdwp/natVMVirtualMachine.cc (initialize): Initialize _jdwp_suspend_counts. (suspendThread): Implement. (resumeThread): Implement. (getSuspendCount): Implement. From-SVN: r117196 --- libjava/ChangeLog | 10 +++ libjava/gnu/classpath/jdwp/VMVirtualMachine.java | 4 + libjava/gnu/classpath/jdwp/natVMVirtualMachine.cc | 97 ++++++++++++++++++++++- 3 files changed, 110 insertions(+), 1 deletion(-) (limited to 'libjava') diff --git a/libjava/ChangeLog b/libjava/ChangeLog index 843e466..8c4662d6 100644 --- a/libjava/ChangeLog +++ b/libjava/ChangeLog @@ -1,3 +1,13 @@ +2006-09-25 Keith Seitz + + * gnu/classpath/jdwp/VMVirtualMachine.java + (_jdwp_suspend_counts): New private variable. + * gnu/classpath/jdwp/natVMVirtualMachine.cc + (initialize): Initialize _jdwp_suspend_counts. + (suspendThread): Implement. + (resumeThread): Implement. + (getSuspendCount): Implement. + 2006-09-22 Marco Trudel * jvmti.cc (_Jv_JVMTI_GetErrorName): Now static. Marked JNICALL. diff --git a/libjava/gnu/classpath/jdwp/VMVirtualMachine.java b/libjava/gnu/classpath/jdwp/VMVirtualMachine.java index 6da1d1d..5c4018f 100644 --- a/libjava/gnu/classpath/jdwp/VMVirtualMachine.java +++ b/libjava/gnu/classpath/jdwp/VMVirtualMachine.java @@ -48,6 +48,7 @@ import gnu.classpath.jdwp.util.MethodResult; import java.lang.reflect.Method; import java.nio.ByteBuffer; import java.util.ArrayList; +import java.util.Hashtable; import java.util.Iterator; /** @@ -57,6 +58,9 @@ import java.util.Iterator; */ public class VMVirtualMachine { + // Thread suspension table. Maps Thread to suspend count (Integer) + private static Hashtable _jdwp_suspend_counts; + public static native void initialize (); /** diff --git a/libjava/gnu/classpath/jdwp/natVMVirtualMachine.cc b/libjava/gnu/classpath/jdwp/natVMVirtualMachine.cc index b475c49..5e790b9 100644 --- a/libjava/gnu/classpath/jdwp/natVMVirtualMachine.cc +++ b/libjava/gnu/classpath/jdwp/natVMVirtualMachine.cc @@ -15,15 +15,20 @@ details. */ #include #include +#include +#include +#include #include #include #include +#include #include #include #include #include #include +#include #include using namespace java::lang; @@ -36,6 +41,7 @@ static jvmtiEnv *_jdwp_jvmtiEnv; void gnu::classpath::jdwp::VMVirtualMachine::initialize () { + _jdwp_suspend_counts = new ::java::util::Hashtable (); JavaVM *vm = _Jv_GetJavaVM (); vm->GetEnv (reinterpret_cast (&_jdwp_jvmtiEnv), JVMTI_VERSION_1_0); } @@ -43,17 +49,106 @@ gnu::classpath::jdwp::VMVirtualMachine::initialize () void gnu::classpath::jdwp::VMVirtualMachine ::suspendThread (Thread *thread) { + jint value; + Integer *count; + { + JvSynchronize dummy (_jdwp_suspend_counts); + count = reinterpret_cast (_jdwp_suspend_counts->get (thread)); + if (count == NULL) + { + // New -- suspend thread + value = 0; + } + else + { + // Thread already suspended + value = count->intValue (); + } + + count = Integer::valueOf (++value); + _jdwp_suspend_counts->put (thread, count); + } + + if (value == 1) + { + // Suspend the thread + jvmtiError err = _jdwp_jvmtiEnv->SuspendThread (thread); + if (err != JVMTI_ERROR_NONE) + { + using namespace gnu::classpath::jdwp::exception; + char *reason; + _jdwp_jvmtiEnv->GetErrorName (err, &reason); + ::java::lang::String *txt + = JvNewStringLatin1 ("could not suspend thread: "); + ::java::lang::StringBuffer *msg + = new ::java::lang::StringBuffer (txt); + msg->append (JvNewStringLatin1 (reason)); + _jdwp_jvmtiEnv->Deallocate ((unsigned char *) reason); + throw new JdwpInternalErrorException (msg->toString ()); + } + } } void gnu::classpath::jdwp::VMVirtualMachine::resumeThread (Thread *thread) { + jint value; + { + JvSynchronize dummy (_jdwp_suspend_counts); + Integer *count + = reinterpret_cast (_jdwp_suspend_counts->get (thread)); + if (count == NULL) + { + // Thread not suspended: ThreadReference.Resume says to ignore it. + return; + } + else + { + // Decrement suspend count + value = count->intValue () - 1; + } + + if (value == 0) + { + // Thread will be resumed, remove from table + _jdwp_suspend_counts->remove (thread); + } + else + { + // Thread stays suspended: record new suspend count + count = Integer::valueOf (value); + _jdwp_suspend_counts->put (thread, count); + } + } + + if (value == 0) + { + jvmtiError err = _jdwp_jvmtiEnv->ResumeThread (thread); + if (err != JVMTI_ERROR_NONE) + { + using namespace gnu::classpath::jdwp::exception; + char *reason; + _jdwp_jvmtiEnv->GetErrorName (err, &reason); + ::java::lang::String *txt + = JvNewStringLatin1 ("could not resume thread: "); + ::java::lang::StringBuffer *msg + = new ::java::lang::StringBuffer (txt); + msg->append (JvNewStringLatin1 (reason)); + _jdwp_jvmtiEnv->Deallocate ((unsigned char *) reason); + throw new JdwpInternalErrorException (msg->toString ()); + } + } } jint gnu::classpath::jdwp::VMVirtualMachine::getSuspendCount (Thread *thread) { - return 0; + jint suspensions = 0; + Integer *count + = reinterpret_cast (_jdwp_suspend_counts->get (thread)); + if (count != NULL) + suspensions = count->intValue (); + return suspensions; } void -- cgit v1.1