summaryrefslogtreecommitdiffstats
path: root/libart
diff options
context:
space:
mode:
authorMathieu Chartier <mathieuc@google.com>2014-12-12 16:07:39 -0800
committerMathieu Chartier <mathieuc@google.com>2014-12-12 16:22:36 -0800
commitc0b55b80df57b9f8c659a5af4525ceba271622b6 (patch)
tree76640a9ce9dde78c0a01b401ceb9694e670dd011 /libart
parent2d265acbac4d0b3098a0949f34027b63a4be7a28 (diff)
downloadlibcore-c0b55b80df57b9f8c659a5af4525ceba271622b6.zip
libcore-c0b55b80df57b9f8c659a5af4525ceba271622b6.tar.gz
libcore-c0b55b80df57b9f8c659a5af4525ceba271622b6.tar.bz2
Only allow one requestGC at a time
Fixes possible deadlock caused by Thread.getAllStackTraces Thread.getAllStackTraces suspends all of the threads. If one of the threads is a thread which holds the GC daemon lock then we may deadlock when we allocate the stack trace. This happens if we get a concurrent GC request when we are allocating the stack trace elements. To fix the deadlock we now only allow a single thread to requestGC at the same time. Credits: yamauchi, hboehm Bug: 18661622 Change-Id: Ia25598e5daa8ff2dc3aa976148d5ff6afa6960f0
Diffstat (limited to 'libart')
-rw-r--r--libart/src/main/java/java/lang/Daemons.java6
1 files changed, 6 insertions, 0 deletions
diff --git a/libart/src/main/java/java/lang/Daemons.java b/libart/src/main/java/java/lang/Daemons.java
index 4f8285c..726f782 100644
--- a/libart/src/main/java/java/lang/Daemons.java
+++ b/libart/src/main/java/java/lang/Daemons.java
@@ -20,6 +20,7 @@ import dalvik.system.VMRuntime;
import java.lang.ref.FinalizerReference;
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
+import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.TimeoutException;
import libcore.util.EmptyArray;
@@ -317,11 +318,16 @@ public final class Daemons {
private static class GCDaemon extends Daemon {
private static final GCDaemon INSTANCE = new GCDaemon();
+ private static final AtomicBoolean atomicBoolean = new AtomicBoolean();
public void requestGC() {
+ if (atomicBoolean.getAndSet(true)) {
+ return;
+ }
synchronized (this) {
notify();
}
+ atomicBoolean.set(false);
}
@Override public void run() {