You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@river.apache.org by pe...@apache.org on 2012/01/16 01:26:35 UTC

svn commit: r1231803 - in /river/jtsk/skunk/peterConcurrentPolicy: qa/src/com/sun/jini/qa/harness/ src/com/sun/jini/start/ src/net/jini/security/ src/org/apache/river/api/security/ src/org/apache/river/impl/util/

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;
     }