You are viewing a plain text version of this content. The canonical link for it is here.
Posted to scm@geronimo.apache.org by dj...@apache.org on 2005/11/08 23:17:34 UTC

svn commit: r331909 - in /geronimo/trunk/modules/connector/src: java/org/apache/geronimo/connector/outbound/ java/org/apache/geronimo/connector/outbound/transactionlog/ test/org/apache/geronimo/connector/outbound/ test/org/apache/geronimo/connector/out...

Author: djencks
Date: Tue Nov  8 14:17:25 2005
New Revision: 331909

URL: http://svn.apache.org/viewcvs?rev=331909&view=rev
Log:
GERONIMO-1125 implement lifecycle destroy method on connection interceptors, remove memory leak

Modified:
    geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/AbstractConnectionManager.java
    geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/AbstractSinglePoolConnectionInterceptor.java
    geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/ConnectionHandleInterceptor.java
    geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/ConnectionInterceptor.java
    geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/ConnectionTrackingInterceptor.java
    geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/LocalXAResourceInsertionInterceptor.java
    geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/MCFConnectionInterceptor.java
    geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/MultiPoolConnectionInterceptor.java
    geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/SinglePoolConnectionInterceptor.java
    geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/SinglePoolMatchAllConnectionInterceptor.java
    geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/SubjectInterceptor.java
    geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/TCCLInterceptor.java
    geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/ThreadLocalCachingConnectionInterceptor.java
    geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/TransactionCachingInterceptor.java
    geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/TransactionEnlistingInterceptor.java
    geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/XAResourceInsertionInterceptor.java
    geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/transactionlog/LogXAResourceInsertionInterceptor.java
    geronimo/trunk/modules/connector/src/test/org/apache/geronimo/connector/outbound/ConnectionInterceptorTestUtils.java
    geronimo/trunk/modules/connector/src/test/org/apache/geronimo/connector/outbound/connectiontracking/ConnectionTrackingCoordinatorTest.java

Modified: geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/AbstractConnectionManager.java
URL: http://svn.apache.org/viewcvs/geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/AbstractConnectionManager.java?rev=331909&r1=331908&r2=331909&view=diff
==============================================================================
--- geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/AbstractConnectionManager.java (original)
+++ geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/AbstractConnectionManager.java Tue Nov  8 14:17:25 2005
@@ -1,6 +1,6 @@
 /**
  *
- * Copyright 2004 The Apache Software Foundation
+ * Copyright 2004-2005 The Apache Software Foundation
  *
  *  Licensed under the Apache License, Version 2.0 (the "License");
  *  you may not use this file except in compliance with the License.
@@ -25,11 +25,12 @@
 
 import org.apache.geronimo.connector.outbound.connectionmanagerconfig.PoolingSupport;
 import org.apache.geronimo.transaction.manager.NamedXAResource;
+import org.apache.geronimo.gbean.GBeanLifecycle;
 
 /**
  * @version $Rev$ $Date$
  */
-public abstract class AbstractConnectionManager implements ConnectionManagerContainer, ConnectionManager, LazyAssociatableConnectionManager, PoolingAttributes {
+public abstract class AbstractConnectionManager implements ConnectionManagerContainer, ConnectionManager, LazyAssociatableConnectionManager, PoolingAttributes, GBeanLifecycle {
     protected final Interceptors interceptors;
 
     //default constructor for use as endpoint
@@ -157,4 +158,15 @@
         PoolingSupport getPoolingAttributes();
     }
 
+    public void doStart() throws Exception {
+
+    }
+
+    public void doStop() throws Exception {
+        interceptors.getStack().destroy();
+    }
+
+    public void doFail() {
+        interceptors.getStack().destroy();
+    }
 }

Modified: geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/AbstractSinglePoolConnectionInterceptor.java
URL: http://svn.apache.org/viewcvs/geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/AbstractSinglePoolConnectionInterceptor.java?rev=331909&r1=331908&r2=331909&view=diff
==============================================================================
--- geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/AbstractSinglePoolConnectionInterceptor.java (original)
+++ geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/AbstractSinglePoolConnectionInterceptor.java Tue Nov  8 14:17:25 2005
@@ -1,6 +1,6 @@
 /**
  *
- * Copyright 2003-2004 The Apache Software Foundation
+ * Copyright 2003-2005 The Apache Software Foundation
  *
  *  Licensed under the Apache License, Version 2.0 (the "License");
  *  you may not use this file except in compliance with the License.
@@ -46,6 +46,7 @@
     protected Timer timer = PoolIdleReleaserTimer.getTimer();
     protected int minSize = 0;
     protected int shrinkLater = 0;
+    protected volatile boolean destroyed = false;
 
     public AbstractSinglePoolConnectionInterceptor(final ConnectionInterceptor next,
                                                    int maxSize,
@@ -91,6 +92,17 @@
         if (log.isTraceEnabled()) {
             log.trace("returning connection" + connectionInfo.getConnectionHandle());
         }
+
+        // not strictly synchronized with destroy(), but pooled operations in internalReturn() are...
+        if (destroyed) {
+            try {
+                connectionInfo.getManagedConnectionInfo().getManagedConnection().destroy();
+            }
+            catch (ResourceException re) {
+            }
+            return;
+        }
+
         try {
             resizeLock.readLock().acquire();
         } catch (InterruptedException e) {
@@ -115,6 +127,17 @@
 
     protected abstract boolean internalReturn(ConnectionInfo connectionInfo, ConnectionReturnAction connectionReturnAction);
 
+    protected abstract void internalDestroy();
+
+    // Cancel the IdleReleaser TimerTask (fixes memory leak) and clean up the pool
+    public void destroy() {
+        destroyed = true; 
+        if (idleReleaser != null)
+            idleReleaser.cancel();
+        internalDestroy();
+        next.destroy();
+    }
+    
     public int getPartitionCount() {
         return 1;
     }
@@ -199,12 +222,12 @@
         if (idleTimeoutMinutes < 0) {
             throw new IllegalArgumentException("idleTimeoutMinutes must be positive or 0, not " + idleTimeoutMinutes);
         }
-        if (idleReleaser != null) {
+        if (idleReleaser!= null) {
             idleReleaser.cancel();
         }
         if (idleTimeoutMinutes > 0) {
             this.idleTimeoutMilliseconds = idleTimeoutMinutes * 60 * 1000;
-            idleReleaser = new IdleReleaser();
+            idleReleaser = new IdleReleaser(this);
             timer.schedule(idleReleaser, this.idleTimeoutMilliseconds, this.idleTimeoutMilliseconds);
         }
     }
@@ -213,31 +236,49 @@
 
     protected abstract boolean addToPool(ManagedConnectionInfo mci);
 
-    private class IdleReleaser extends TimerTask {
-
+    // static class to permit chain of strong references from preventing ClassLoaders
+    // from being GC'ed.
+    private static class IdleReleaser extends TimerTask {
+        private AbstractSinglePoolConnectionInterceptor parent;
+
+        private IdleReleaser(AbstractSinglePoolConnectionInterceptor parent) {
+            this.parent = parent;
+        }
+     
+        public boolean cancel() {
+            this.parent = null;
+            return super.cancel();
+        }
+        
         public void run() {
+            // protect against interceptor being set to null mid-execution
+            AbstractSinglePoolConnectionInterceptor interceptor = parent;
+            if (interceptor == null) 
+                return;
             try {
-                resizeLock.readLock().acquire();
+                interceptor.resizeLock.readLock().acquire();
             } catch (InterruptedException e) {
                 return;
             }
             try {
-                long threshold = System.currentTimeMillis() - idleTimeoutMilliseconds;
-                ArrayList killList = new ArrayList(getPartitionMaxSize());
-                getExpiredManagedConnectionInfos(threshold, killList);
+                long threshold = System.currentTimeMillis() - interceptor.idleTimeoutMilliseconds;
+                ArrayList killList = new ArrayList(interceptor.getPartitionMaxSize());
+                interceptor.getExpiredManagedConnectionInfos(threshold, killList);
                 for (Iterator i = killList.iterator(); i.hasNext();) {
                     ManagedConnectionInfo managedConnectionInfo = (ManagedConnectionInfo) i.next();
                     ConnectionInfo killInfo = new ConnectionInfo(managedConnectionInfo);
-                    internalReturn(killInfo, ConnectionReturnAction.DESTROY);
+                    interceptor.internalReturn(killInfo, ConnectionReturnAction.DESTROY);
                 }
-                permits.release(killList.size());
+                interceptor.permits.release(killList.size());
             } finally {
-                resizeLock.readLock().release();
+                interceptor.resizeLock.readLock().release();
             }
         }
 
     }
 
+    // Currently only a short-lived (10 millisecond) task. 
+    // So, FillTask, unlike IdleReleaser, shouldn't cause GC problems.     
     protected class FillTask extends TimerTask {
         private final ManagedConnectionFactory managedConnectionFactory;
         private final Subject subject;

Modified: geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/ConnectionHandleInterceptor.java
URL: http://svn.apache.org/viewcvs/geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/ConnectionHandleInterceptor.java?rev=331909&r1=331908&r2=331909&view=diff
==============================================================================
--- geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/ConnectionHandleInterceptor.java (original)
+++ geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/ConnectionHandleInterceptor.java Tue Nov  8 14:17:25 2005
@@ -1,6 +1,6 @@
 /**
  *
- * Copyright 2003-2004 The Apache Software Foundation
+ * Copyright 2003-2005 The Apache Software Foundation
  *
  *  Licensed under the Apache License, Version 2.0 (the "License");
  *  you may not use this file except in compliance with the License.
@@ -71,4 +71,7 @@
         next.returnConnection(connectionInfo, connectionReturnAction);
     }
 
+    public void destroy() {
+        next.destroy();
+    }
 }

Modified: geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/ConnectionInterceptor.java
URL: http://svn.apache.org/viewcvs/geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/ConnectionInterceptor.java?rev=331909&r1=331908&r2=331909&view=diff
==============================================================================
--- geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/ConnectionInterceptor.java (original)
+++ geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/ConnectionInterceptor.java Tue Nov  8 14:17:25 2005
@@ -1,6 +1,6 @@
 /**
  *
- * Copyright 2003-2004 The Apache Software Foundation
+ * Copyright 2003-2005 The Apache Software Foundation
  *
  *  Licensed under the Apache License, Version 2.0 (the "License");
  *  you may not use this file except in compliance with the License.
@@ -33,5 +33,7 @@
     void getConnection(ConnectionInfo connectionInfo) throws ResourceException;
 
     void returnConnection(ConnectionInfo connectionInfo, ConnectionReturnAction connectionReturnAction);
+
+    void destroy();
 
 } // ConnectionInterceptor

Modified: geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/ConnectionTrackingInterceptor.java
URL: http://svn.apache.org/viewcvs/geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/ConnectionTrackingInterceptor.java?rev=331909&r1=331908&r2=331909&view=diff
==============================================================================
--- geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/ConnectionTrackingInterceptor.java (original)
+++ geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/ConnectionTrackingInterceptor.java Tue Nov  8 14:17:25 2005
@@ -1,6 +1,6 @@
 /**
  *
- * Copyright 2003-2004 The Apache Software Foundation
+ * Copyright 2003-2005 The Apache Software Foundation
  *
  *  Licensed under the Apache License, Version 2.0 (the "License");
  *  you may not use this file except in compliance with the License.
@@ -82,6 +82,10 @@
         next.returnConnection(connectionInfo, connectionReturnAction);
     }
 
+    public void destroy() {
+        next.destroy();
+    }
+    
     public void enter(Collection connectionInfos)
             throws ResourceException {
         for (Iterator i = connectionInfos.iterator(); i.hasNext();) {

Modified: geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/LocalXAResourceInsertionInterceptor.java
URL: http://svn.apache.org/viewcvs/geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/LocalXAResourceInsertionInterceptor.java?rev=331909&r1=331908&r2=331909&view=diff
==============================================================================
--- geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/LocalXAResourceInsertionInterceptor.java (original)
+++ geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/LocalXAResourceInsertionInterceptor.java Tue Nov  8 14:17:25 2005
@@ -1,6 +1,6 @@
 /**
  *
- * Copyright 2003-2004 The Apache Software Foundation
+ * Copyright 2003-2005 The Apache Software Foundation
  *
  *  Licensed under the Apache License, Version 2.0 (the "License");
  *  you may not use this file except in compliance with the License.
@@ -50,4 +50,7 @@
         next.returnConnection(connectionInfo, connectionReturnAction);
     }
 
+    public void destroy() {
+        next.destroy();        
+    }
 }

Modified: geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/MCFConnectionInterceptor.java
URL: http://svn.apache.org/viewcvs/geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/MCFConnectionInterceptor.java?rev=331909&r1=331908&r2=331909&view=diff
==============================================================================
--- geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/MCFConnectionInterceptor.java (original)
+++ geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/MCFConnectionInterceptor.java Tue Nov  8 14:17:25 2005
@@ -1,6 +1,6 @@
 /**
  *
- * Copyright 2003-2004 The Apache Software Foundation
+ * Copyright 2003-2005 The Apache Software Foundation
  *
  *  Licensed under the Apache License, Version 2.0 (the "License");
  *  you may not use this file except in compliance with the License.
@@ -64,6 +64,10 @@
         }
     }
 
+    public void destroy() {
+        // MCF is the "tail" of the stack. So, we're all done...
+    }
+    
     public void setStack(ConnectionInterceptor stack) {
         this.stack = stack;
     }

Modified: geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/MultiPoolConnectionInterceptor.java
URL: http://svn.apache.org/viewcvs/geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/MultiPoolConnectionInterceptor.java?rev=331909&r1=331908&r2=331909&view=diff
==============================================================================
--- geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/MultiPoolConnectionInterceptor.java (original)
+++ geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/MultiPoolConnectionInterceptor.java Tue Nov  8 14:17:25 2005
@@ -1,6 +1,6 @@
 /**
  *
- * Copyright 2003-2004 The Apache Software Foundation
+ * Copyright 2003-2005 The Apache Software Foundation
  *
  *  Licensed under the Apache License, Version 2.0 (the "License");
  *  you may not use this file except in compliance with the License.
@@ -49,6 +49,9 @@
 
     private final Map pools = new HashMap();
 
+    // volatile is not necessary, here, because of synchronization. but maintained for consistency with other Interceptors...
+    private volatile boolean destroyed = false;
+
     public MultiPoolConnectionInterceptor(
             final ConnectionInterceptor next,
             PoolingSupport singlePoolFactory,
@@ -68,6 +71,9 @@
                         useCRI ? mci.getConnectionRequestInfo() : null);
         ConnectionInterceptor poolInterceptor = null;
         synchronized (pools) {
+            if (destroyed) {
+                throw new ResourceException("ConnectionManaged has been destroyed");
+            }
             poolInterceptor = (ConnectionInterceptor) pools.get(key);
             if (poolInterceptor == null) {
                 poolInterceptor = singlePoolFactory.addPoolingInterceptors(next);
@@ -78,6 +84,7 @@
         poolInterceptor.getConnection(connectionInfo);
     }
 
+    // let underlying pools handle destroyed processing...
     public void returnConnection(
             ConnectionInfo connectionInfo,
             ConnectionReturnAction connectionReturnAction) {
@@ -86,6 +93,17 @@
         poolInterceptor.returnConnection(connectionInfo, connectionReturnAction);
     }
 
+    public void destroy() {
+        synchronized (pools) {
+            destroyed = true;
+            for (Iterator it = pools.entrySet().iterator(); it.hasNext(); ) {
+                ((ConnectionInterceptor)((Map.Entry)it.next()).getValue()).destroy();
+                it.remove();
+            }
+        }
+        next.destroy();
+    }
+    
     public int getPartitionCount() {
         return pools.size();
     }

Modified: geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/SinglePoolConnectionInterceptor.java
URL: http://svn.apache.org/viewcvs/geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/SinglePoolConnectionInterceptor.java?rev=331909&r1=331908&r2=331909&view=diff
==============================================================================
--- geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/SinglePoolConnectionInterceptor.java (original)
+++ geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/SinglePoolConnectionInterceptor.java Tue Nov  8 14:17:25 2005
@@ -1,6 +1,6 @@
 /**
  *
- * Copyright 2003-2004 The Apache Software Foundation
+ * Copyright 2003-2005 The Apache Software Foundation
  *
  *  Licensed under the Apache License, Version 2.0 (the "License");
  *  you may not use this file except in compliance with the License.
@@ -41,7 +41,6 @@
 
     private PoolDeque pool;
 
-
     public SinglePoolConnectionInterceptor(final ConnectionInterceptor next,
                                            int maxSize,
                                            int minSize,
@@ -55,6 +54,10 @@
 
     protected void internalGetConnection(ConnectionInfo connectionInfo) throws ResourceException {
         synchronized (pool) {
+            if (destroyed) {
+                throw new ResourceException("ManagedConnection pool has been destroyed");
+            }
+                
             ManagedConnectionInfo newMCI = null;
             if (pool.isEmpty()) {
                 next.getConnection(connectionInfo);
@@ -109,6 +112,20 @@
         }
     }
 
+    protected void internalDestroy() {
+        synchronized (pool) {
+            while (!pool.isEmpty()) {
+                ManagedConnection mc = pool.removeLast().getManagedConnection();
+                if (mc != null) {
+                    try {
+                        mc.destroy();
+                    }
+                    catch (ResourceException re) { } // ignore
+                }
+            }
+        }
+    }
+
     protected boolean internalReturn(ConnectionInfo connectionInfo, ConnectionReturnAction connectionReturnAction) {
         ManagedConnectionInfo mci = connectionInfo.getManagedConnectionInfo();
         ManagedConnection mc = mci.getManagedConnection();
@@ -119,6 +136,16 @@
         }
         boolean wasInPool = false;
         synchronized (pool) {
+            // a bit redundant with returnConnection check in AbstractSinglePoolConnectionInterceptor, 
+            // but checking here closes a small timing hole...
+            if (destroyed) {
+                try {
+                    mc.destroy();
+                }
+                catch (ResourceException re) { } // ignore
+                return pool.remove(mci);
+            }
+                
             if (shrinkLater > 0) {
                 //nothing can get in the pool while shrinkLater > 0, so wasInPool is false here.
                 connectionReturnAction = ConnectionReturnAction.DESTROY;
@@ -183,7 +210,6 @@
         }
         return added;
     }
-
 
     static class PoolDeque {
 

Modified: geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/SinglePoolMatchAllConnectionInterceptor.java
URL: http://svn.apache.org/viewcvs/geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/SinglePoolMatchAllConnectionInterceptor.java?rev=331909&r1=331908&r2=331909&view=diff
==============================================================================
--- geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/SinglePoolMatchAllConnectionInterceptor.java (original)
+++ geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/SinglePoolMatchAllConnectionInterceptor.java Tue Nov  8 14:17:25 2005
@@ -1,6 +1,6 @@
 /**
  *
- * Copyright 2003-2004 The Apache Software Foundation
+ * Copyright 2003-2005 The Apache Software Foundation
  *
  *  Licensed under the Apache License, Version 2.0 (the "License");
  *  you may not use this file except in compliance with the License.
@@ -35,32 +35,11 @@
  * @version $Rev$ $Date$
  */
 public class SinglePoolMatchAllConnectionInterceptor extends AbstractSinglePoolConnectionInterceptor {
-//        implements ConnectionInterceptor, PoolingAttributes {
-
-//    private static Log log = LogFactory.getLog(SinglePoolMatchAllConnectionInterceptor.class.getName());
-
-
-//    private final ConnectionInterceptor next;
-
-//    private Timer timer = PoolIdleReleaserTimer.getTimer();
-
-//    private FIFOSemaphore permits;
 
     private HashMap pool;
 
     private int maxSize;
 
-//    private int blockingTimeoutMilliseconds;
-
-//    private long idleTimeoutMilliseconds;
-
-//    private int connectionCount = 0;
-
-//    private int minSize = 0;
-
-//    private IdleReleaser idleReleaser;
-//    private int shrinkLater = 0;
-
     public SinglePoolMatchAllConnectionInterceptor(final ConnectionInterceptor next,
                                                    int maxSize,
                                                    int minSize,
@@ -68,36 +47,15 @@
                                                    int idleTimeoutMinutes) {
 
         super(next, maxSize, minSize, blockingTimeoutMilliseconds, idleTimeoutMinutes);
-//        this.next = next;
         this.maxSize = maxSize;
-//        this.blockingTimeoutMilliseconds = blockingTimeoutMilliseconds;
-//        permits = new FIFOSemaphore(maxSize);
         pool = new HashMap(maxSize);
-//        setIdleTimeoutMinutes(idleTimeoutMinutes);
     }
 
-//    public void getConnection(ConnectionInfo connectionInfo) throws ResourceException {
-//        if (connectionInfo.getManagedConnectionInfo().getManagedConnection() != null) {
-//            return;
-//        }
-//        try {
-//            if (permits.attempt(blockingTimeoutMilliseconds)) {
-//                internalGetConnection(connectionInfo);
-//            } else {
-//                throw new ResourceException("No ManagedConnections available "
-//                        + "within configured blocking timeout ( "
-//                        + blockingTimeoutMilliseconds
-//                        + " [ms] )");
-//
-//            } // end of else
-//
-//        } catch (InterruptedException ie) {
-//            throw new ResourceException("Interrupted while requesting permit!");
-//        } // end of try-catch
-//    }
-
     protected void internalGetConnection(ConnectionInfo connectionInfo) throws ResourceException {
         synchronized (pool) {
+            if (destroyed) {
+                throw new ResourceException("ManagedConnection pool has been destroyed");
+            }
             try {
                 if (!pool.isEmpty()) {
                     ManagedConnectionInfo mci = connectionInfo.getManagedConnectionInfo();
@@ -145,23 +103,6 @@
         }
     }
 
-//    public void returnConnection(ConnectionInfo connectionInfo,
-//                                 ConnectionReturnAction connectionReturnAction) {
-//        if (log.isTraceEnabled()) {
-//            log.trace("returning connection" + connectionInfo.getConnectionHandle());
-//        }
-//        ManagedConnectionInfo mci = connectionInfo.getManagedConnectionInfo();
-//        if (connectionReturnAction == ConnectionReturnAction.RETURN_HANDLE && mci.hasConnectionHandles()) {
-//            return;
-//        }
-//
-//        boolean wasInPool = internalReturn(connectionInfo, connectionReturnAction);
-//
-//        if (!wasInPool) {
-//            permits.release();
-//        }
-//    }
-
     protected boolean internalReturn(ConnectionInfo connectionInfo, ConnectionReturnAction connectionReturnAction) {
         ManagedConnectionInfo mci = connectionInfo.getManagedConnectionInfo();
         ManagedConnection mc = mci.getManagedConnection();
@@ -173,6 +114,14 @@
 
         boolean wasInPool = false;
         synchronized (pool) {
+            // a bit redundant, but this closes a small timing hole...
+            if (destroyed) {
+                try {
+                    mc.destroy();
+                }
+                catch (ResourceException re) { } // ignore
+                return pool.remove(mci.getManagedConnection()) != null;
+            }
             if (shrinkLater > 0) {
                 //nothing can get in the pool while shrinkLater > 0, so wasInPool is false here.
                 connectionReturnAction = ConnectionReturnAction.DESTROY;
@@ -191,10 +140,18 @@
         return wasInPool;
     }
 
-    //PoolingAttributes implementation
-//    public int getPartitionCount() {
-//        return 1;
-//    }
+    protected void internalDestroy() {
+        synchronized (pool) {
+            Iterator it = pool.keySet().iterator();
+            for (; it.hasNext(); ) {
+                try {
+                    ((ManagedConnection)it.next()).destroy();
+                }
+                catch (ResourceException re) { } // ignore
+                it.remove();
+            }
+        }
+    }
 
     public int getPartitionMaxSize() {
         return maxSize;
@@ -248,92 +205,4 @@
         return added;
     }
 
-//    public int getConnectionCount() {
-//        return connectionCount;
-//    }
-
-//    public int getBlockingTimeoutMilliseconds() {
-//        return blockingTimeoutMilliseconds;
-//    }
-//
-//    public void setBlockingTimeoutMilliseconds(int timeoutMilliseconds) {
-//        this.blockingTimeoutMilliseconds = timeoutMilliseconds;
-//    }
-
-//    public int getIdleTimeoutMinutes() {
-//        return (int) idleTimeoutMilliseconds / (1000 * 60);
-//    }
-
-//    public void setIdleTimeoutMinutes(int idleTimeoutMinutes) {
-//        this.idleTimeoutMilliseconds = idleTimeoutMinutes * 60 * 1000;
-//        if (idleReleaser != null) {
-//            idleReleaser.cancel();
-//        }
-//        idleReleaser = new IdleReleaser();
-//        timer.schedule(idleReleaser, this.idleTimeoutMilliseconds, this.idleTimeoutMilliseconds);
-//    }
-
-
-//    private class IdleReleaser extends TimerTask {
-//
-//        public void run() {
-//            long threshold = System.currentTimeMillis() - idleTimeoutMilliseconds;
-//            ManagedConnectionInfo[] killList = new ManagedConnectionInfo[pool.size()];
-//            int j = 0;
-//            synchronized (pool) {
-//                for (Iterator iterator = pool.entrySet().iterator(); iterator.hasNext();) {
-//                    Map.Entry entry = (Map.Entry) iterator.next();
-//                    ManagedConnectionInfo mci = (ManagedConnectionInfo) entry.getValue();
-//                    if (mci.getLastUsed() < threshold) {
-//                        killList[j] = mci;
-//                        j++;
-//                    }
-//                }
-//            }
-//            for (int i = 0; i < j; i++) {
-//                ManagedConnectionInfo managedConnectionInfo = killList[i];
-//                ConnectionInfo killInfo = new ConnectionInfo(managedConnectionInfo);
-//                internalReturn(killInfo, ConnectionReturnAction.DESTROY);
-//            }
-//            permits.release(j);
-//        }
-//    }
-//
-//    private class FillTask extends TimerTask {
-//        private final ManagedConnectionFactory managedConnectionFactory;
-//        private final Subject subject;
-//        private final ConnectionRequestInfo cri;
-//
-//        public FillTask(ConnectionInfo connectionInfo) {
-//            managedConnectionFactory = connectionInfo.getManagedConnectionInfo().getManagedConnectionFactory();
-//            subject = connectionInfo.getManagedConnectionInfo().getSubject();
-//            cri = connectionInfo.getManagedConnectionInfo().getConnectionRequestInfo();
-//        }
-//
-//        public void run() {
-//            while (connectionCount < minSize) {
-//                ManagedConnectionInfo mci = new ManagedConnectionInfo(managedConnectionFactory, cri);
-//                mci.setSubject(subject);
-//                ConnectionInfo ci = new ConnectionInfo(mci);
-//                try {
-//                    next.getConnection(ci);
-//                } catch (ResourceException e) {
-//                    return;
-//                }
-//                boolean added = false;
-//                synchronized (pool) {
-//                    connectionCount++;
-//                    added = maxSize > pool.size();
-//                    if (added) {
-//                        pool.put(mci.getManagedConnection(), mci);
-//                    }
-//                }
-//                if (!added) {
-//                    internalReturn(ci, ConnectionReturnAction.DESTROY);
-//                    return;
-//                }
-//            }
-//        }
-//    }
-
-}
\ No newline at end of file
+}

Modified: geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/SubjectInterceptor.java
URL: http://svn.apache.org/viewcvs/geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/SubjectInterceptor.java?rev=331909&r1=331908&r2=331909&view=diff
==============================================================================
--- geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/SubjectInterceptor.java (original)
+++ geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/SubjectInterceptor.java Tue Nov  8 14:17:25 2005
@@ -1,6 +1,6 @@
 /**
  *
- * Copyright 2003-2004 The Apache Software Foundation
+ * Copyright 2003-2005 The Apache Software Foundation
  *
  *  Licensed under the Apache License, Version 2.0 (the "License");
  *  you may not use this file except in compliance with the License.
@@ -92,4 +92,7 @@
         next.returnConnection(connectionInfo, connectionReturnAction);
     }
 
+    public void destroy() {
+        next.destroy();
+    }
 }

Modified: geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/TCCLInterceptor.java
URL: http://svn.apache.org/viewcvs/geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/TCCLInterceptor.java?rev=331909&r1=331908&r2=331909&view=diff
==============================================================================
--- geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/TCCLInterceptor.java (original)
+++ geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/TCCLInterceptor.java Tue Nov  8 14:17:25 2005
@@ -1,6 +1,6 @@
 /**
  *
- * Copyright 2003-2004 The Apache Software Foundation
+ * Copyright 2003-2005 The Apache Software Foundation
  *
  *  Licensed under the Apache License, Version 2.0 (the "License");
  *  you may not use this file except in compliance with the License.
@@ -51,5 +51,9 @@
         } finally {
             currentThread.setContextClassLoader(oldClassLoader);
         }
+    }
+    
+    public void destroy() {
+        this.next.destroy();
     }
 }

Modified: geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/ThreadLocalCachingConnectionInterceptor.java
URL: http://svn.apache.org/viewcvs/geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/ThreadLocalCachingConnectionInterceptor.java?rev=331909&r1=331908&r2=331909&view=diff
==============================================================================
--- geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/ThreadLocalCachingConnectionInterceptor.java (original)
+++ geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/ThreadLocalCachingConnectionInterceptor.java Tue Nov  8 14:17:25 2005
@@ -1,6 +1,6 @@
 /**
  *
- * Copyright 2004 The Apache Software Foundation
+ * Copyright 2004-2005 The Apache Software Foundation
  *
  *  Licensed under the Apache License, Version 2.0 (the "License");
  *  you may not use this file except in compliance with the License.
@@ -75,5 +75,9 @@
         if (connectionReturnAction == ConnectionReturnAction.DESTROY || connectionInfo.isUnshareable()) {
             next.returnConnection(connectionInfo, connectionReturnAction);
         }
+    }
+    
+    public void destroy() {
+        next.destroy();
     }
 }

Modified: geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/TransactionCachingInterceptor.java
URL: http://svn.apache.org/viewcvs/geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/TransactionCachingInterceptor.java?rev=331909&r1=331908&r2=331909&view=diff
==============================================================================
--- geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/TransactionCachingInterceptor.java (original)
+++ geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/TransactionCachingInterceptor.java Tue Nov  8 14:17:25 2005
@@ -1,6 +1,6 @@
 /**
  *
- * Copyright 2003-2004 The Apache Software Foundation
+ * Copyright 2003-2005 The Apache Software Foundation
  *
  *  Licensed under the Apache License, Version 2.0 (the "License");
  *  you may not use this file except in compliance with the License.
@@ -109,6 +109,10 @@
         next.returnConnection(connectionInfo, connectionReturnAction);
     }
 
+    public void destroy() {
+        next.destroy();
+    }
+    
     public void afterCompletion(Object stuff) {
         ManagedConnectionInfos managedConnectionInfos = (ManagedConnectionInfos) stuff;
         ManagedConnectionInfo sharedMCI = managedConnectionInfos.getShared();

Modified: geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/TransactionEnlistingInterceptor.java
URL: http://svn.apache.org/viewcvs/geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/TransactionEnlistingInterceptor.java?rev=331909&r1=331908&r2=331909&view=diff
==============================================================================
--- geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/TransactionEnlistingInterceptor.java (original)
+++ geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/TransactionEnlistingInterceptor.java Tue Nov  8 14:17:25 2005
@@ -1,6 +1,6 @@
 /**
  *
- * Copyright 2003-2004 The Apache Software Foundation
+ * Copyright 2003-2005 The Apache Software Foundation
  *
  *  Licensed under the Apache License, Version 2.0 (the "License");
  *  you may not use this file except in compliance with the License.
@@ -94,4 +94,8 @@
         next.returnConnection(connectionInfo, connectionReturnAction);
     }
 
+    public void destroy() {
+        next.destroy();
+    }
+    
 }

Modified: geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/XAResourceInsertionInterceptor.java
URL: http://svn.apache.org/viewcvs/geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/XAResourceInsertionInterceptor.java?rev=331909&r1=331908&r2=331909&view=diff
==============================================================================
--- geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/XAResourceInsertionInterceptor.java (original)
+++ geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/XAResourceInsertionInterceptor.java Tue Nov  8 14:17:25 2005
@@ -1,6 +1,6 @@
 /**
  *
- * Copyright 2003-2004 The Apache Software Foundation
+ * Copyright 2003-2005 The Apache Software Foundation
  *
  *  Licensed under the Apache License, Version 2.0 (the "License");
  *  you may not use this file except in compliance with the License.
@@ -45,6 +45,10 @@
 
     public void returnConnection(ConnectionInfo connectionInfo, ConnectionReturnAction connectionReturnAction) {
         next.returnConnection(connectionInfo, connectionReturnAction);
+    }
+    
+    public void destroy() {
+        next.destroy();
     }
 
 }

Modified: geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/transactionlog/LogXAResourceInsertionInterceptor.java
URL: http://svn.apache.org/viewcvs/geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/transactionlog/LogXAResourceInsertionInterceptor.java?rev=331909&r1=331908&r2=331909&view=diff
==============================================================================
--- geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/transactionlog/LogXAResourceInsertionInterceptor.java (original)
+++ geronimo/trunk/modules/connector/src/java/org/apache/geronimo/connector/outbound/transactionlog/LogXAResourceInsertionInterceptor.java Tue Nov  8 14:17:25 2005
@@ -1,6 +1,6 @@
 /**
  *
- * Copyright 2003-2004 The Apache Software Foundation
+ * Copyright 2003-2005 The Apache Software Foundation
  *
  *  Licensed under the Apache License, Version 2.0 (the "License");
  *  you may not use this file except in compliance with the License.
@@ -56,4 +56,7 @@
         next.returnConnection(connectionInfo, connectionReturnAction);
     }
 
+    public void destroy() {
+        next.destroy();
+    }
 }

Modified: geronimo/trunk/modules/connector/src/test/org/apache/geronimo/connector/outbound/ConnectionInterceptorTestUtils.java
URL: http://svn.apache.org/viewcvs/geronimo/trunk/modules/connector/src/test/org/apache/geronimo/connector/outbound/ConnectionInterceptorTestUtils.java?rev=331909&r1=331908&r2=331909&view=diff
==============================================================================
--- geronimo/trunk/modules/connector/src/test/org/apache/geronimo/connector/outbound/ConnectionInterceptorTestUtils.java (original)
+++ geronimo/trunk/modules/connector/src/test/org/apache/geronimo/connector/outbound/ConnectionInterceptorTestUtils.java Tue Nov  8 14:17:25 2005
@@ -1,6 +1,6 @@
 /**
  *
- * Copyright 2003-2004 The Apache Software Foundation
+ * Copyright 2003-2005 The Apache Software Foundation
  *
  *  Licensed under the Apache License, Version 2.0 (the "License");
  *  you may not use this file except in compliance with the License.
@@ -68,6 +68,10 @@
 
     public void returnConnection(ConnectionInfo connectionInfo, ConnectionReturnAction connectionReturnAction) {
         returnedConnectionInfo = connectionInfo;
+    }
+    
+    public void destroy() {
+        
     }
 
     protected void makeSubject(String principalName) {

Modified: geronimo/trunk/modules/connector/src/test/org/apache/geronimo/connector/outbound/connectiontracking/ConnectionTrackingCoordinatorTest.java
URL: http://svn.apache.org/viewcvs/geronimo/trunk/modules/connector/src/test/org/apache/geronimo/connector/outbound/connectiontracking/ConnectionTrackingCoordinatorTest.java?rev=331909&r1=331908&r2=331909&view=diff
==============================================================================
--- geronimo/trunk/modules/connector/src/test/org/apache/geronimo/connector/outbound/connectiontracking/ConnectionTrackingCoordinatorTest.java (original)
+++ geronimo/trunk/modules/connector/src/test/org/apache/geronimo/connector/outbound/connectiontracking/ConnectionTrackingCoordinatorTest.java Tue Nov  8 14:17:25 2005
@@ -1,6 +1,6 @@
 /**
  *
- * Copyright 2003-2004 The Apache Software Foundation
+ * Copyright 2003-2005 The Apache Software Foundation
  *
  *  Licensed under the Apache License, Version 2.0 (the "License");
  *  you may not use this file except in compliance with the License.
@@ -147,5 +147,7 @@
     }
 
     public void returnConnection(ConnectionInfo connectionInfo, ConnectionReturnAction connectionReturnAction) {
+    }
+    public void destroy() {        
     }
 }