diff options
author | Mathieu Chartier <mathieuc@google.com> | 2014-12-12 16:07:39 -0800 |
---|---|---|
committer | Mathieu Chartier <mathieuc@google.com> | 2014-12-12 16:22:36 -0800 |
commit | c0b55b80df57b9f8c659a5af4525ceba271622b6 (patch) | |
tree | 76640a9ce9dde78c0a01b401ceb9694e670dd011 /libart | |
parent | 2d265acbac4d0b3098a0949f34027b63a4be7a28 (diff) | |
download | libcore-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.java | 6 |
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() { |