diff -r a6b5f444cb68 -r 00a25f4c4d44 jdk/src/java.base/share/classes/java/security/Permissions.java --- a/jdk/src/java.base/share/classes/java/security/Permissions.java Mon Jun 08 16:17:37 2015 +0300 +++ b/jdk/src/java.base/share/classes/java/security/Permissions.java Tue Jun 09 09:18:07 2015 -0400 @@ -33,6 +33,7 @@ import java.util.List; import java.util.Iterator; import java.util.Collections; +import java.util.concurrent.ConcurrentHashMap; import java.io.Serializable; import java.io.ObjectStreamField; import java.io.ObjectOutputStream; @@ -85,7 +86,7 @@ * Key is permissions Class, value is PermissionCollection for that class. * Not serialized; see serialization section at end of class. */ - private transient Map, PermissionCollection> permsMap; + private transient ConcurrentHashMap, PermissionCollection> permsMap; // optimization. keep track of whether unresolved permissions need to be // checked @@ -99,7 +100,7 @@ * Creates a new Permissions object containing no PermissionCollections. */ public Permissions() { - permsMap = new HashMap<>(11); + permsMap = new ConcurrentHashMap<>(11); allPermission = null; } @@ -120,18 +121,14 @@ * * @see PermissionCollection#isReadOnly() */ - + @Override public void add(Permission permission) { if (isReadOnly()) throw new SecurityException( "attempt to add a Permission to a readonly Permissions object"); - PermissionCollection pc; - - synchronized (this) { - pc = getPermissionCollection(permission, true); - pc.add(permission); - } + PermissionCollection pc = getPermissionCollection(permission, true); + pc.add(permission); // No sync; staleness -> optimizations delayed, which is OK if (permission instanceof AllPermission) { @@ -169,21 +166,19 @@ * PermissionCollection it * belongs to, false if not. */ - + @Override public boolean implies(Permission permission) { // No sync; staleness -> skip optimization, which is OK if (allPermission != null) { return true; // AllPermission has already been added } else { - synchronized (this) { - PermissionCollection pc = getPermissionCollection(permission, - false); - if (pc != null) { - return pc.implies(permission); - } else { - // none found - return false; - } + PermissionCollection pc = getPermissionCollection(permission, + false); + if (pc != null) { + return pc.implies(permission); + } else { + // none found + return false; } } } @@ -194,14 +189,12 @@ * * @return an enumeration of all the Permissions. */ - + @Override public Enumeration elements() { // go through each Permissions in the hash table // and call their elements() function. - synchronized (this) { - return new PermissionsEnumerator(permsMap.values().iterator()); - } + return new PermissionsEnumerator(permsMap.values().iterator()); } /** @@ -236,34 +229,39 @@ * It should be set to true when invoked from add(). */ private PermissionCollection getPermissionCollection(Permission p, - boolean createEmpty) { + boolean createEmpty) { Class c = p.getClass(); - PermissionCollection pc = permsMap.get(c); - if (!hasUnresolved && !createEmpty) { - return pc; - } else if (pc == null) { + return permsMap.get(c); + } - // Check for unresolved permissions - pc = (hasUnresolved ? getUnresolvedPermissions(p) : null); - - // if still null, create a new collection - if (pc == null && createEmpty) { - - pc = p.newPermissionCollection(); + // Create and add permission collection to map if it is absent. + // NOTE: cannot use lambda for mappingFunction parameter until + // JDK-8076596 is fixed. + return permsMap.computeIfAbsent(c, + new java.util.function.Function<>() { + @Override + public PermissionCollection apply(Class k) { + // Check for unresolved permissions + PermissionCollection pc = + (hasUnresolved ? getUnresolvedPermissions(p) : null); - // still no PermissionCollection? - // We'll give them a PermissionsHash. - if (pc == null) - pc = new PermissionsHash(); - } + // if still null, create a new collection + if (pc == null && createEmpty) { + + pc = p.newPermissionCollection(); - if (pc != null) { - permsMap.put(c, pc); + // still no PermissionCollection? + // We'll give them a PermissionsHash. + if (pc == null) { + pc = new PermissionsHash(); + } + } + return pc; + } } - } - return pc; + ); } /** @@ -277,8 +275,6 @@ */ private PermissionCollection getUnresolvedPermissions(Permission p) { - // Called from within synchronized method so permsMap doesn't need lock - UnresolvedPermissionCollection uc = (UnresolvedPermissionCollection) permsMap.get(UnresolvedPermission.class); @@ -362,9 +358,7 @@ // Copy perms into a Hashtable Hashtable, PermissionCollection> perms = new Hashtable<>(permsMap.size()*2); // no sync; estimate - synchronized (this) { - perms.putAll(permsMap); - } + perms.putAll(permsMap); // Write out serializable fields ObjectOutputStream.PutField pfields = out.putFields(); @@ -394,7 +388,7 @@ @SuppressWarnings("unchecked") Hashtable, PermissionCollection> perms = (Hashtable, PermissionCollection>)gfields.get("perms", null); - permsMap = new HashMap<>(perms.size()*2); + permsMap = new ConcurrentHashMap<>(perms.size()*2); permsMap.putAll(perms); // Set hasUnresolved @@ -481,14 +475,13 @@ * Key and value are (same) permissions objects. * Not serialized; see serialization section at end of class. */ - private transient Map permsMap; + private transient ConcurrentHashMap permsMap; /** * Create an empty PermissionsHash object. */ - PermissionsHash() { - permsMap = new HashMap<>(11); + permsMap = new ConcurrentHashMap<>(11); } /** @@ -496,11 +489,9 @@ * * @param permission the Permission object to add. */ - + @Override public void add(Permission permission) { - synchronized (this) { - permsMap.put(permission, permission); - } + permsMap.put(permission, permission); } /** @@ -512,23 +503,21 @@ * @return true if "permission" is a proper subset of a permission in * the set, false if not. */ - + @Override public boolean implies(Permission permission) { // attempt a fast lookup and implies. If that fails // then enumerate through all the permissions. - synchronized (this) { - Permission p = permsMap.get(permission); + Permission p = permsMap.get(permission); - // If permission is found, then p.equals(permission) - if (p == null) { - for (Permission p_ : permsMap.values()) { - if (p_.implies(permission)) - return true; - } - return false; - } else { - return true; + // If permission is found, then p.equals(permission) + if (p == null) { + for (Permission p_ : permsMap.values()) { + if (p_.implies(permission)) + return true; } + return false; + } else { + return true; } } @@ -537,12 +526,9 @@ * * @return an enumeration of all the Permissions. */ - + @Override public Enumeration elements() { - // Convert Iterator of Map values into an Enumeration - synchronized (this) { - return Collections.enumeration(permsMap.values()); - } + return permsMap.elements(); } private static final long serialVersionUID = -8491988220802933440L; @@ -570,9 +556,7 @@ // Copy perms into a Hashtable Hashtable perms = new Hashtable<>(permsMap.size()*2); - synchronized (this) { - perms.putAll(permsMap); - } + perms.putAll(permsMap); // Write out serializable fields ObjectOutputStream.PutField pfields = out.putFields(); @@ -597,7 +581,7 @@ @SuppressWarnings("unchecked") Hashtable perms = (Hashtable)gfields.get("perms", null); - permsMap = new HashMap<>(perms.size()*2); + permsMap = new ConcurrentHashMap<>(perms.size()*2); permsMap.putAll(perms); } }