changeset 7216:555140f804ae

7153157: ClassValue.get does not return if computeValue calls remove Summary: Track intermediate states more precisely, according to spec. Reviewed-by: twisti, forax
author poonam
date Tue, 20 May 2014 17:52:35 -0700
parents 00a704025001
children 7060b13cb6cc
files src/share/classes/java/lang/ClassValue.java
diffstat 1 files changed, 11 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/java/lang/ClassValue.java	Tue May 20 16:07:46 2014 +0100
+++ b/src/share/classes/java/lang/ClassValue.java	Tue May 20 17:52:35 2014 -0700
@@ -489,9 +489,18 @@
         /** 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);
             }
         }