From f9d233dae8ca66ed5a2a474155d6bee0d74c355b Mon Sep 17 00:00:00 2001 From: Sebastien Hertz Date: Fri, 9 Jan 2015 14:51:41 +0100 Subject: [PATCH] JDWP: allow VirtualMachine.Resume on partial suspension Allows to resume multiple threads with a single VirtualMachine.Resume command. When some threads are suspended for an event by the debugger with a suspend count of 1 (other threads are running), a debugger can resume them all this way. Bug: 18924933 Change-Id: I81543df8228d56a4cf201e59885015880650f202 --- runtime/thread_list.cc | 35 ++++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/runtime/thread_list.cc b/runtime/thread_list.cc index 9707c7ba7..42d5c4200 100644 --- a/runtime/thread_list.cc +++ b/runtime/thread_list.cc @@ -813,7 +813,6 @@ void ThreadList::SuspendSelfForDebugger() { void ThreadList::ResumeAllForDebugger() { Thread* self = Thread::Current(); Thread* debug_thread = Dbg::GetDebugThread(); - bool needs_resume = false; VLOG(threads) << *self << " ResumeAllForDebugger starting..."; @@ -826,32 +825,34 @@ void ThreadList::ResumeAllForDebugger() { MutexLock suspend_count_mu(self, *Locks::thread_suspend_count_lock_); // Update global suspend all state for attaching threads. DCHECK_GE(suspend_all_count_, debug_suspend_all_count_); - needs_resume = (debug_suspend_all_count_ > 0); - if (needs_resume) { + if (debug_suspend_all_count_ > 0) { --suspend_all_count_; --debug_suspend_all_count_; - // Decrement everybody's suspend count (except our own). - for (const auto& thread : list_) { - if (thread == self || thread == debug_thread) { - continue; - } - if (thread->GetDebugSuspendCount() == 0) { - // This thread may have been individually resumed with ThreadReference.Resume. - continue; - } - VLOG(threads) << "requesting thread resume: " << *thread; - thread->ModifySuspendCount(self, -1, true); - } } else { // We've been asked to resume all threads without being asked to - // suspend them all before. Let's print a warning. + // suspend them all before. That may happen if a debugger tries + // to resume some suspended threads (with suspend count == 1) + // at once with a VirtualMachine.Resume command. Let's print a + // warning. LOG(WARNING) << "Debugger attempted to resume all threads without " << "having suspended them all before."; } + // Decrement everybody's suspend count (except our own). + for (const auto& thread : list_) { + if (thread == self || thread == debug_thread) { + continue; + } + if (thread->GetDebugSuspendCount() == 0) { + // This thread may have been individually resumed with ThreadReference.Resume. + continue; + } + VLOG(threads) << "requesting thread resume: " << *thread; + thread->ModifySuspendCount(self, -1, true); + } } } - if (needs_resume) { + { MutexLock mu(self, *Locks::thread_suspend_count_lock_); Thread::resume_cond_->Broadcast(self); } -- 2.11.0