From 6afc94828507a5549ff809be066fd290cd3b141f Mon Sep 17 00:00:00 2001 From: jrose Date: Thu, 12 Jul 2012 00:10:53 -0700 Subject: [PATCH] 7153157: ClassValue.get does not return if computeValue calls remove Summary: Track intermediate states more precisely, according to spec. Reviewed-by: twisti, forax --- src/share/classes/java/lang/ClassValue.java | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/share/classes/java/lang/ClassValue.java b/src/share/classes/java/lang/ClassValue.java index 6a824bcc4..472eb646b 100644 --- a/src/share/classes/java/lang/ClassValue.java +++ b/src/share/classes/java/lang/ClassValue.java @@ -489,9 +489,18 @@ public abstract class ClassValue { /** Remove an entry. */ synchronized void removeEntry(ClassValue classValue) { - // make all cache elements for this guy go stale: - if (remove(classValue.identity) != null) { + Entry e = remove(classValue.identity); + if (e == null) { + // Uninitialized, and no pending calls to computeValue. No change. + } else if (e.isPromise()) { + // State is uninitialized, with a pending call to finishEntry. + // Since remove is a no-op in such a state, keep the promise + // by putting it back into the map. + put(classValue.identity, e); + } else { + // In an initialized state. Bump forward, and de-initialize. classValue.bumpVersion(); + // Make all cache elements for this guy go stale. removeStaleEntries(classValue); } } -- GitLab