diff options
author | Elena Sayapina <elena.v.sayapina@intel.com> | 2014-04-30 17:51:03 +0700 |
---|---|---|
committer | Narayan Kamath <narayan@google.com> | 2014-05-06 18:28:15 +0100 |
commit | eb3e5888d4b3c17b5b6e977440178e88ba174f93 (patch) | |
tree | c8556479202e04257da3f4c1c88b7d4d6d416e79 /luni/src | |
parent | 9f2ab8ad1eff63bd5cf5a300feefb1be396161dc (diff) | |
download | libcore-eb3e5888d4b3c17b5b6e977440178e88ba174f93.zip libcore-eb3e5888d4b3c17b5b6e977440178e88ba174f93.tar.gz libcore-eb3e5888d4b3c17b5b6e977440178e88ba174f93.tar.bz2 |
Change ReferenceQueue order from LIFO to FIFO.
LIFO order of FinalizerReference.queue breaks runFinalization().
runFinalization() creates a Sentinel finalizable object and waits
for it to be finalized. As FinalizerReference.queue is LIFO,
the Sentinel object is placed at the beginning of the queue and
then gets finalized first. So the method returns even though
objects placed in the queue before the Sentinel are not finalized.
This patch changes the queue order to FIFO to ensure that all
elements enqueued before the Sentinel are finalized before it.
bug: https://code.google.com/p/android/issues/detail?id=37980
Change-Id: Ie6bc96e6a3759bc36ce6586066052b6d6bbe8d52
Signed-off-by: Elena Sayapina <elena.v.sayapina@intel.com>
Diffstat (limited to 'luni/src')
-rw-r--r-- | luni/src/main/java/java/lang/ref/ReferenceQueue.java | 21 |
1 files changed, 12 insertions, 9 deletions
diff --git a/luni/src/main/java/java/lang/ref/ReferenceQueue.java b/luni/src/main/java/java/lang/ref/ReferenceQueue.java index 2b8089c..7ddd97d 100644 --- a/luni/src/main/java/java/lang/ref/ReferenceQueue.java +++ b/luni/src/main/java/java/lang/ref/ReferenceQueue.java @@ -28,6 +28,7 @@ public class ReferenceQueue<T> { private static final int NANOS_PER_MILLI = 1000000; private Reference<? extends T> head; + private Reference<? extends T> tail; /** * Constructs a new instance of this class. @@ -48,18 +49,16 @@ public class ReferenceQueue<T> { return null; } - Reference<? extends T> ret; + Reference<? extends T> ret = head; - ret = head; - - if (head == head.queueNext) { + if (head == tail) { + tail = null; head = null; } else { head = head.queueNext; } ret.queueNext = null; - return ret; } @@ -133,12 +132,16 @@ public class ReferenceQueue<T> { * reference object to be enqueued. */ synchronized void enqueue(Reference<? extends T> reference) { - if (head == null) { - reference.queueNext = reference; + if (tail == null) { + head = reference; } else { - reference.queueNext = head; + tail.queueNext = reference; } - head = reference; + + // The newly enqueued reference becomes the new tail, and always + // points to itself. + tail = reference; + tail.queueNext = reference; notify(); } |