Author: peter_firmstone Date: Mon Jan 16 00:26:33 2012 New Revision: 1231803
URL: http://svn.apache.org/viewvc?rev=1231803&view=rev Log: Altered DelegateCombinerSecurityManager to support SecurityContext, so policies and subclass SecurityManagers that implement SecurityContextSource are supported. Security.getContext() is called instead of AccessController.getContext(). Updated Reference Collections to utilse a Garbage Collection cleaning background Executor. Modified: river/jtsk/skunk/peterConcurrentPolicy/qa/src/com/sun/jini/qa/harness/MasterTest.java river/jtsk/skunk/peterConcurrentPolicy/src/com/sun/jini/start/AggregatePolicyProvider.java river/jtsk/skunk/peterConcurrentPolicy/src/net/jini/security/Security.java river/jtsk/skunk/peterConcurrentPolicy/src/net/jini/security/SecurityContext.java river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/DelegateCombinerSecurityManager.java river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/PermissionComparator.java river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/RC.java river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferenceBlockingDeque.java river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferenceBlockingQueue.java river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferenceCollection.java river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferenceConcurrentMap.java river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferenceConcurrentNavigableMap.java river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferenceDeque.java river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferenceList.java river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferenceMap.java river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferenceNavigableMap.java river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferenceNavigableSet.java river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferenceSet.java river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferenceSortedMap.java river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferenceSortedSet.java river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferencedQueue.java Modified: river/jtsk/skunk/peterConcurrentPolicy/qa/src/com/sun/jini/qa/harness/MasterTest.java URL: http://svn.apache.org/viewvc/river/jtsk/skunk/peterConcurrentPolicy/qa/src/com/sun/jini/qa/harness/MasterTest.java?rev=1231803&r1=1231802&r2=1231803&view=diff ============================================================================== --- river/jtsk/skunk/peterConcurrentPolicy/qa/src/com/sun/jini/qa/harness/MasterTest.java (original) +++ river/jtsk/skunk/peterConcurrentPolicy/qa/src/com/sun/jini/qa/harness/MasterTest.java Mon Jan 16 00:26:33 2012 @@ -36,6 +36,7 @@ import javax.security.auth.Subject; import net.jini.config.Configuration; import net.jini.config.ConfigurationException; +import org.apache.river.api.security.DelegateCombinerSecurityManager; /** * A wrapper which drives the execution of a test on the master host. @@ -83,8 +84,9 @@ class MasterTest { System.setErr(System.out); logger.log(Level.FINE, "Starting MasterTest"); if (System.getSecurityManager() == null) { - System.setSecurityManager(new java.rmi.RMISecurityManager()); +// System.setSecurityManager(new java.rmi.RMISecurityManager()); // System.setSecurityManager(new ProfilingSecurityManager()); + System.setSecurityManager(new DelegateCombinerSecurityManager()); } if (args.length < 1) { exit(false, Test.ENV, "Arguments missing"); Modified: river/jtsk/skunk/peterConcurrentPolicy/src/com/sun/jini/start/AggregatePolicyProvider.java URL: http://svn.apache.org/viewvc/river/jtsk/skunk/peterConcurrentPolicy/src/com/sun/jini/start/AggregatePolicyProvider.java?rev=1231803&r1=1231802&r2=1231803&view=diff ============================================================================== --- river/jtsk/skunk/peterConcurrentPolicy/src/com/sun/jini/start/AggregatePolicyProvider.java (original) +++ river/jtsk/skunk/peterConcurrentPolicy/src/com/sun/jini/start/AggregatePolicyProvider.java Mon Jan 16 00:26:33 2012 @@ -513,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(); } @@ -533,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()); + } } /** @@ -544,6 +562,7 @@ public class AggregatePolicyProvider private final ClassLoader ccl; private final SecurityContext sc; + private final int hashCode; AggregateSecurityContext(SecurityContext sc) { if (sc == null) { @@ -551,12 +570,16 @@ public class AggregatePolicyProvider } 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(); @@ -567,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(); @@ -598,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/skunk/peterConcurrentPolicy/src/net/jini/security/Security.java URL: http://svn.apache.org/viewvc/river/jtsk/skunk/peterConcurrentPolicy/src/net/jini/security/Security.java?rev=1231803&r1=1231802&r2=1231803&view=diff ============================================================================== --- river/jtsk/skunk/peterConcurrentPolicy/src/net/jini/security/Security.java (original) +++ river/jtsk/skunk/peterConcurrentPolicy/src/net/jini/security/Security.java Mon Jan 16 00:26:33 2012 @@ -462,26 +462,7 @@ public final class Security { } final AccessControlContext acc = AccessController.getContext(); - return new SecurityContext() { - public PrivilegedAction wrap(PrivilegedAction a) { - if (a == null) { - throw new NullPointerException(); - } - return a; - } - - public PrivilegedExceptionAction wrap(PrivilegedExceptionAction a) - { - if (a == null) { - throw new NullPointerException(); - } - return a; - } - - public AccessControlContext getAccessControlContext() { - return acc; - } - }; + return new SecurityContextImpl(acc); } /** @@ -982,4 +963,48 @@ public final class Security { return getClassContext()[2]; } } + + private static class SecurityContextImpl implements SecurityContext { + + private final AccessControlContext acc; + private final int hashCode; + + public SecurityContextImpl(AccessControlContext acc) { + this.acc = acc; + int hash = 7; + hash = 23 * hash + (this.acc != null ? this.acc.hashCode() : 0); + hashCode = hash; + } + + public <T> PrivilegedAction<T> wrap(PrivilegedAction<T> a) { + if (a == null) { + throw new NullPointerException(); + } + return a; + } + + public <T> PrivilegedExceptionAction<T> wrap(PrivilegedExceptionAction<T> a) + { + if (a == null) { + throw new NullPointerException(); + } + return a; + } + + public AccessControlContext getAccessControlContext() { + return acc; + } + + @Override + public int hashCode() { + return hashCode; + } + + @Override + public boolean equals(Object o){ + if (!(o instanceof SecurityContextImpl)) return false; + SecurityContext that = (SecurityContext) o; + return getAccessControlContext().equals(that.getAccessControlContext()); + } + } } Modified: river/jtsk/skunk/peterConcurrentPolicy/src/net/jini/security/SecurityContext.java URL: http://svn.apache.org/viewvc/river/jtsk/skunk/peterConcurrentPolicy/src/net/jini/security/SecurityContext.java?rev=1231803&r1=1231802&r2=1231803&view=diff ============================================================================== --- river/jtsk/skunk/peterConcurrentPolicy/src/net/jini/security/SecurityContext.java (original) +++ river/jtsk/skunk/peterConcurrentPolicy/src/net/jini/security/SecurityContext.java Mon Jan 16 00:26:33 2012 @@ -51,7 +51,11 @@ import java.security.PrivilegedException * AccessController.doPrivileged( * ctx.wrap(action), ctx.getAccessControlContext()); * </pre> - * + * + * <BOLD> + * Implementations must override Object equals and hashCode. + * </BOLD> + * * @author Sun Microsystems, Inc. * * @since 2.0 @@ -71,12 +75,13 @@ public interface SecurityContext { * <code>run</code> method is propagated through the <code>run</code> * method of the wrapper action. * + * @param <T> return type of PrivilegedAction * @param action the action to be wrapped * @return security context-restoring action wrapping <code>action</code>, * or <code>action</code> if no wrapping is necessary * @throws NullPointerException if <code>action</code> is <code>null</code> */ - PrivilegedAction wrap(PrivilegedAction action); + <T> PrivilegedAction<T> wrap(PrivilegedAction<T> action); /** * Returns a security context-restoring @@ -91,12 +96,13 @@ public interface SecurityContext { * thrown by the wrapped action's <code>run</code> method is propagated * through the <code>run</code> method of the wrapper action. * + * @param <T> return type of PrivilegedExceptionAction * @param action the action to be wrapped * @return security context-restoring action wrapping <code>action</code>, * or <code>action</code> if no wrapping is necessary * @throws NullPointerException if <code>action</code> is <code>null</code> */ - PrivilegedExceptionAction wrap(PrivilegedExceptionAction action); + <T> PrivilegedExceptionAction<T> wrap(PrivilegedExceptionAction<T> action); /** * Returns access control context portion of snapshotted security context. Modified: river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/DelegateCombinerSecurityManager.java URL: http://svn.apache.org/viewvc/river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/DelegateCombinerSecurityManager.java?rev=1231803&r1=1231802&r2=1231803&view=diff ============================================================================== --- river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/DelegateCombinerSecurityManager.java (original) +++ river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/DelegateCombinerSecurityManager.java Mon Jan 16 00:26:33 2012 @@ -47,18 +47,20 @@ import java.util.concurrent.RunnableFutu import java.util.concurrent.SynchronousQueue; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicBoolean; import java.util.logging.Level; import java.util.logging.Logger; +import net.jini.security.Security; +import net.jini.security.SecurityContext; import org.apache.river.api.delegates.DelegatePermission; import org.apache.river.impl.util.RC; import org.apache.river.impl.util.Ref; import org.apache.river.impl.util.Referrer; /** - * DelegateCombinerSecurityManager, is intended to be a high performance - * SecurityManager implementation that weakly caches the results of security checks - * for each AccessControlContext. + * DelegateCombinerSecurityManager, is intended to be a highly scalable + * SecurityManager implementation that softly caches the results of security checks + * for each context, which may be an instance of SecurityContext or + * AccessControlContext. * * This SecurityManager should be tuned for garbage collection for a large * young generation heap, since many young objects are created and discarded. @@ -66,23 +68,27 @@ import org.apache.river.impl.util.Referr * It is recommended that this SecurityManager be installed from the command * line in order to load as early as possible. * + * @see Security + * @see SecurityContext + * @see AccessControlContext + * * @author Peter Firmstone */ public class DelegateCombinerSecurityManager extends SecurityManager implements DelegateSecurityManager { - + private static final Logger logger = Logger.getLogger(DelegateCombinerSecurityManager.class.getName()); private final DomainCombiner dc; // Cache of optimised Delegate AccessControlContext's private final ConcurrentMap<AccessControlContext, AccessControlContext> contextCache; - private final ConcurrentMap<AccessControlContext, NavigableSet<Permission>> checked; + private final ConcurrentMap<Object, NavigableSet<Permission>> checked; private final Guard g; private final Action action; private final Executor executor; private final Comparator<Referrer<Permission>> permCompare; private final AccessControlContext SMConstructorContext; private final AccessControlContext SMPrivilegedContext; - private final Guard createAccPerm; - private final Logger logger; + private final ThreadLocal<SecurityContext> threadContext; + private final ThreadLocal<Boolean> inTrustedCodeRecursiveCall; public DelegateCombinerSecurityManager(){ super(); @@ -98,12 +104,12 @@ extends SecurityManager implements Deleg new ConcurrentHashMap<Referrer<AccessControlContext>, Referrer<AccessControlContext>>(100); contextCache = RC.concurrentMap(internal, Ref.SOFT, Ref.STRONG); - ConcurrentMap<Referrer<AccessControlContext>, Referrer<NavigableSet<Permission>>> refmap - = new ConcurrentHashMap<Referrer<AccessControlContext>, + ConcurrentMap<Referrer<Object>, Referrer<NavigableSet<Permission>>> refmap + = new ConcurrentHashMap<Referrer<Object>, Referrer<NavigableSet<Permission>>>(100); checked = RC.concurrentMap(refmap, Ref.SOFT, Ref.STRONG); g = new SecurityPermission("getPolicy"); - createAccPerm = new SecurityPermission("createAccessControlContext"); + Permission createAccPerm = new SecurityPermission("createAccessControlContext"); action = new Action(); // Make this a tunable property. double blocking_coefficient = 0.6; // 0 CPU intensive to 0.9 IO intensive @@ -121,27 +127,84 @@ extends SecurityManager implements Deleg TimeUnit.SECONDS, new SynchronousQueue<Runnable>(), new ThreadPoolExecutor.CallerRunsPolicy()); permCompare = RC.comparator(new PermissionComparator()); - logger = Logger.getLogger(DelegateCombinerSecurityManager.class.getName()); - // Get the policy & refresh, if it hasn't been initialized. + threadContext = new ThreadLocal<SecurityContext>(); + inTrustedCodeRecursiveCall = new ThreadLocal<Boolean>(); + /* Get the policy & refresh, in case it hasn't been initialized. + * While there is no SecurityManager, + * no policy checks are performed, however the policy must be in a + * constructed working state, before the SecurityManager is set, + * otherwise the Policy, if it's a non jvm policy, won't have permission + * to read the properties and files it needs in order to be constructed. + */ Policy policy = java.security.Policy.getPolicy(); // This is to avoid unnecessarily refreshing the policy. - if (!policy.implies(context[0], (Permission) createAccPerm)) policy.refresh(); - // Bug ID: 7093090 Reduce synchronization in java.security.Policy.getPolicyNoCheck + if (!policy.implies(context[0], createAccPerm)) policy.refresh(); + /* Bug ID: 7093090 Reduce synchronization in java.security.Policy.getPolicyNoCheck + * This bug may cause contention between ProtectionDomain implies + * calls, also it could be a point of attack for Denial of service, + * since the lock used is a static class lock. This bug has been fixed + * in jdk7. + */ } + /** + * Throws a <code>SecurityException</code> if the requested + * access, specified by the given permission, is not permitted based + * on the security policy currently in effect. + * + * This method obtains the current SecurityContext and checks + * the give permission in that context. + * + * @see SecurityContext + * @see Security + * @param perm + * @throws SecurityException + */ + @Override public void checkPermission(Permission perm) throws SecurityException { - checkPermission(perm, AccessController.getContext()); + Object context = null; + Boolean call = inTrustedCodeRecursiveCall.get(); + if (call == Boolean.TRUE) return; // In Security and Policy static methods we trust. + inTrustedCodeRecursiveCall.set(Boolean.TRUE); + try { + context = Security.getContext(); + }finally { + inTrustedCodeRecursiveCall.set(Boolean.FALSE); // Must always happen, no matter what. + } + checkPermission(perm, context); } + /** + * Throws a <code>SecurityException</code> if the requested + * access, specified by the given permission and context, is not permitted based + * on the security policy currently in effect. + * + * It is absolutely essential that the SecurityContext override equals + * and hashCode. + * + * @param perm + * @param context - AccessControlContext or SecurityContext + * @throws SecurityException + */ @Override public void checkPermission(Permission perm, Object context) throws SecurityException { - if (!(context instanceof AccessControlContext)) throw new SecurityException(); - if (perm == null ) throw new NullPointerException("Permission Collection null"); + if (perm == null ) throw new NullPointerException("Permission Collection null"); + AccessControlContext executionContext = null; + SecurityContext securityContext = null; + if (context instanceof AccessControlContext){ + executionContext = (AccessControlContext) context; + } else if (context instanceof SecurityContext){ + securityContext = (SecurityContext) context; + executionContext = securityContext.getAccessControlContext(); + } else { + throw new SecurityException(); + } + threadContext.set(securityContext); // may be null. /* The next line speeds up permission checks related to this SecurityManager. */ - if ( SMPrivilegedContext.equals(context) || SMConstructorContext.equals(context)) return; // prevents endless loop in debug. - AccessControlContext executionContext = (AccessControlContext) context; + if ( SMPrivilegedContext.equals(executionContext) || + SMConstructorContext.equals(executionContext)) return; // prevents endless loop in debug. // Checks if Permission has already been checked for this context. - NavigableSet<Permission> checkedPerms = checked.get(executionContext); + NavigableSet<Permission> checkedPerms = checked.get(context); if (checkedPerms == null){ /* A ConcurrentSkipListSet is used to avoid blocking during * removal operations that occur while the garbage collector @@ -164,25 +227,17 @@ extends SecurityManager implements Deleg NavigableSet<Referrer<Permission>> internal = new ConcurrentSkipListSet<Referrer<Permission>>(permCompare); checkedPerms = RC.navigableSet(internal, Ref.SOFT); - NavigableSet<Permission> existed = checked.putIfAbsent(executionContext, checkedPerms); + NavigableSet<Permission> existed = checked.putIfAbsent(context, checkedPerms); if (existed != null) checkedPerms = existed; } if (checkedPerms.contains(perm)) return; // don't need to check again. // Cache the created AccessControlContext. AccessControlContext delegateContext = contextCache.get(executionContext); if (delegateContext == null ) { - /* It is not possible to "create" a delegate AccessControlContext - * for checking permission to create an AccessControlContext - * with DomainCombiner, it creates a recursive loop. In this - * case just use the executionContext. - */ - if (createAccPerm.equals(perm)){ - delegateContext = executionContext; - } else { - final AccessControlContext finalExecutionContext = executionContext; - // Create a new AccessControlContext with the DelegateDomainCombiner - // we don't need to preserve the Subject accross the call - // we have sufficient privilege. + final AccessControlContext finalExecutionContext = executionContext; + // Create a new AccessControlContext with the DelegateDomainCombiner + inTrustedCodeRecursiveCall.set(Boolean.TRUE); + try { delegateContext = AccessController.doPrivileged( new PrivilegedAction<AccessControlContext>(){ public AccessControlContext run() { @@ -190,24 +245,24 @@ extends SecurityManager implements Deleg } } ); - // Optimise the delegateContext, this runs the DelegateDomainCombiner - // and returns the AccessControlContext. - // This is a mutator method, the delegateContext returned - // is actually the same object passed in, after it is - // mutated, but just in case that changes in future we - // return it. - delegateContext = AccessController.doPrivileged(action, delegateContext); - contextCache.putIfAbsent(executionContext, delegateContext); - // Above putIfAbsent: It doesn't matter if it already existed, - // the context we have is valid to perform a permissionCheck. + }finally { + inTrustedCodeRecursiveCall.set(Boolean.FALSE); // Must always happen, no matter what. } + // Optimise the delegateContext, this runs the DelegateDomainCombiner + // and returns the AccessControlContext. + // This is a mutator method, the delegateContext returned + // is actually the same object passed in, after it is + // mutated, but just in case that changes in future we + // return it. + delegateContext = AccessController.doPrivileged(action, delegateContext); + contextCache.putIfAbsent(executionContext, delegateContext); + // Above putIfAbsent: It doesn't matter if it already existed, + // the context we have is valid to perform a permissionCheck. } // Normal execution, same as SecurityManager. delegateContext.checkPermission(perm); // Throws SecurityException. /* It's ok to cache SocketPermission if we use a comparator */ - // If we get to here, no exceptions were thrown, we have permission. - // Don't cache SocketPermission. - // if (perm instanceof SocketPermission) return; + // If we get to here, no exceptions were thrown, caller has permission. checkedPerms.add(perm); } @@ -271,6 +326,8 @@ extends SecurityManager implements Deleg * are from the Context that the SecurityManager has been asked * to check. * + * assignedDomains are inherited domains. + * * This code wraps assignedDomains in a DelegateProtectionDomain * to ensure we check for the DelegatePermission or it's candidate * Permission. @@ -298,12 +355,24 @@ extends SecurityManager implements Deleg private final ProtectionDomain[] context; DelegateProtectionDomain(ProtectionDomain[] context){ - // Use static domain so we don't strong reference to ClassLoader + // Use static domain so we don't strongly reference the ClassLoader // which has a strong reference to ProtectionDomain. super(null, null); this.context = context; // Not mutated so don't need to clone. } + /* An earlier implementation used interruption to cancel running tasks, + * this interruption only added complexity, in most cases permission + * checks are expected to pass and failure occurs far less often, + * for that reason, it is acceptable for all tasks to run to completion. + * The overall performance cost of using task interruption was likely + * greater, due to increased access of shared memory for only a small + * performance benefit for failling permission checks. + * + * If the current thread is interrupted, the interrupt status is + * preserved, this is done in cases where permission is required to perform + * safe shutdown + */ @Override public boolean implies(Permission perm) { Thread currentThread = Thread.currentThread(); @@ -327,10 +396,9 @@ extends SecurityManager implements Deleg } CountDownLatch latch = new CountDownLatch(l); List<RunnableFuture<Boolean>> resultList = new ArrayList<RunnableFuture<Boolean>>(l); - AtomicBoolean terminated = new AtomicBoolean(false); for ( int i = 0; i < l; i++ ){ resultList.add(new FutureTask<Boolean>( - new PermissionCheck(context[i], perm, latch, currentThread, terminated) + new PermissionCheck(context[i], perm, latch, threadContext.get()) )); } Iterator<RunnableFuture<Boolean>> it = resultList.iterator(); @@ -354,23 +422,15 @@ extends SecurityManager implements Deleg } catch (ExecutionException ex) { // This should never happen, unless a runtime exception occurs. if (logger.isLoggable(Level.SEVERE)) logger.log(Level.SEVERE, null, ex); + throw new RuntimeException("Unrecoverable: ", ex.getCause()); // Bail out. } } catch (InterruptedException ex) { - // REMIND: Java Memory Model and thread interruption. - if (terminated.get()){ - /* Interrupted by a task returning false */ - it = resultList.iterator(); - while (it.hasNext()){ - it.next().cancel(true); - } - if (interrupt) currentThread.interrupt(); - return false; - } + // REMIND: Java Memory Model and thread interruption. // We've been externally interrupted, during execution. - // Do this the slow way! + // Do this the slow way to avoid reinterruption during shutdown cleanup! if (logger.isLoggable(Level.FINEST)) logger.log(Level.FINEST, "External Interruption", ex); for ( int i = 0; i < l; i++ ){ - if (! checkPermission(context[i], perm)) { + if (!checkPermission(context[i], perm)) { currentThread.interrupt(); // restore external interrupt. return false; } @@ -378,8 +438,6 @@ extends SecurityManager implements Deleg currentThread.interrupt(); // restore external interrupt. return true; } - if (interrupt) currentThread.interrupt(); - return false; } @Override @@ -407,54 +465,43 @@ extends SecurityManager implements Deleg private final ProtectionDomain pd; private final Permission p; private final CountDownLatch latch; - private final Thread callThread; - private final AtomicBoolean terminated; - private final ClassLoader contextClassLoader; // Required for AggregatePolicyProvider. + private final SecurityContext securityContext; // Preserves context accross calls. - PermissionCheck(ProtectionDomain pd, Permission p, CountDownLatch c, Thread caller, AtomicBoolean terminated){ + PermissionCheck(ProtectionDomain pd, Permission p, CountDownLatch c, SecurityContext sc){ if (pd == null || p == null) throw new NullPointerException(); this.pd = pd; this.p = p; latch = c; - this.callThread = caller; - this.terminated = terminated; - contextClassLoader = AccessController.doPrivileged(new PrivilegedAction<ClassLoader>(){ - public ClassLoader run() { - return callThread.getContextClassLoader(); - } - }); + securityContext = sc; + } public Boolean call() throws Exception { // Required for AggregatePolicyProvider. - AccessController.doPrivileged(new PrivilegedAction(){ - public Object run() { - Thread.currentThread().setContextClassLoader(contextClassLoader); - return null; - } - }); - boolean result = checkPermission(pd, p); - // If we need to check for any Permission that we have substituted - // for a standard jvm permission, getPermissions and convert, - // then test here for static ProtectionDomain's. - if (!result) { - // This only allows one task to terminate the caller, provided - // that no external interruption has occurred. The interrupt - // status is cleared by the InterruptedException, - // preventing late terminating tasks from re-interrupting - // during cancellation initiated by the caller. - // The first task to return false initiates early termination - // of the other tasks. - // Is it ok to interrupt our own thread if under load. - if (terminated.compareAndSet(callThread.isInterrupted(), true)) callThread.interrupt(); // Not atomic - } + Boolean result = AccessController.doPrivileged( + securityContext != null ? + securityContext.wrap( + new PrivilegedAction<Boolean>(){ + public Boolean run() { + boolean result = checkPermission(pd, p); + return Boolean.valueOf(result); + } + } + ) + :new PrivilegedAction<Boolean>(){ + public Boolean run() { + boolean result = checkPermission(pd, p); + return Boolean.valueOf(result); + } + } + ); latch.countDown(); return result; } } - static boolean checkPermission(ProtectionDomain pd, Permission p){ + private static boolean checkPermission(ProtectionDomain pd, Permission p){ boolean result = pd.implies(p); if (!result && p instanceof DelegatePermission ){ Permission candidate = ((DelegatePermission)p).getPermission(); Modified: river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/PermissionComparator.java URL: http://svn.apache.org/viewvc/river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/PermissionComparator.java?rev=1231803&r1=1231802&r2=1231803&view=diff ============================================================================== --- river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/PermissionComparator.java (original) +++ river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/PermissionComparator.java Mon Jan 16 00:26:33 2012 @@ -33,8 +33,10 @@ import java.util.Comparator; * * Class is sorted by class hashcode. * - * Name is sorted using Unicode character order, so wildcards "*" and - * characters will preceed numbers, which will preceed letters. + * Name is sorted using Unicode character order, so wildcards "*" will + * preceed numbers, which will preceed letters. + * + * UnresolvedPermission is a special case. * * The comparator must be as fast as possible, the common case is not equal, * so that must be very fast. Modified: river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/RC.java URL: http://svn.apache.org/viewvc/river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/RC.java?rev=1231803&r1=1231802&r2=1231803&view=diff ============================================================================== --- river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/RC.java (original) +++ river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/RC.java Mon Jan 16 00:26:33 2012 @@ -166,7 +166,7 @@ public class RC { * @return */ public static <T> Collection<T> collection(Collection<Referrer<T>> internal, Ref type){ - return new ReferenceCollection<T>(internal, type, false); + return new ReferenceCollection<T>(internal, type, true); } // /** @@ -193,7 +193,7 @@ public class RC { * @return */ public static <T> List<T> list(List<Referrer<T>> internal, Ref type){ - return new ReferenceList<T>(internal, type); + return new ReferenceList<T>(internal, type, true); } /** @@ -206,7 +206,7 @@ public class RC { * @return */ public static <T> Set<T> set(Set<Referrer<T>> internal, Ref type){ - return new ReferenceSet<T>(internal, type); + return new ReferenceSet<T>(internal, type, true); } /** * Wrap a SortedSet for holding references so it appears as a SortedSet @@ -219,7 +219,7 @@ public class RC { */ public static <T> SortedSet<T> sortedSet( SortedSet<Referrer<T>> internal, Ref type){ - return new ReferenceSortedSet<T>(internal, type); + return new ReferenceSortedSet<T>(internal, type, true); } /** * Wrap a NavigableSet for holding references so it appears as a NavigableSet @@ -232,7 +232,7 @@ public class RC { */ public static <T> NavigableSet<T> navigableSet( NavigableSet<Referrer<T>> internal, Ref type){ - return new ReferenceNavigableSet<T>(internal, type); + return new ReferenceNavigableSet<T>(internal, type, true); } /** * Wrap a Queue for holding references so it appears as a Queue @@ -244,7 +244,7 @@ public class RC { * @return */ public static <T> Queue<T> queue(Queue<Referrer<T>> internal, Ref type){ - return new ReferencedQueue<T>(internal, type); + return new ReferencedQueue<T>(internal, type, true); } /** * Wrap a Deque for holding references so it appears as a Deque @@ -256,7 +256,7 @@ public class RC { * @return */ public static <T> Deque<T> deque(Deque<Referrer<T>> internal, Ref type){ - return new ReferenceDeque<T>(internal, type); + return new ReferenceDeque<T>(internal, type, true); } /** * Wrap a BlockingQueue for holding references so it appears as a BlockingQueue @@ -269,7 +269,7 @@ public class RC { */ public static <T> BlockingQueue<T> blockingQueue( BlockingQueue<Referrer<T>> internal, Ref type){ - return new ReferenceBlockingQueue<T>(internal, type); + return new ReferenceBlockingQueue<T>(internal, type, true); } /** * Wrap a BlockingDeque for holding references so it appears as a BlockingDeque @@ -282,7 +282,7 @@ public class RC { */ public static <T> BlockingDeque<T> blockingDeque( BlockingDeque<Referrer<T>> internal, Ref type){ - return new ReferenceBlockingDeque<T>(internal, type); + return new ReferenceBlockingDeque<T>(internal, type, true); } /** * Wrap a Map for holding references so it appears as a Map @@ -297,7 +297,7 @@ public class RC { */ public static <K, V> Map<K, V> map( Map<Referrer<K>, Referrer<V>> internal, Ref key, Ref value){ - return new ReferenceMap<K, V>(internal, key, value); + return new ReferenceMap<K, V>(internal, key, value, true); } /** * Wrap a SortedMap for holding references so it appears as a SortedMap @@ -312,7 +312,7 @@ public class RC { */ public static <K, V> SortedMap<K, V> sortedMap( SortedMap<Referrer<K>, Referrer<V>> internal, Ref key, Ref value){ - return new ReferenceSortedMap<K, V>(internal, key, value); + return new ReferenceSortedMap<K, V>(internal, key, value, true); } /** * Wrap a NavigableMap for holding Referrers so it appears as a NavigableMap @@ -327,7 +327,7 @@ public class RC { */ public static <K, V> NavigableMap<K, V> navigableMap( NavigableMap<Referrer<K>, Referrer<V>> internal, Ref key, Ref value){ - return new ReferenceNavigableMap<K, V>(internal, key, value); + return new ReferenceNavigableMap<K, V>(internal, key, value, true); } /** * Wrap a ConcurrentMap for holding references so it appears as a ConcurrentMap @@ -342,7 +342,7 @@ public class RC { */ public static <K, V> ConcurrentMap<K, V> concurrentMap( ConcurrentMap<Referrer<K>, Referrer<V>> internal, Ref key, Ref value){ - return new ReferenceConcurrentMap<K, V>(internal, key, value); + return new ReferenceConcurrentMap<K, V>(internal, key, value, true); } /** @@ -358,6 +358,6 @@ public class RC { */ public static <K, V> ConcurrentNavigableMap<K, V> concurrentNavigableMap( ConcurrentNavigableMap<Referrer<K>, Referrer<V>> internal, Ref key, Ref value){ - return new ReferenceConcurrentNavigableMap<K, V>(internal, key, value); + return new ReferenceConcurrentNavigableMap<K, V>(internal, key, value, true); } } Modified: river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferenceBlockingDeque.java URL: http://svn.apache.org/viewvc/river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferenceBlockingDeque.java?rev=1231803&r1=1231802&r2=1231803&view=diff ============================================================================== --- river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferenceBlockingDeque.java (original) +++ river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferenceBlockingDeque.java Mon Jan 16 00:26:33 2012 @@ -33,8 +33,8 @@ class ReferenceBlockingDeque<T> extends private final BlockingDeque<Referrer<T>> deque; - ReferenceBlockingDeque(BlockingDeque<Referrer<T>> deque, Ref type){ - super(deque, type); + ReferenceBlockingDeque(BlockingDeque<Referrer<T>> deque, Ref type, boolean gcThreads){ + super(deque, type, gcThreads); this.deque = deque; } Modified: river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferenceBlockingQueue.java URL: http://svn.apache.org/viewvc/river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferenceBlockingQueue.java?rev=1231803&r1=1231802&r2=1231803&view=diff ============================================================================== --- river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferenceBlockingQueue.java (original) +++ river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferenceBlockingQueue.java Mon Jan 16 00:26:33 2012 @@ -33,8 +33,8 @@ class ReferenceBlockingQueue<T> extends private static final long serialVersionUID = 1L; private final BlockingQueue<Referrer<T>> queue; - ReferenceBlockingQueue(BlockingQueue<Referrer<T>> queue, Ref type){ - super(queue, type); + ReferenceBlockingQueue(BlockingQueue<Referrer<T>> queue, Ref type, boolean gcThreads){ + super(queue, type, gcThreads); this.queue = queue; } Modified: river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferenceCollection.java URL: http://svn.apache.org/viewvc/river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferenceCollection.java?rev=1231803&r1=1231802&r2=1231803&view=diff ============================================================================== --- river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferenceCollection.java (original) +++ river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferenceCollection.java Mon Jan 16 00:26:33 2012 @@ -65,11 +65,11 @@ class ReferenceCollection<T> extends Abs private final Ref type; ReferenceCollection(Collection<Referrer<T>> col, Ref type, boolean gcThread){ - this(col, new ReferenceProcessor<T>(col, type, type == Ref.STRONG ? null : new ReferenceQueue<T>(), false), type, false); + this(col, new ReferenceProcessor<T>(col, type, type == Ref.STRONG ? null : new ReferenceQueue<T>(), gcThread), type); } ReferenceCollection(Collection<Referrer<T>> col, - ReferenceQueuingFactory<T, Referrer<T>> rqf, Ref type, boolean gcThread){ + ReferenceQueuingFactory<T, Referrer<T>> rqf, Ref type){ this.col = col; this.rqf = rqf; this.type = type; Modified: river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferenceConcurrentMap.java URL: http://svn.apache.org/viewvc/river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferenceConcurrentMap.java?rev=1231803&r1=1231802&r2=1231803&view=diff ============================================================================== --- river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferenceConcurrentMap.java (original) +++ river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferenceConcurrentMap.java Mon Jan 16 00:26:33 2012 @@ -54,8 +54,8 @@ class ReferenceConcurrentMap<K, V> exten // ConcurrentMap must be protected from null values? It changes it's behaviour, is that a problem? private final ConcurrentMap<Referrer<K>, Referrer<V>> map; - ReferenceConcurrentMap(ConcurrentMap<Referrer<K>,Referrer<V>> map, Ref key, Ref val){ - super (map, key, val); + ReferenceConcurrentMap(ConcurrentMap<Referrer<K>,Referrer<V>> map, Ref key, Ref val, boolean gcThreads){ + super (map, key, val, gcThreads); this.map = map; } Modified: river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferenceConcurrentNavigableMap.java URL: http://svn.apache.org/viewvc/river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferenceConcurrentNavigableMap.java?rev=1231803&r1=1231802&r2=1231803&view=diff ============================================================================== --- river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferenceConcurrentNavigableMap.java (original) +++ river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferenceConcurrentNavigableMap.java Mon Jan 16 00:26:33 2012 @@ -33,8 +33,8 @@ class ReferenceConcurrentNavigableMap<K, extends ReferenceConcurrentMap<K,V> implements ConcurrentNavigableMap<K,V>{ private final ConcurrentNavigableMap<Referrer<K>,Referrer<V>> map; - ReferenceConcurrentNavigableMap(ConcurrentNavigableMap<Referrer<K>, Referrer<V>> map, Ref keyRef, Ref valRef){ - super(map, keyRef, valRef); + ReferenceConcurrentNavigableMap(ConcurrentNavigableMap<Referrer<K>, Referrer<V>> map, Ref keyRef, Ref valRef, boolean gcThreads){ + super(map, keyRef, valRef, gcThreads); this.map = map; } Modified: river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferenceDeque.java URL: http://svn.apache.org/viewvc/river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferenceDeque.java?rev=1231803&r1=1231802&r2=1231803&view=diff ============================================================================== --- river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferenceDeque.java (original) +++ river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferenceDeque.java Mon Jan 16 00:26:33 2012 @@ -30,8 +30,8 @@ import java.util.Iterator; class ReferenceDeque<T> extends ReferencedQueue<T> implements Deque<T>{ private static final long serialVersionUID = 1L; private final Deque<Referrer<T>> deque; - ReferenceDeque(Deque<Referrer<T>> deque, Ref type){ - super(deque, type); + ReferenceDeque(Deque<Referrer<T>> deque, Ref type, boolean gcThreads){ + super(deque, type, gcThreads); this.deque = deque; } Modified: river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferenceList.java URL: http://svn.apache.org/viewvc/river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferenceList.java?rev=1231803&r1=1231802&r2=1231803&view=diff ============================================================================== --- river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferenceList.java (original) +++ river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferenceList.java Mon Jan 16 00:26:33 2012 @@ -48,13 +48,13 @@ import java.util.ListIterator; class ReferenceList<T> extends ReferenceCollection<T> implements List<T> { private static final long serialVersionUID = 1L; private final List<Referrer<T>> list; - ReferenceList(List<Referrer<T>> list, Ref type){ - super(list, type, false); + ReferenceList(List<Referrer<T>> list, Ref type, boolean gcThreads){ + super(list, type, gcThreads); this.list = list; } ReferenceList(List<Referrer<T>> list, ReferenceQueuingFactory<T, Referrer<T>> rqf, Ref type){ - super(list, rqf, type, false); + super(list, rqf, type); this.list = list; } Modified: river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferenceMap.java URL: http://svn.apache.org/viewvc/river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferenceMap.java?rev=1231803&r1=1231802&r2=1231803&view=diff ============================================================================== --- river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferenceMap.java (original) +++ river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferenceMap.java Mon Jan 16 00:26:33 2012 @@ -66,10 +66,10 @@ class ReferenceMap<K, V> extends Abstrac private final Set<K> keys; private final Set<Entry<K,V>> entrys; - ReferenceMap(Map<Referrer<K>,Referrer<V>> map, Ref key, Ref val){ + ReferenceMap(Map<Referrer<K>,Referrer<V>> map, Ref key, Ref val, boolean gcThreads){ this(map, - new ReferenceProcessor<K>(map.keySet(), key, new ReferenceQueue<K>(), false), - new ReferenceProcessor<V>(map.values(), val, new ReferenceQueue<V>(), false), + new ReferenceProcessor<K>(map.keySet(), key, new ReferenceQueue<K>(), gcThreads), + new ReferenceProcessor<V>(map.values(), val, new ReferenceQueue<V>(), gcThreads), key, val ); } @@ -80,7 +80,7 @@ class ReferenceMap<K, V> extends Abstrac this.vrqf = vrqf; this.key = key; this.val = val; - values = new ReferenceCollection<V>(this.map.values(), vrqf, val, false); + values = new ReferenceCollection<V>(this.map.values(), vrqf, val); keys = new ReferenceSet<K>(this.map.keySet(), krqf, key); // We let this escape during construction, but it's package private only // and doesn't escape the package. Modified: river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferenceNavigableMap.java URL: http://svn.apache.org/viewvc/river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferenceNavigableMap.java?rev=1231803&r1=1231802&r2=1231803&view=diff ============================================================================== --- river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferenceNavigableMap.java (original) +++ river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferenceNavigableMap.java Mon Jan 16 00:26:33 2012 @@ -18,7 +18,6 @@ package org.apache.river.impl.util; -import java.lang.ref.Reference; import java.util.Map.Entry; import java.util.NavigableMap; import java.util.NavigableSet; @@ -30,8 +29,8 @@ import java.util.NavigableSet; class ReferenceNavigableMap<K,V> extends ReferenceSortedMap<K,V> implements NavigableMap<K,V> { private final NavigableMap<Referrer<K>, Referrer<V>> map; - ReferenceNavigableMap(NavigableMap<Referrer<K>, Referrer<V>> map, Ref keyRef, Ref valRef){ - super(map, keyRef, valRef); + ReferenceNavigableMap(NavigableMap<Referrer<K>, Referrer<V>> map, Ref keyRef, Ref valRef, boolean gcThreads){ + super(map, keyRef, valRef, gcThreads); this.map = map; } Modified: river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferenceNavigableSet.java URL: http://svn.apache.org/viewvc/river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferenceNavigableSet.java?rev=1231803&r1=1231802&r2=1231803&view=diff ============================================================================== --- river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferenceNavigableSet.java (original) +++ river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferenceNavigableSet.java Mon Jan 16 00:26:33 2012 @@ -33,8 +33,8 @@ public class ReferenceNavigableSet<T> private static final long serialVersionUID = 1L; private final NavigableSet<Referrer<T>> set; - public ReferenceNavigableSet(NavigableSet<Referrer<T>> set, Ref type){ - super(set, type); + public ReferenceNavigableSet(NavigableSet<Referrer<T>> set, Ref type, boolean gcThreads){ + super(set, type, gcThreads); this.set = set; } Modified: river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferenceSet.java URL: http://svn.apache.org/viewvc/river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferenceSet.java?rev=1231803&r1=1231802&r2=1231803&view=diff ============================================================================== --- river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferenceSet.java (original) +++ river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferenceSet.java Mon Jan 16 00:26:33 2012 @@ -33,12 +33,12 @@ import java.util.Set; class ReferenceSet<T> extends ReferenceCollection<T> implements Set<T>{ private static final long serialVersionUID = 1L; - ReferenceSet(Set<Referrer<T>> col, Ref type){ - super(col, type, false); + ReferenceSet(Set<Referrer<T>> col, Ref type, boolean gcThreads){ + super(col, type, gcThreads); } ReferenceSet(Set<Referrer<T>> col, ReferenceQueuingFactory<T, Referrer<T>> rqf, Ref type){ - super(col, rqf, type, false); + super(col, rqf, type); } private void readObject(ObjectInputStream stream) Modified: river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferenceSortedMap.java URL: http://svn.apache.org/viewvc/river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferenceSortedMap.java?rev=1231803&r1=1231802&r2=1231803&view=diff ============================================================================== --- river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferenceSortedMap.java (original) +++ river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferenceSortedMap.java Mon Jan 16 00:26:33 2012 @@ -31,8 +31,8 @@ import java.util.SortedMap; class ReferenceSortedMap<K,V> extends ReferenceMap<K,V> implements SortedMap<K,V>{ private SortedMap<Referrer<K>, Referrer<V>> map; - ReferenceSortedMap(SortedMap<Referrer<K>, Referrer<V>> map, Ref keyRef, Ref valRef){ - super(map, keyRef, valRef); + ReferenceSortedMap(SortedMap<Referrer<K>, Referrer<V>> map, Ref keyRef, Ref valRef, boolean gcThreads){ + super(map, keyRef, valRef, gcThreads); this.map = map; } Modified: river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferenceSortedSet.java URL: http://svn.apache.org/viewvc/river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferenceSortedSet.java?rev=1231803&r1=1231802&r2=1231803&view=diff ============================================================================== --- river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferenceSortedSet.java (original) +++ river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferenceSortedSet.java Mon Jan 16 00:26:33 2012 @@ -34,10 +34,11 @@ import java.util.SortedSet; * @author Peter Firmstone. */ class ReferenceSortedSet<T> extends ReferenceSet<T> implements SortedSet<T> { + private static final long serialVersionUID = 1L; private final SortedSet<Referrer<T>> set; - ReferenceSortedSet( SortedSet<Referrer<T>> set, Ref type){ - super(set, type); + ReferenceSortedSet( SortedSet<Referrer<T>> set, Ref type, boolean gcThreads){ + super(set, type, gcThreads); this.set = set; } Modified: river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferencedQueue.java URL: http://svn.apache.org/viewvc/river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferencedQueue.java?rev=1231803&r1=1231802&r2=1231803&view=diff ============================================================================== --- river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferencedQueue.java (original) +++ river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/util/ReferencedQueue.java Mon Jan 16 00:26:33 2012 @@ -31,8 +31,8 @@ public class ReferencedQueue<T> extends private static final long serialVersionUID = 1L; private final Queue<Referrer<T>> queue; - public ReferencedQueue( Queue<Referrer<T>> queue, Ref type){ - super(queue, type, false); + public ReferencedQueue( Queue<Referrer<T>> queue, Ref type, boolean gcThreads){ + super(queue, type, gcThreads); this.queue = queue; }
