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. |