Implement ThreadReference.CurrentContendedMonitor and ThreadReference.Interrupt.
The JDWP test for CurrentContendedMonitor also uses Interrupt.
Change-Id: Id1f6add29b578a0494da672d21dd54f23e866475
diff --git a/src/debugger.cc b/src/debugger.cc
index 958fd38..8724327 100644
--- a/src/debugger.cc
+++ b/src/debugger.cc
@@ -713,6 +713,24 @@
return JDWP::ERR_NONE;
}
+JDWP::JdwpError Dbg::GetContendedMonitor(JDWP::ObjectId thread_id, JDWP::ObjectId& contended_monitor)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ ScopedObjectAccessUnchecked soa(Thread::Current());
+ MutexLock mu(soa.Self(), *Locks::thread_list_lock_);
+ Thread* thread;
+ JDWP::JdwpError error = DecodeThread(soa, thread_id, thread);
+ if (error != JDWP::ERR_NONE) {
+ return error;
+ }
+ if (!IsSuspendedForDebugger(soa, thread)) {
+ return JDWP::ERR_THREAD_NOT_SUSPENDED;
+ }
+
+ contended_monitor = gRegistry->Add(Monitor::GetContendedMonitor(thread));
+
+ return JDWP::ERR_NONE;
+}
+
JDWP::JdwpError Dbg::GetReflectedType(JDWP::RefTypeId class_id, JDWP::ExpandBuf* pReply) {
JDWP::JdwpError status;
Class* c = DecodeClass(class_id, status);
@@ -1574,6 +1592,18 @@
return JDWP::ERR_NONE;
}
+JDWP::JdwpError Dbg::Interrupt(JDWP::ObjectId thread_id) {
+ ScopedObjectAccess soa(Thread::Current());
+ MutexLock mu(soa.Self(), *Locks::thread_list_lock_);
+ Thread* thread;
+ JDWP::JdwpError error = DecodeThread(soa, thread_id, thread);
+ if (error != JDWP::ERR_NONE) {
+ return error;
+ }
+ thread->Interrupt();
+ return JDWP::ERR_NONE;
+}
+
void Dbg::GetThreads(JDWP::ObjectId thread_group_id, std::vector<JDWP::ObjectId>& thread_ids) {
class ThreadListVisitor {
public: