Author: markt
Date: Thu May 28 20:09:07 2015
New Revision: 1682320

URL: http://svn.apache.org/r1682320
Log:
Update Commons Pool fork to 2.4.0

Modified:
    tomcat/trunk/java/org/apache/tomcat/dbcp/pool2/   (props changed)
    
tomcat/trunk/java/org/apache/tomcat/dbcp/pool2/impl/BaseGenericObjectPool.java
    
tomcat/trunk/java/org/apache/tomcat/dbcp/pool2/impl/GenericKeyedObjectPool.java
    
tomcat/trunk/java/org/apache/tomcat/dbcp/pool2/impl/GenericKeyedObjectPoolConfig.java
    tomcat/trunk/java/org/apache/tomcat/dbcp/pool2/impl/GenericObjectPool.java

Propchange: tomcat/trunk/java/org/apache/tomcat/dbcp/pool2/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Thu May 28 20:09:07 2015
@@ -1 +1 @@
-/commons/proper/pool/trunk/src/main/java/org/apache/commons/pool2:1593516-1648905
+/commons/proper/pool/trunk/src/main/java/org/apache/commons/pool2:1593516-1682319

Modified: 
tomcat/trunk/java/org/apache/tomcat/dbcp/pool2/impl/BaseGenericObjectPool.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/dbcp/pool2/impl/BaseGenericObjectPool.java?rev=1682320&r1=1682319&r2=1682320&view=diff
==============================================================================
--- 
tomcat/trunk/java/org/apache/tomcat/dbcp/pool2/impl/BaseGenericObjectPool.java 
(original)
+++ 
tomcat/trunk/java/org/apache/tomcat/dbcp/pool2/impl/BaseGenericObjectPool.java 
Thu May 28 20:09:07 2015
@@ -21,6 +21,7 @@ import java.io.StringWriter;
 import java.io.Writer;
 import java.lang.management.ManagementFactory;
 import java.lang.ref.WeakReference;
+import java.util.Deque;
 import java.util.Iterator;
 import java.util.TimerTask;
 import java.util.concurrent.atomic.AtomicLong;
@@ -89,7 +90,7 @@ public abstract class BaseGenericObjectP
     volatile boolean closed = false;
     final Object evictionLock = new Object();
     private Evictor evictor = null; // @GuardedBy("evictionLock")
-    Iterator<PooledObject<T>> evictionIterator = null; // 
@GuardedBy("evictionLock")
+    EvictionIterator evictionIterator = null; // @GuardedBy("evictionLock")
     /*
      * Class loader for evictor thread to use since, in a JavaEE or similar
      * environment, the context class loader for the evictor thread may not 
have
@@ -583,7 +584,9 @@ public abstract class BaseGenericObjectP
 
     /**
      * Sets the name of the {@link EvictionPolicy} implementation that is
-     * used by this pool.
+     * used by this pool. The Pool will attempt to load the class using the
+     * thread context class loader. If that fails, the Pool will attempt to 
load
+     * the class using the class loader that loaded this class.
      *
      * @param evictionPolicyClassName   the fully qualified class name of the
      *                                  new eviction policy
@@ -593,8 +596,13 @@ public abstract class BaseGenericObjectP
     public final void setEvictionPolicyClassName(
             String evictionPolicyClassName) {
         try {
-            Class<?> clazz = Class.forName(evictionPolicyClassName, true,
-                    Thread.currentThread().getContextClassLoader());
+            Class<?> clazz;
+            try {
+                clazz = Class.forName(evictionPolicyClassName, true,
+                        Thread.currentThread().getContextClassLoader());
+            } catch (ClassNotFoundException e) {
+                clazz = Class.forName(evictionPolicyClassName);
+            }
             Object policy = clazz.newInstance();
             if (policy instanceof EvictionPolicy<?>) {
                 @SuppressWarnings("unchecked") // safe, because we just 
checked the class
@@ -645,9 +653,11 @@ public abstract class BaseGenericObjectP
 
     /**
      * Returns the {@link EvictionPolicy} defined for this pool.
+     *
      * @return the eviction policy
+     * @since 2.4
      */
-    final EvictionPolicy<T> getEvictionPolicy() {
+    protected EvictionPolicy<T> getEvictionPolicy() {
         return evictionPolicy;
     }
 
@@ -1098,4 +1108,96 @@ public abstract class BaseGenericObjectP
             return (long) result;
         }
     }
+
+    /**
+     * The idle object eviction iterator. Holds a reference to the idle 
objects.
+     */
+    class EvictionIterator implements Iterator<PooledObject<T>> {
+
+        private final Deque<PooledObject<T>> idleObjects;
+        private final Iterator<PooledObject<T>> idleObjectIterator;
+
+        /**
+         * Create an EvictionIterator for the provided idle instance deque.
+         * @param idleObjects underlying deque
+         */
+        EvictionIterator(final Deque<PooledObject<T>> idleObjects) {
+            this.idleObjects = idleObjects;
+
+            if (getLifo()) {
+                idleObjectIterator = idleObjects.descendingIterator();
+            } else {
+                idleObjectIterator = idleObjects.iterator();
+            }
+        }
+
+        /**
+         * Returns the idle object deque referenced by this iterator.
+         * @return the idle object deque
+         */
+        public Deque<PooledObject<T>> getIdleObjects() {
+            return idleObjects;
+        }
+
+        /** {@inheritDoc} */
+        @Override
+        public boolean hasNext() {
+            return idleObjectIterator.hasNext();
+        }
+
+        /** {@inheritDoc} */
+        @Override
+        public PooledObject<T> next() {
+            return idleObjectIterator.next();
+        }
+
+        /** {@inheritDoc} */
+        @Override
+        public void remove() {
+            idleObjectIterator.remove();
+        }
+
+    }
+
+    /**
+     * Wrapper for objects under management by the pool.
+     *
+     * GenericObjectPool and GenericKeyedObjectPool maintain references to all
+     * objects under management using maps keyed on the objects. This wrapper
+     * class ensures that objects can work as hash keys.
+     *
+     * @param <T> type of objects in the pool
+     */
+    static class IdentityWrapper<T> {
+        /** Wrapped object */
+        private final T instance;
+
+        /**
+         * Create a wrapper for an instance.
+         *
+         * @param instance object to wrap
+         */
+        public IdentityWrapper(T instance) {
+            this.instance = instance;
+        }
+
+        @Override
+        public int hashCode() {
+            return System.identityHashCode(instance);
+        }
+
+        @Override
+        @SuppressWarnings("rawtypes")
+        public boolean equals(Object other) {
+            return ((IdentityWrapper) other).instance == instance;
+        }
+
+        /**
+         * @return the wrapped object
+         */
+        public T getObject() {
+            return instance;
+        }
+    }
+
 }

Modified: 
tomcat/trunk/java/org/apache/tomcat/dbcp/pool2/impl/GenericKeyedObjectPool.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/dbcp/pool2/impl/GenericKeyedObjectPool.java?rev=1682320&r1=1682319&r2=1682320&view=diff
==============================================================================
--- 
tomcat/trunk/java/org/apache/tomcat/dbcp/pool2/impl/GenericKeyedObjectPool.java 
(original)
+++ 
tomcat/trunk/java/org/apache/tomcat/dbcp/pool2/impl/GenericKeyedObjectPool.java 
Thu May 28 20:09:07 2015
@@ -17,6 +17,7 @@
 package org.apache.tomcat.dbcp.pool2.impl;
 
 import java.util.ArrayList;
+import java.util.Deque;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
@@ -468,13 +469,23 @@ public class GenericKeyedObjectPool<K,T>
 
         ObjectDeque<T> objectDeque = poolMap.get(key);
 
-        PooledObject<T> p = objectDeque.getAllObjects().get(obj);
+        PooledObject<T> p = objectDeque.getAllObjects().get(new 
IdentityWrapper<>(obj));
 
         if (p == null) {
             throw new IllegalStateException(
                     "Returned object not currently part of this pool");
         }
 
