summaryrefslogtreecommitdiffstats
path: root/runtime/jdwp
diff options
context:
space:
mode:
authorSebastien Hertz <shertz@google.com>2015-01-14 08:37:47 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2015-01-14 08:37:49 +0000
commitb640deca3616a7a985d146a96407c1af3ffa1592 (patch)
tree19d4b1658222ec21ff5c352e9a683f43e90e038f /runtime/jdwp
parent7fd1c7eabc6c12a2ff67ef58860aae761c92136e (diff)
parent55f6534f260ec82ef2d69a0667b1883f13d11399 (diff)
downloadart-b640deca3616a7a985d146a96407c1af3ffa1592.tar.gz
art-b640deca3616a7a985d146a96407c1af3ffa1592.tar.bz2
art-b640deca3616a7a985d146a96407c1af3ffa1592.zip
Merge "JDWP: fix deadlock with GC"
Diffstat (limited to 'runtime/jdwp')
-rw-r--r--runtime/jdwp/object_registry.cc15
1 files changed, 14 insertions, 1 deletions
diff --git a/runtime/jdwp/object_registry.cc b/runtime/jdwp/object_registry.cc
index 20db368c21..e415c3d1cd 100644
--- a/runtime/jdwp/object_registry.cc
+++ b/runtime/jdwp/object_registry.cc
@@ -104,7 +104,20 @@ bool ObjectRegistry::ContainsLocked(Thread* self, mirror::Object* o, int32_t ide
}
void ObjectRegistry::Clear() {
- Thread* self = Thread::Current();
+ Thread* const self = Thread::Current();
+
+ // We must not hold the mutator lock exclusively if we want to delete weak global
+ // references. Otherwise this can lead to a deadlock with a running GC:
+ // 1. GC thread disables access to weak global references, then releases
+ // mutator lock.
+ // 2. JDWP thread takes mutator lock exclusively after suspending all
+ // threads.
+ // 3. GC thread waits for shared mutator lock which is held by JDWP
+ // thread.
+ // 4. JDWP thread clears weak global references but need to wait for GC
+ // thread to re-enable access to them.
+ Locks::mutator_lock_->AssertNotExclusiveHeld(self);
+
MutexLock mu(self, lock_);
VLOG(jdwp) << "Object registry contained " << object_to_entry_.size() << " entries";
// Delete all the JNI references.