8172048: Re-examine use of AtomicReference in java.security.Policy
authorredestad
Mon, 02 Jan 2017 22:45:34 +0100
changeset 42951 fb59ca170643
parent 42950 526b862a4bc4
child 42952 44060b966525
8172048: Re-examine use of AtomicReference in java.security.Policy Reviewed-by: plevart, dholmes, chegar
jdk/src/java.base/share/classes/java/security/Policy.java
--- a/jdk/src/java.base/share/classes/java/security/Policy.java	Fri Dec 30 13:02:23 2016 +0300
+++ b/jdk/src/java.base/share/classes/java/security/Policy.java	Mon Jan 02 22:45:34 2017 +0100
@@ -28,7 +28,6 @@
 
 import java.util.Enumeration;
 import java.util.WeakHashMap;
-import java.util.concurrent.atomic.AtomicReference;
 import java.util.Objects;
 import sun.security.jca.GetInstance;
 import sun.security.util.Debug;
@@ -107,9 +106,10 @@
         }
     }
 
-    // PolicyInfo is stored in an AtomicReference
-    private static AtomicReference<PolicyInfo> policy =
-        new AtomicReference<>(new PolicyInfo(null, false));
+    // PolicyInfo is volatile since we apply DCL during initialization.
+    // For correctness, care must be taken to read the field only once and only
+    // write to it after any other initialization action has taken place.
+    private static volatile PolicyInfo policyInfo = new PolicyInfo(null, false);
 
     private static final Debug debug = Debug.getInstance("policy");
 
@@ -121,9 +121,8 @@
     private WeakHashMap<ProtectionDomain.Key, PermissionCollection> pdMapping;
 
     /** package private for AccessControlContext and ProtectionDomain */
-    static boolean isSet()
-    {
-        PolicyInfo pi = policy.get();
+    static boolean isSet() {
+        PolicyInfo pi = policyInfo;
         return pi.policy != null && pi.initialized == true;
     }
 
@@ -168,16 +167,15 @@
      */
     static Policy getPolicyNoCheck()
     {
-        PolicyInfo pi = policy.get();
+        PolicyInfo pi = policyInfo;
         // Use double-check idiom to avoid locking if system-wide policy is
         // already initialized
         if (pi.initialized == false || pi.policy == null) {
             synchronized (Policy.class) {
-                PolicyInfo pinfo = policy.get();
-                if (pinfo.policy == null) {
+                pi = policyInfo;
+                if (pi.policy == null) {
                     return loadPolicyProvider();
                 }
-                return pinfo.policy;
             }
         }
         return pi.policy;
@@ -206,7 +204,7 @@
             policyProvider.equals(DEFAULT_POLICY))
         {
             Policy polFile = new sun.security.provider.PolicyFile();
-            policy.set(new PolicyInfo(polFile, true));
+            policyInfo = new PolicyInfo(polFile, true);
             return polFile;
         }
 
@@ -216,7 +214,7 @@
          * provider to avoid potential recursion.
          */
         Policy polFile = new sun.security.provider.PolicyFile();
-        policy.set(new PolicyInfo(polFile, false));
+        policyInfo = new PolicyInfo(polFile, false);
 
         Policy pol = AccessController.doPrivileged(new PrivilegedAction<>() {
             @Override
@@ -244,7 +242,7 @@
             }
             pol = polFile;
         }
-        policy.set(new PolicyInfo(pol, true));
+        policyInfo = new PolicyInfo(pol, true);
         return pol;
     }
 
@@ -274,7 +272,7 @@
             initPolicy(p);
         }
         synchronized (Policy.class) {
-            policy.set(new PolicyInfo(p, p != null));
+            policyInfo = new PolicyInfo(p, p != null);
         }
     }
 
@@ -326,7 +324,7 @@
         }
 
         if (policyDomain.getCodeSource() != null) {
-            Policy pol = policy.get().policy;
+            Policy pol = policyInfo.policy;
             if (pol != null) {
                 policyPerms = pol.getPermissions(policyDomain);
             }