+        synchronized(p) {
+            final PooledObjectState state = p.getState();
+            if (state != PooledObjectState.ALLOCATED) {
+                throw new IllegalStateException(
+                        "Object has already been returned to this pool or is 
invalid");
+            } else {
+                p.markReturning(); // Keep from being marked abandoned (once 
GKOP does this)
+            }
+        }
+
         long activeTime = p.getActiveTimeMillis();
 
         if (getTestOnReturn()) {
@@ -572,7 +583,7 @@ public class GenericKeyedObjectPool<K,T>
 
         ObjectDeque<T> objectDeque = poolMap.get(key);
 
-        PooledObject<T> p = objectDeque.getAllObjects().get(obj);
+        PooledObject<T> p = objectDeque.getAllObjects().get(new 
IdentityWrapper<>(obj));
         if (p == null) {
             throw new IllegalStateException(
                     "Object not currently part of this pool");
@@ -878,8 +889,6 @@ public class GenericKeyedObjectPool<K,T>
 
             boolean testWhileIdle = getTestWhileIdle();
 
-            LinkedBlockingDeque<PooledObject<T>> idleObjects = null;
-
             for (int i = 0, m = getNumTests(); i < m; i++) {
                 if(evictionIterator == null || !evictionIterator.hasNext()) {
                     if (evictionKeyIterator == null ||
@@ -900,13 +909,9 @@ public class GenericKeyedObjectPool<K,T>
                         if (objectDeque == null) {
                             continue;
                         }
-                        idleObjects = objectDeque.getIdleObjects();
 
-                        if (getLifo()) {
-                            evictionIterator = 
idleObjects.descendingIterator();
-                        } else {
-                            evictionIterator = idleObjects.iterator();
-                        }
+                        final Deque<PooledObject<T>> idleObjects = 
objectDeque.getIdleObjects();
+                        evictionIterator = new EvictionIterator(idleObjects);
                         if (evictionIterator.hasNext()) {
                             break;
                         }
@@ -917,8 +922,10 @@ public class GenericKeyedObjectPool<K,T>
                     // Pools exhausted
                     return;
                 }
+                final Deque<PooledObject<T>> idleObjects;
                 try {
                     underTest = evictionIterator.next();
+                    idleObjects = evictionIterator.getIdleObjects();
                 } catch (NoSuchElementException nsee) {
                     // Object was borrowed in another thread
                     // Don't count this as an eviction test so reduce i;
@@ -964,14 +971,12 @@ public class GenericKeyedObjectPool<K,T>
                             destroyedByEvictorCount.incrementAndGet();
                         }
                         if (active) {
-                            if (!factory.validateObject(evictionKey,
-                                    underTest)) {
+                            if (!factory.validateObject(evictionKey, 
underTest)) {
                                 destroy(evictionKey, underTest, true);
                                 destroyedByEvictorCount.incrementAndGet();
                             } else {
                                 try {
-                                    factory.passivateObject(evictionKey,
-                                            underTest);
+                                    factory.passivateObject(evictionKey, 
underTest);
                                 } catch (Exception e) {
                                     destroy(evictionKey, underTest, true);
                                     destroyedByEvictorCount.incrementAndGet();
@@ -1040,7 +1045,7 @@ public class GenericKeyedObjectPool<K,T>
         }
 
         createdCount.incrementAndGet();
-        objectDeque.getAllObjects().put(p.getObject(), p);
+        objectDeque.getAllObjects().put(new IdentityWrapper<>(p.getObject()), 
p);
         return p;
     }
 
@@ -1063,7 +1068,7 @@ public class GenericKeyedObjectPool<K,T>
             boolean isIdle = objectDeque.getIdleObjects().remove(toDestroy);
 
             if (isIdle || always) {
-                objectDeque.getAllObjects().remove(toDestroy.getObject());
+                objectDeque.getAllObjects().remove(new 
IdentityWrapper<>(toDestroy.getObject()));
                 toDestroy.invalidate();
 
                 try {
@@ -1247,8 +1252,7 @@ public class GenericKeyedObjectPool<K,T>
      *
      * @param key - The key to register for pool control.
      *
-     * @throws Exception If the associated factory fails to create the 
necessary
-     *                   number of idle instances
+     * @throws Exception If the associated factory throws an exception
      */
     public void preparePool(K key) throws Exception {
         int minIdlePerKeySave = getMinIdlePerKey();
@@ -1432,11 +1436,10 @@ public class GenericKeyedObjectPool<K,T>
         private final AtomicInteger createCount = new AtomicInteger(0);
 
         /*
-         * The map is keyed on pooled instances.  Note: pooled instances
-         * <em>must</em> be distinguishable by equals for this structure to
-         * work properly.
+         * The map is keyed on pooled instances, wrapped to ensure that
+         * they work properly as keys.
          */
-        private final Map<S, PooledObject<S>> allObjects =
+        private final Map<IdentityWrapper<S>, PooledObject<S>> allObjects =
                 new ConcurrentHashMap<>();
 
         /*
@@ -1489,9 +1492,10 @@ public class GenericKeyedObjectPool<K,T>
          *
          * @return All the objects
          */
-        public Map<S, PooledObject<S>> getAllObjects() {
+        public Map<IdentityWrapper<S>, PooledObject<S>> getAllObjects() {
             return allObjects;
         }
+
     }
 
     //--- configuration attributes 
---------------------------------------------

Modified: 
tomcat/trunk/java/org/apache/tomcat/dbcp/pool2/impl/GenericKeyedObjectPoolConfig.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/dbcp/pool2/impl/GenericKeyedObjectPoolConfig.java?rev=1682320&r1=1682319&r2=1682320&view=diff
==============================================================================
--- 
tomcat/trunk/java/org/apache/tomcat/dbcp/pool2/impl/GenericKeyedObjectPoolConfig.java
 (original)
+++ 
tomcat/trunk/java/org/apache/tomcat/dbcp/pool2/impl/GenericKeyedObjectPoolConfig.java
 Thu May 28 20:09:07 2015
@@ -47,7 +47,7 @@ public class GenericKeyedObjectPoolConfi
     public static final int DEFAULT_MIN_IDLE_PER_KEY = 0;
 
     /**
-     * The default value for the {@code minIdlePerKey} configuration attribute.
+     * The default value for the {@code maxIdlePerKey} configuration attribute.
      * @see GenericKeyedObjectPool#getMaxIdlePerKey()
      */
     public static final int DEFAULT_MAX_IDLE_PER_KEY = 8;

Modified: 
tomcat/trunk/java/org/apache/tomcat/dbcp/pool2/impl/GenericObjectPool.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/dbcp/pool2/impl/GenericObjectPool.java?rev=1682320&r1=1682319&r2=1682320&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/dbcp/pool2/impl/GenericObjectPool.java 
(original)
+++ tomcat/trunk/java/org/apache/tomcat/dbcp/pool2/impl/GenericObjectPool.java 
Thu May 28 20:09:07 2015
@@ -532,27 +532,24 @@ public class GenericObjectPool<T> extend
      */
     @Override
     public void returnObject(T obj) {
-        PooledObject<T> p = allObjects.get(obj);
+        PooledObject<T> p = allObjects.get(new IdentityWrapper<>(obj));
 
-        if (!isAbandonedConfig()) {
-            if (p == null) {
+        if (p == null) {
+            if (!isAbandonedConfig()) {
                 throw new IllegalStateException(
                         "Returned object not currently part of this pool");
+            } else {
+                return; // Object was abandoned and removed
             }
-        } else {
-            if (p == null) {
-                return;  // Object was abandoned and removed
+        }
+
+        synchronized(p) {
+            final PooledObjectState state = p.getState();
+            if (state != PooledObjectState.ALLOCATED) {
+                throw new IllegalStateException(
+                        "Object has already been returned to this pool or is 
invalid");
             } else {
-                // Make sure object is not being reclaimed
-                synchronized(p) {
-                    final PooledObjectState state = p.getState();
-                    if (state != PooledObjectState.ALLOCATED) {
-                        throw new IllegalStateException(
-                                "Object has already been returned to this pool 
or is invalid");
-                    } else {
-                        p.markReturning(); // Keep from being marked abandoned
-                    }
-                }
+                p.markReturning(); // Keep from being marked abandoned
             }
         }
 
@@ -633,7 +630,7 @@ public class GenericObjectPool<T> extend
      */
     @Override
     public void invalidateObject(T obj) throws Exception {
-        PooledObject<T> p = allObjects.get(obj);
+        PooledObject<T> p = allObjects.get(new IdentityWrapper<>(obj));
         if (p == null) {
             if (isAbandonedConfig()) {
                 return;
@@ -751,11 +748,7 @@ public class GenericObjectPool<T> extend
 
                 for (int i = 0, m = getNumTests(); i < m; i++) {
                     if (evictionIterator == null || 
!evictionIterator.hasNext()) {
-                        if (getLifo()) {
-                            evictionIterator = 
idleObjects.descendingIterator();
-                        } else {
-                            evictionIterator = idleObjects.iterator();
-                        }
+                        evictionIterator = new EvictionIterator(idleObjects);
                     }
                     if (!evictionIterator.hasNext()) {
                         // Pool exhausted, nothing to do here
@@ -837,6 +830,20 @@ public class GenericObjectPool<T> extend
     }
 
     /**
+     * Tries to ensure that {@link #getMinIdle()} idle instances are available
+     * in the pool.
+     *
+     * @throws Exception If the associated factory throws an exception
+     * @since 2.4
+     */
+    public void preparePool() throws Exception {
+        if (getMinIdle() < 1) {
+            return;
+        }
+        ensureMinIdle();
+    }
+
+    /**
      * Attempts to create a new wrapped pooled object.
      * <p>
      * If there are {@link #getMaxTotal()} objects already in circulation
@@ -869,7 +876,7 @@ public class GenericObjectPool<T> extend
         }
 
         createdCount.incrementAndGet();
-        allObjects.put(p.getObject(), p);
+        allObjects.put(new IdentityWrapper<>(p.getObject()), p);
         return p;
     }
 
@@ -884,7 +891,7 @@ public class GenericObjectPool<T> extend
     private void destroy(PooledObject<T> toDestory) throws Exception {
         toDestory.invalidate();
         idleObjects.remove(toDestory);
-        allObjects.remove(toDestory.getObject());
+        allObjects.remove(new IdentityWrapper<>(toDestory.getObject()));
         try {
             factory.destroyObject(toDestory);
         } finally {
@@ -939,6 +946,9 @@ public class GenericObjectPool<T> extend
     /**
      * Create an object, and place it into the pool. addObject() is useful for
      * "pre-loading" a pool with idle objects.
+     * <p>
+     * If there is no capacity available to add to the pool, this is a no-op
+     * (no exception, no impact to the pool). </p>
      */
     @Override
     public void addObject() throws Exception {
@@ -953,7 +963,8 @@ public class GenericObjectPool<T> extend
 
     /**
      * Add the provided wrapped pooled object to the set of idle objects for
-     * this pool. The object must already be part of the pool.
+     * this pool. The object must already be part of the pool.  If {@code p}
+     * is null, this is a no-op (no exception, but no impact on the pool).
      *
      * @param p The object to make idle
      *
@@ -1032,7 +1043,7 @@ public class GenericObjectPool<T> extend
     public void use(T pooledObject) {
         AbandonedConfig ac = this.abandonedConfig;
         if (ac != null && ac.getUseUsageTracking()) {
-            PooledObject<T> wrapper = allObjects.get(pooledObject);
+            PooledObject<T> wrapper = allObjects.get(new 
IdentityWrapper<>(pooledObject));
             wrapper.use();
         }
     }
@@ -1118,7 +1129,7 @@ public class GenericObjectPool<T> extend
      * #_maxActive}. Map keys are pooled objects, values are the PooledObject
      * wrappers used internally by the pool.
      */
-    private final Map<T, PooledObject<T>> allObjects =
+    private final Map<IdentityWrapper<T>, PooledObject<T>> allObjects =
         new ConcurrentHashMap<>();
     /*
      * The combined count of the currently created objects and those in the



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to