Author: peter_firmstone Date: Sun Feb 19 03:20:00 2012 New Revision: 1290929
URL: http://svn.apache.org/viewvc?rev=1290929&view=rev Log: Incremental merge Modified: river/jtsk/merge/src/com/sun/jini/collection/WeakKeyReference.java river/jtsk/merge/src/com/sun/jini/start/AggregatePolicyProvider.java river/jtsk/merge/src/com/sun/jini/start/LoaderSplitPolicyProvider.java river/jtsk/merge/src/com/sun/jini/start/SharedActivationPolicyPermission.java river/jtsk/merge/src/com/sun/jini/thread/ThreadPool.java Modified: river/jtsk/merge/src/com/sun/jini/collection/WeakKeyReference.java URL: http://svn.apache.org/viewvc/river/jtsk/merge/src/com/sun/jini/collection/WeakKeyReference.java?rev=1290929&r1=1290928&r2=1290929&view=diff ============================================================================== --- river/jtsk/merge/src/com/sun/jini/collection/WeakKeyReference.java (original) +++ river/jtsk/merge/src/com/sun/jini/collection/WeakKeyReference.java Sun Feb 19 03:20:00 2012 @@ -79,12 +79,8 @@ public class WeakKeyReference extends We * </ul> */ public boolean equals(Object other) { - if (other == null) - return false; - if (this == other) - return true; - if (!(other instanceof WeakKeyReference)) - return false; + if (this == other) return true; + if (!(other instanceof WeakKeyReference)) return false; Object thisRef = get(); Object otherRef = ((WeakKeyReference) other).get(); if (thisRef == null || otherRef == null) // if null it's not *anything* Modified: river/jtsk/merge/src/com/sun/jini/start/AggregatePolicyProvider.java URL: http://svn.apache.org/viewvc/river/jtsk/merge/src/com/sun/jini/start/AggregatePolicyProvider.java?rev=1290929&r1=1290928&r2=1290929&view=diff ============================================================================== --- river/jtsk/merge/src/com/sun/jini/start/AggregatePolicyProvider.java (original) +++ river/jtsk/merge/src/com/sun/jini/start/AggregatePolicyProvider.java Sun Feb 19 03:20:00 2012 @@ -18,7 +18,6 @@ package com.sun.jini.start; -import com.sun.jini.collection.WeakIdentityMap; import java.lang.reflect.Method; import java.security.AccessControlContext; import java.security.AccessController; @@ -36,10 +35,19 @@ import java.security.Security; import java.security.SecurityPermission; import java.util.Map; import java.util.WeakHashMap; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; import net.jini.security.SecurityContext; +import org.apache.river.api.security.ConcurrentPolicy; import net.jini.security.policy.DynamicPolicy; import net.jini.security.policy.PolicyInitializationException; import net.jini.security.policy.SecurityContextSource; +import org.apache.river.api.security.PermissionGrant; +import org.apache.river.impl.util.RC; +import org.apache.river.impl.util.Ref; +import org.apache.river.impl.util.Referrer; /** * Security policy provider which supports associating security sub-policies @@ -69,24 +77,38 @@ import net.jini.security.policy.Security * @since 2.0 */ public class AggregatePolicyProvider - extends Policy implements DynamicPolicy, SecurityContextSource + extends Policy implements DynamicPolicy, SecurityContextSource, ConcurrentPolicy { private static final String mainPolicyClassProperty = "com.sun.jini.start.AggregatePolicyProvider.mainPolicyClass"; private static final String defaultMainPolicyClass = "net.jini.security.policy.DynamicPolicyProvider"; - private static final Map trustGetCCL = new WeakHashMap(); - private static final ProtectionDomain myDomain = (ProtectionDomain) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - return AggregatePolicyProvider.class.getProtectionDomain(); - } - }); - - private WeakIdentityMap subPolicies = new WeakIdentityMap(); - private WeakIdentityMap subPolicyCache = new WeakIdentityMap(); - private Policy mainPolicy; + private static final ConcurrentMap<Class,Boolean> trustGetCCL + = RC.concurrentMap( + new ConcurrentHashMap<Referrer<Class>,Referrer<Boolean>>(), + Ref.WEAK_IDENTITY, Ref.STRONG); + private static final ProtectionDomain myDomain + = AccessController.doPrivileged( + new PrivilegedAction<ProtectionDomain>() { + public ProtectionDomain run() { + return AggregatePolicyProvider.class.getProtectionDomain(); + } + }); + + private final Map<ClassLoader,Policy> subPolicies = new WeakHashMap<ClassLoader,Policy>();// protected by lock + // The cache is used to avoid repeat security checks, the subPolicies map + // cannot be used to cache child ClassLoaders because their policy could + // change if a policy is updated. + private final ConcurrentMap<ClassLoader,Policy> subPolicyChildClassLoaderCache = // put protected by policyRead + RC.concurrentMap( // clear protected by policyWrite + new ConcurrentHashMap<Referrer<ClassLoader>,Referrer<Policy>>(), + Ref.WEAK_IDENTITY, Ref.STRONG); +// private final ReadWriteLock policyUpdate = new ReentrantReadWriteLock(); +// private final Lock policyRead = policyUpdate.readLock(); +// private final Lock policyWrite = policyUpdate.writeLock(); + private final Lock lock = new ReentrantLock(); + private volatile Policy mainPolicy; // protected by policyUpdate /** * Creates a new <code>AggregatePolicyProvider</code> instance, containing @@ -209,6 +231,30 @@ public class AggregatePolicyProvider public void refresh() { getCurrentSubPolicy().refresh(); } + + public boolean isConcurrent() { + Policy p = getCurrentSubPolicy(); + if (p instanceof ConcurrentPolicy){ + return ((ConcurrentPolicy)p).isConcurrent(); + } + return false; + } + + public PermissionGrant[] getPermissionGrants(ProtectionDomain domain) { + Policy p = getCurrentSubPolicy(); + if (p instanceof ConcurrentPolicy){ + return ((ConcurrentPolicy)p).getPermissionGrants(domain); + } + return new PermissionGrant[0]; + } + + public PermissionGrant[] getPermissionGrants() { + Policy p = getCurrentSubPolicy(); + if (p instanceof ConcurrentPolicy){ + return ((ConcurrentPolicy)p).getPermissionGrants(); + } + return new PermissionGrant[0]; + } /** * Changes sub-policy association with given class loader. If @@ -237,12 +283,11 @@ public class AggregatePolicyProvider if (sm != null) { sm.checkPermission(new SecurityPermission("setPolicy")); } - synchronized (subPolicies) { - subPolicyCache.clear(); + lock.lock(); + try { if (loader != null) { if (subPolicy != null) { subPolicies.put(loader, subPolicy); - subPolicyCache.put(loader, subPolicy); } else { subPolicies.remove(loader); } @@ -252,7 +297,11 @@ public class AggregatePolicyProvider } mainPolicy = subPolicy; } - } + subPolicyChildClassLoaderCache.clear(); + subPolicyChildClassLoaderCache.putAll(subPolicies); + } finally { + lock.unlock(); + } } /** @@ -365,9 +414,7 @@ public class AggregatePolicyProvider // force class resolution by pre-invoking methods called by implies() trustGetContextClassLoader0(Thread.class); getContextClassLoader(); - synchronized (subPolicies) { - lookupSubPolicy(ldr); - } + lookupSubPolicy(ldr); } /** @@ -375,36 +422,39 @@ public class AggregatePolicyProvider */ private Policy getCurrentSubPolicy() { final Thread t = Thread.currentThread(); - if (!trustGetContextClassLoader(t)) { - return mainPolicy; - } - ClassLoader ccl = getContextClassLoader(); - synchronized (subPolicies) { - Policy policy = (Policy) subPolicyCache.get(ccl); - if (policy == null) { - policy = lookupSubPolicy(ccl); - subPolicyCache.put(ccl, policy); - } - return policy; - } + boolean trust = trustGetContextClassLoader(t); + ClassLoader ccl = trust ? getContextClassLoader() : null; + if ( ccl == null ) return mainPolicy; + Policy policy = subPolicyChildClassLoaderCache.get(ccl); // just a cache. + if ( policy != null ) return policy; + lock.lock(); + try { + policy = lookupSubPolicy(ccl); + return policy; + }finally{ + lock.unlock(); + } } /** * Returns sub-policy associated with the given class loader. This method - * should only be called when already synchronized on subPolicies. + * should only be called when already synchronized on lock. */ private Policy lookupSubPolicy(final ClassLoader ldr) { - assert Thread.holdsLock(subPolicies); - return (Policy) AccessController.doPrivileged( - new PrivilegedAction() { - public Object run() { - for (ClassLoader l = ldr; l != null; l = l.getParent()) { - Policy p = (Policy) subPolicies.get(l); - if (p != null) { - return p; - } - } - return mainPolicy; + return AccessController.doPrivileged( + new PrivilegedAction<Policy>() { + public Policy run() { + Policy p = null; + for (ClassLoader l = ldr; l != null; l = l.getParent()) { + p = subPolicies.get(l); + if (p != null) break; + } + if (p == null) p = mainPolicy; + Policy exists = + subPolicyChildClassLoaderCache.putIfAbsent(ldr, p); + if ( exists != null && p != exists ) + throw new IllegalStateException("Policy Mutation occured"); + return p; } }); } @@ -413,9 +463,9 @@ public class AggregatePolicyProvider * Returns current context class loader. */ static ClassLoader getContextClassLoader() { - return (ClassLoader) AccessController.doPrivileged( - new PrivilegedAction() { - public Object run() { + return AccessController.doPrivileged( + new PrivilegedAction<ClassLoader>() { + public ClassLoader run() { return Thread.currentThread().getContextClassLoader(); } }); @@ -432,22 +482,20 @@ public class AggregatePolicyProvider } Boolean b; - synchronized (trustGetCCL) { - b = (Boolean) trustGetCCL.get(cl); - } + b = trustGetCCL.get(cl); if (b == null) { b = trustGetContextClassLoader0(cl); - synchronized (trustGetCCL) { - trustGetCCL.put(cl, b); - } +// Boolean existed = + trustGetCCL.putIfAbsent(cl, b); } return b.booleanValue(); } private static Boolean trustGetContextClassLoader0(final Class cl) { - return (Boolean) AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { + return AccessController.doPrivileged(new PrivilegedAction<Boolean>() { + public Boolean run() { try { + @SuppressWarnings("unchecked") Method m = cl.getMethod( "getContextClassLoader", new Class[0]); return Boolean.valueOf(m.getDeclaringClass() == Thread.class); @@ -465,17 +513,24 @@ public class AggregatePolicyProvider */ private static class DefaultSecurityContext implements SecurityContext { - private final AccessControlContext acc = - AccessController.getContext(); + private final AccessControlContext acc; + private final int hashCode; + + DefaultSecurityContext(){ + acc = AccessController.getContext(); + int hash = 5; + hash = 47 * hash + (this.acc != null ? this.acc.hashCode() : 0); + hashCode = hash; + } - public PrivilegedAction wrap(PrivilegedAction a) { + public <T> PrivilegedAction<T> wrap(PrivilegedAction<T> a) { if (a == null) { throw new NullPointerException(); } return a; } - public PrivilegedExceptionAction wrap(PrivilegedExceptionAction a) { + public <T> PrivilegedExceptionAction<T> wrap(PrivilegedExceptionAction<T> a) { if (a == null) { throw new NullPointerException(); } @@ -485,6 +540,17 @@ public class AggregatePolicyProvider public AccessControlContext getAccessControlContext() { return acc; } + + @Override + public int hashCode() { + return hashCode; + } + + public boolean equals(Object o){ + if (!(o instanceof DefaultSecurityContext)) return false; + SecurityContext that = (SecurityContext) o; + return getAccessControlContext().equals(that.getAccessControlContext()); + } } /** @@ -494,20 +560,26 @@ public class AggregatePolicyProvider */ private static class AggregateSecurityContext implements SecurityContext { - private final ClassLoader ccl = getContextClassLoader(); + private final ClassLoader ccl; private final SecurityContext sc; + private final int hashCode; AggregateSecurityContext(SecurityContext sc) { if (sc == null) { throw new NullPointerException(); } this.sc = sc; + ccl = getContextClassLoader(); + int hash = 3; + hash = 61 * hash + (this.ccl != null ? this.ccl.hashCode() : 0); + hash = 61 * hash + (this.sc != null ? this.sc.hashCode() : 0); + hashCode = hash; } - public PrivilegedAction wrap(PrivilegedAction a) { - final PrivilegedAction wa = sc.wrap(a); - return new PrivilegedAction() { - public Object run() { + public <T> PrivilegedAction<T> wrap(PrivilegedAction<T> a) { + final PrivilegedAction<T> wa = sc.wrap(a); + return new PrivilegedAction<T>() { + public T run() { ClassLoader sccl = setCCL(ccl, false); try { return wa.run(); @@ -518,10 +590,10 @@ public class AggregatePolicyProvider }; } - public PrivilegedExceptionAction wrap(PrivilegedExceptionAction a) { - final PrivilegedExceptionAction wa = sc.wrap(a); - return new PrivilegedExceptionAction() { - public Object run() throws Exception { + public <T> PrivilegedExceptionAction<T> wrap(PrivilegedExceptionAction<T> a) { + final PrivilegedExceptionAction<T> wa = sc.wrap(a); + return new PrivilegedExceptionAction<T>() { + public T run() throws Exception { ClassLoader sccl = setCCL(ccl, false); try { return wa.run(); @@ -537,9 +609,9 @@ public class AggregatePolicyProvider } private ClassLoader setCCL(final ClassLoader ldr, final boolean force) { - return (ClassLoader) AccessController.doPrivileged( - new PrivilegedAction() { - public Object run() { + return AccessController.doPrivileged( + new PrivilegedAction<ClassLoader>() { + public ClassLoader run() { Thread t = Thread.currentThread(); ClassLoader old = null; if (force || ldr != (old = t.getContextClassLoader())) { @@ -549,5 +621,20 @@ public class AggregatePolicyProvider } }); } + + @Override + public int hashCode() { + return hashCode; + } + + public boolean equals(Object o){ + if (!(o instanceof AggregateSecurityContext)) return false; + AggregateSecurityContext that = (AggregateSecurityContext) o; + if (sc.equals(that.sc)){ + if ( ccl == that.ccl) return true; // both may be null. + if ( ccl != null && ccl.equals(that.ccl)) return true; + } + return false; + } } } Modified: river/jtsk/merge/src/com/sun/jini/start/LoaderSplitPolicyProvider.java URL: http://svn.apache.org/viewvc/river/jtsk/merge/src/com/sun/jini/start/LoaderSplitPolicyProvider.java?rev=1290929&r1=1290928&r2=1290929&view=diff ============================================================================== --- river/jtsk/merge/src/com/sun/jini/start/LoaderSplitPolicyProvider.java (original) +++ river/jtsk/merge/src/com/sun/jini/start/LoaderSplitPolicyProvider.java Sun Feb 19 03:20:00 2012 @@ -30,6 +30,14 @@ import java.security.Policy; import java.security.Principal; import java.security.PrivilegedAction; import java.security.ProtectionDomain; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; +import org.apache.river.api.security.ConcurrentPolicy; +import org.apache.river.api.security.PermissionGrant; +import org.apache.river.impl.util.RC; +import org.apache.river.impl.util.Ref; +import org.apache.river.impl.util.Referrer; /** * Security policy provider which handles permission queries and grants by @@ -51,17 +59,17 @@ import java.security.ProtectionDomain; public class LoaderSplitPolicyProvider extends Policy implements DynamicPolicy { - private static final ProtectionDomain myDomain = (ProtectionDomain) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - return LoaderSplitPolicyProvider.class.getProtectionDomain(); - } - }); + private static final ProtectionDomain myDomain = + AccessController.doPrivileged(new PrivilegedAction<ProtectionDomain>() { + public ProtectionDomain run() { + return LoaderSplitPolicyProvider.class.getProtectionDomain(); + } + }); private final ClassLoader loader; private final Policy loaderPolicy; private final Policy defaultPolicy; - private final WeakIdentityMap delegateMap = new WeakIdentityMap(); + private final ConcurrentMap<ClassLoader,Policy> delegateMap; /** * Creates a new <code>LoaderSplitPolicyProvider</code> instance which @@ -90,6 +98,9 @@ public class LoaderSplitPolicyProvider this.loader = loader; this.loaderPolicy = loaderPolicy; this.defaultPolicy = defaultPolicy; + delegateMap = RC.concurrentMap( + new ConcurrentHashMap<Referrer<ClassLoader>,Referrer<Policy>>() + ,Ref.WEAK_IDENTITY , Ref.STRONG); ensureDependenciesResolved(); } @@ -155,7 +166,7 @@ public class LoaderSplitPolicyProvider loaderPolicy.refresh(); defaultPolicy.refresh(); } - + /** * Returns <code>true</code> if both of the underlying policy providers * implement {@link DynamicPolicy} and return <code>true</code> from calls @@ -241,33 +252,28 @@ public class LoaderSplitPolicyProvider */ return loaderPolicy; } - Policy p; - synchronized (delegateMap) { - p = (Policy) delegateMap.get(ldr); - } + Policy p = delegateMap.get(ldr); if (p == null) { - p = (Policy) AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - for (ClassLoader l = ldr; l != null; l = l.getParent()) - { - if (l == loader) { - return loaderPolicy; - } - } - return defaultPolicy; - } - }); - synchronized (delegateMap) { - delegateMap.put(ldr, p); - } + p = AccessController.doPrivileged(new PrivilegedAction<Policy>() { + public Policy run() { + for (ClassLoader l = ldr; l != null; l = l.getParent()) + { + if (l == loader) { + return loaderPolicy; + } + } + return defaultPolicy; + } + }); + delegateMap.putIfAbsent(ldr, p); } return p; } private static ClassLoader getClassLoader(final Class cl) { - return (ClassLoader) AccessController.doPrivileged( - new PrivilegedAction() { - public Object run() { return cl.getClassLoader(); } - }); + return AccessController.doPrivileged( + new PrivilegedAction<ClassLoader>() { + public ClassLoader run() { return cl.getClassLoader(); } + }); } } Modified: river/jtsk/merge/src/com/sun/jini/start/SharedActivationPolicyPermission.java URL: http://svn.apache.org/viewvc/river/jtsk/merge/src/com/sun/jini/start/SharedActivationPolicyPermission.java?rev=1290929&r1=1290928&r2=1290929&view=diff ============================================================================== --- river/jtsk/merge/src/com/sun/jini/start/SharedActivationPolicyPermission.java (original) +++ river/jtsk/merge/src/com/sun/jini/start/SharedActivationPolicyPermission.java Sun Feb 19 03:20:00 2012 @@ -71,7 +71,7 @@ public final class SharedActivationPolic * target of the <code>implies()</code> checks. * @serial */ - private /*final*/ FilePermission policyPermission; + private final Permission policyPermission; /** * Constructor that creates a @@ -81,7 +81,7 @@ public final class SharedActivationPolic public SharedActivationPolicyPermission(String policy) { //TBD - check for null args super(policy); - init(policy); + policyPermission = init(policy); } /** @@ -94,13 +94,13 @@ public final class SharedActivationPolic public SharedActivationPolicyPermission(String policy, String action) { //TBD - check for null args super(policy); - init(policy); + policyPermission = init(policy); } /** * Contains common code to all constructors. */ - private void init(final String policy) { + private Permission init(final String policy) { /* * In order to leverage the <code>FilePermission</code> logic * we need to make sure that forward slashes ("/"), in @@ -110,6 +110,7 @@ public final class SharedActivationPolic * http://host:port/* matches http://host:port/bogus.jar under * UNIX, but not under Windows since "\*" is the wildcard there. */ + if (policy == null) throw new NullPointerException("Null policy string not allowed"); String uncanonicalPath = null; try { URL url = new URL(policy); @@ -123,7 +124,7 @@ public final class SharedActivationPolic uncanonicalPath = policy; } - policyPermission = new FilePermission(uncanonicalPath, "read"); + return new FilePermission(uncanonicalPath, "read"); } // javadoc inherited from superclass Modified: river/jtsk/merge/src/com/sun/jini/thread/ThreadPool.java URL: http://svn.apache.org/viewvc/river/jtsk/merge/src/com/sun/jini/thread/ThreadPool.java?rev=1290929&r1=1290928&r2=1290929&view=diff ============================================================================== --- river/jtsk/merge/src/com/sun/jini/thread/ThreadPool.java (original) +++ river/jtsk/merge/src/com/sun/jini/thread/ThreadPool.java Sun Feb 19 03:20:00 2012 @@ -56,7 +56,7 @@ import java.util.logging.Logger; * * @author Sun Microsystems, Inc. **/ -final class ThreadPool implements Executor { +final class ThreadPool implements Executor, java.util.concurrent.Executor { /** how long a thread waits in the idle state before passing away */ private static final long idleTimeout = // default 5 minutes @@ -101,6 +101,10 @@ final class ThreadPool implements Execut t.start(); } + public void execute(Runnable command) { + execute(command, "com.sun.jini.thread.ThreadPool"); + } + /** * Task simply encapsulates a task's Runnable object with its name. */
