# HG changeset patch # User redestad # Date 1483393534 -3600 # Node ID fb59ca170643c425ad85459fbc43d1bbac1e1ec3 # Parent 526b862a4bc4aa33eba9c51293e96eb386e1585c 8172048: Re-examine use of AtomicReference in java.security.Policy Reviewed-by: plevart, dholmes, chegar diff -r 526b862a4bc4 -r fb59ca170643 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 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 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); }