jdk/src/java.base/share/classes/java/security/ProtectionDomain.java
changeset 34956 cfa4105ed600
parent 32834 e1dca5fe4de3
child 37880 60ec48925dc6
equal deleted inserted replaced
34951:4e8b871b54a7 34956:cfa4105ed600
     1 /*
     1 /*
     2  * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
     2  * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.  Oracle designates this
     7  * published by the Free Software Foundation.  Oracle designates this
    25 
    25 
    26 package java.security;
    26 package java.security;
    27 
    27 
    28 import java.lang.ref.Reference;
    28 import java.lang.ref.Reference;
    29 import java.lang.ref.ReferenceQueue;
    29 import java.lang.ref.ReferenceQueue;
       
    30 import java.lang.ref.SoftReference;
    30 import java.lang.ref.WeakReference;
    31 import java.lang.ref.WeakReference;
    31 import java.util.ArrayList;
    32 import java.util.ArrayList;
    32 import java.util.Enumeration;
    33 import java.util.Enumeration;
    33 import java.util.List;
    34 import java.util.List;
    34 import java.util.Map;
    35 import java.util.Map;
    35 import java.util.WeakHashMap;
       
    36 import java.util.concurrent.ConcurrentHashMap;
    36 import java.util.concurrent.ConcurrentHashMap;
    37 import jdk.internal.misc.JavaSecurityAccess;
    37 import jdk.internal.misc.JavaSecurityAccess;
    38 import jdk.internal.misc.JavaSecurityProtectionDomainAccess;
    38 import jdk.internal.misc.JavaSecurityProtectionDomainAccess;
    39 import static jdk.internal.misc.JavaSecurityProtectionDomainAccess.ProtectionDomainCache;
    39 import static jdk.internal.misc.JavaSecurityProtectionDomainAccess.ProtectionDomainCache;
    40 import jdk.internal.misc.SharedSecrets;
    40 import jdk.internal.misc.SharedSecrets;
   470     /**
   470     /**
   471      * A cache of ProtectionDomains and their Permissions.
   471      * A cache of ProtectionDomains and their Permissions.
   472      *
   472      *
   473      * This class stores ProtectionDomains as weak keys in a ConcurrentHashMap
   473      * This class stores ProtectionDomains as weak keys in a ConcurrentHashMap
   474      * with additional support for checking and removing weak keys that are no
   474      * with additional support for checking and removing weak keys that are no
   475      * longer in use.
   475      * longer in use. There can be cases where the permission collection may
       
   476      * have a chain of strong references back to the ProtectionDomain, which
       
   477      * ordinarily would prevent the entry from being removed from the map. To
       
   478      * address that, we wrap the permission collection in a SoftReference so
       
   479      * that it can be reclaimed by the garbage collector due to memory demand.
   476      */
   480      */
   477     private static class PDCache implements ProtectionDomainCache {
   481     private static class PDCache implements ProtectionDomainCache {
   478         private final ConcurrentHashMap<WeakProtectionDomainKey,
   482         private final ConcurrentHashMap<WeakProtectionDomainKey,
   479                                         PermissionCollection>
   483                                         SoftReference<PermissionCollection>>
   480                                         pdMap = new ConcurrentHashMap<>();
   484                                         pdMap = new ConcurrentHashMap<>();
   481         private final ReferenceQueue<Key> queue = new ReferenceQueue<>();
   485         private final ReferenceQueue<Key> queue = new ReferenceQueue<>();
   482 
   486 
   483         @Override
   487         @Override
   484         public void put(ProtectionDomain pd, PermissionCollection pc) {
   488         public void put(ProtectionDomain pd, PermissionCollection pc) {
   485             processQueue(queue, pdMap);
   489             processQueue(queue, pdMap);
   486             WeakProtectionDomainKey weakPd =
   490             WeakProtectionDomainKey weakPd =
   487                 new WeakProtectionDomainKey(pd, queue);
   491                 new WeakProtectionDomainKey(pd, queue);
   488             pdMap.putIfAbsent(weakPd, pc);
   492             pdMap.put(weakPd, new SoftReference<>(pc));
   489         }
   493         }
   490 
   494 
   491         @Override
   495         @Override
   492         public PermissionCollection get(ProtectionDomain pd) {
   496         public PermissionCollection get(ProtectionDomain pd) {
   493             processQueue(queue, pdMap);
   497             processQueue(queue, pdMap);
   494             WeakProtectionDomainKey weakPd =
   498             WeakProtectionDomainKey weakPd = new WeakProtectionDomainKey(pd);
   495                 new WeakProtectionDomainKey(pd, queue);
   499             SoftReference<PermissionCollection> sr = pdMap.get(weakPd);
   496             return pdMap.get(weakPd);
   500             return (sr == null) ? null : sr.get();
   497         }
   501         }
   498 
   502 
   499         /**
   503         /**
   500          * Removes weak keys from the map that have been enqueued
   504          * Removes weak keys from the map that have been enqueued
   501          * on the reference queue and are no longer in use.
   505          * on the reference queue and are no longer in use.
   531          */
   535          */
   532         WeakProtectionDomainKey(ProtectionDomain pd, ReferenceQueue<Key> rq) {
   536         WeakProtectionDomainKey(ProtectionDomain pd, ReferenceQueue<Key> rq) {
   533             this((pd == null ? NULL_KEY : pd.key), rq);
   537             this((pd == null ? NULL_KEY : pd.key), rq);
   534         }
   538         }
   535 
   539 
       
   540         WeakProtectionDomainKey(ProtectionDomain pd) {
       
   541             this(pd == null ? NULL_KEY : pd.key);
       
   542         }
       
   543 
   536         private WeakProtectionDomainKey(Key key, ReferenceQueue<Key> rq) {
   544         private WeakProtectionDomainKey(Key key, ReferenceQueue<Key> rq) {
   537             super(key, rq);
   545             super(key, rq);
       
   546             hash = key.hashCode();
       
   547         }
       
   548 
       
   549         private WeakProtectionDomainKey(Key key) {
       
   550             super(key);
   538             hash = key.hashCode();
   551             hash = key.hashCode();
   539         }
   552         }
   540 
   553 
   541         /**
   554         /**
   542          * Returns the identity hash code of the original referent.
   555          * Returns the identity hash code of the original referent.