7153157: ClassValue.get does not return if computeValue calls remove
authorjrose
Thu, 12 Jul 2012 00:10:53 -0700
changeset 13419 ef84025f710f
parent 13137 34287f5b12fa
child 13420 62cedce8afa6
7153157: ClassValue.get does not return if computeValue calls remove Summary: Track intermediate states more precisely, according to spec. Reviewed-by: twisti, forax
jdk/src/share/classes/java/lang/ClassValue.java
--- a/jdk/src/share/classes/java/lang/ClassValue.java	Thu Jul 05 18:44:32 2012 -0700
+++ b/jdk/src/share/classes/java/lang/ClassValue.java	Thu Jul 12 00:10:53 2012 -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);
             }
         }