changeset 5873:05e5ce861a58

7153157: ClassValue.get does not return if computeValue calls remove Summary: Track intermediate states more precisely, according to spec. Reviewed-by: twisti, forax
author jrose
date Thu, 12 Jul 2012 00:10:53 -0700
parents 9d1738ef61d6
children beeb1d5ecd9e
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	Thu Jul 05 18:44:32 2012 -0700
+++ b/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);
             }
         }