aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libjava/ChangeLog10
-rw-r--r--libjava/gnu/classpath/jdwp/VMVirtualMachine.java4
-rw-r--r--libjava/gnu/classpath/jdwp/natVMVirtualMachine.cc97
3 files changed, 110 insertions, 1 deletions
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 <keiths@redhat.com>
+
+ * 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 <mtrudel@gmx.ch>
* 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 <java/lang/Class.h>
#include <java/lang/ClassLoader.h>
+#include <java/lang/Integer.h>
+#include <java/lang/String.h>
+#include <java/lang/StringBuffer.h>
#include <java/lang/Thread.h>
#include <java/nio/ByteBuffer.h>
#include <java/util/ArrayList.h>
+#include <java/util/Hashtable.h>
#include <java/util/Iterator.h>
#include <gnu/classpath/jdwp/VMFrame.h>
#include <gnu/classpath/jdwp/VMMethod.h>
#include <gnu/classpath/jdwp/VMVirtualMachine.h>
#include <gnu/classpath/jdwp/event/EventRequest.h>
+#include <gnu/classpath/jdwp/exception/JdwpInternalErrorException.h>
#include <gnu/classpath/jdwp/util/MethodResult.h>
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<void **> (&_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<Integer *> (_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<Integer *> (_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<Integer *> (_jdwp_suspend_counts->get (thread));
+ if (count != NULL)
+ suspensions = count->intValue ();
+ return suspensions;
}
void