You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by ma...@apache.org on 2021/01/15 15:18:28 UTC

[tomcat] 02/02: Update Commons Pool 2 to 2.9.1-SNAPSHOT

This is an automated email from the ASF dual-hosted git repository.

markt pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/tomcat.git

commit b346ab44c212af9475729a47d16b19ed4f0f276f
Author: Mark Thomas <ma...@apache.org>
AuthorDate: Fri Jan 15 15:18:03 2021 +0000

    Update Commons Pool 2 to 2.9.1-SNAPSHOT
---
 MERGE.txt                                          |  2 +-
 java/org/apache/tomcat/dbcp/pool2/DestroyMode.java | 30 +++++++++++
 .../apache/tomcat/dbcp/pool2/KeyedObjectPool.java  | 27 ++++++++++
 .../dbcp/pool2/KeyedPooledObjectFactory.java       | 20 +++++++
 java/org/apache/tomcat/dbcp/pool2/ObjectPool.java  | 24 +++++++++
 .../tomcat/dbcp/pool2/PooledObjectFactory.java     | 23 +++++++-
 .../tomcat/dbcp/pool2/impl/EvictionTimer.java      |  2 +-
 .../dbcp/pool2/impl/GenericKeyedObjectPool.java    | 52 +++++++++++++-----
 .../tomcat/dbcp/pool2/impl/GenericObjectPool.java  | 63 ++++++++++++++--------
 webapps/docs/changelog.xml                         |  4 ++
 10 files changed, 208 insertions(+), 39 deletions(-)

diff --git a/MERGE.txt b/MERGE.txt
index 8071016..52851d9 100644
--- a/MERGE.txt
+++ b/MERGE.txt
@@ -62,7 +62,7 @@ Pool2
 Sub-tree
 src/main/java/org/apache/commons/pool2
 The SHA1 ID / tag for the most recent commit to be merged to Tomcat is:
-rel/commons-pool-2.8.1
+a38c52529beb04bf0815b7d95fb4a393ea110dee
 
 DBCP2
 Sub-tree
diff --git a/java/org/apache/tomcat/dbcp/pool2/DestroyMode.java b/java/org/apache/tomcat/dbcp/pool2/DestroyMode.java
new file mode 100644
index 0000000..ed8ca47
--- /dev/null
+++ b/java/org/apache/tomcat/dbcp/pool2/DestroyMode.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tomcat.dbcp.pool2;
+
+/**
+ * Destroy context provided to object factories via destroyObject methods. Values provide information about why the pool
+ * is asking for a pooled object to be destroyed.
+ *
+ * @since 2.9.0
+ */
+public enum DestroyMode {
+    /** Normal destroy */
+    NORMAL,
+    /** Destroy abandoned object */
+    ABANDONED
+}
diff --git a/java/org/apache/tomcat/dbcp/pool2/KeyedObjectPool.java b/java/org/apache/tomcat/dbcp/pool2/KeyedObjectPool.java
index 9e5d550..f2712d9 100644
--- a/java/org/apache/tomcat/dbcp/pool2/KeyedObjectPool.java
+++ b/java/org/apache/tomcat/dbcp/pool2/KeyedObjectPool.java
@@ -269,6 +269,33 @@ public interface KeyedObjectPool<K, V> extends Closeable {
      */
     void invalidateObject(K key, V obj) throws Exception;
 
+
+    /**
+     * Invalidates an object from the pool, using the provided
+     * {@link DestroyMode}.
+     * <p>
+     * By contract, {@code obj} <strong>must</strong> have been obtained
+     * using {@link #borrowObject borrowObject} or a related method as defined
+     * in an implementation or sub-interface using a {@code key} that is
+     * equivalent to the one used to borrow the {@code Object} in the first
+     * place.
+     * </p>
+     * <p>
+     * This method should be used when an object that has been borrowed is
+     * determined (due to an exception or other problem) to be invalid.
+     * </p>
+     *
+     * @param key the key used to obtain the object
+     * @param obj a {@link #borrowObject borrowed} instance to be returned.
+     * @param mode destroy activation context provided to the factory
+     *
+     * @throws Exception if the instance cannot be invalidated
+     * @since 2.9.0
+     */
+    default void invalidateObject(final K key, final V obj, final DestroyMode mode) throws Exception {
+        invalidateObject(key, obj);
+    }
+
     /**
      * Return an instance to the pool. By contract, {@code obj}
      * <strong>must</strong> have been obtained using
diff --git a/java/org/apache/tomcat/dbcp/pool2/KeyedPooledObjectFactory.java b/java/org/apache/tomcat/dbcp/pool2/KeyedPooledObjectFactory.java
index 5bf8b11..0a24a47 100644
--- a/java/org/apache/tomcat/dbcp/pool2/KeyedPooledObjectFactory.java
+++ b/java/org/apache/tomcat/dbcp/pool2/KeyedPooledObjectFactory.java
@@ -114,6 +114,26 @@ public interface KeyedPooledObjectFactory<K, V> {
     void destroyObject(K key, PooledObject<V> p) throws Exception;
 
     /**
+     * Destroy an instance no longer needed by the pool, using the provided {@link DestroyMode}.
+     *
+     * @param key the key used when selecting the instance
+     * @param p a {@code PooledObject} wrapping the instance to be destroyed
+     * @param mode DestroyMode providing context to the factory
+     *
+     * @throws Exception should be avoided as it may be swallowed by
+     *    the pool implementation.
+     *
+     * @see #validateObject
+     * @see KeyedObjectPool#invalidateObject
+     * @see #destroyObject(Object, PooledObject)
+     * @see DestroyMode
+     * @since 2.9.0
+     */
+    default void destroyObject(final K key, final PooledObject<V> p, final DestroyMode mode) throws Exception {
+        destroyObject(key, p);
+    }
+
+    /**
      * Ensures that the instance is safe to be returned by the pool.
      *
      * @param key the key used when selecting the object
diff --git a/java/org/apache/tomcat/dbcp/pool2/ObjectPool.java b/java/org/apache/tomcat/dbcp/pool2/ObjectPool.java
index d371317..426bc96 100644
--- a/java/org/apache/tomcat/dbcp/pool2/ObjectPool.java
+++ b/java/org/apache/tomcat/dbcp/pool2/ObjectPool.java
@@ -185,6 +185,29 @@ public interface ObjectPool<T> extends Closeable {
     void invalidateObject(T obj) throws Exception;
 
     /**
+     * Invalidates an object from the pool, using the provided
+     * {@link DestroyMode}
+     * <p>
+     * By contract, {@code obj} <strong>must</strong> have been obtained
+     * using {@link #borrowObject} or a related method as defined in an
+     * implementation or sub-interface.
+     * </p>
+     * <p>
+     * This method should be used when an object that has been borrowed is
+     * determined (due to an exception or other problem) to be invalid.
+     * </p>
+     *
+     * @param obj a {@link #borrowObject borrowed} instance to be disposed.
+     * @param mode destroy activation context provided to the factory
+     *
+     * @throws Exception if the instance cannot be invalidated
+     * @since 2.9.0
+     */
+    default void invalidateObject(final T obj, final DestroyMode mode) throws Exception {
+        invalidateObject(obj);
+    }
+
+    /**
      * Returns an instance to the pool. By contract, {@code obj}
      * <strong>must</strong> have been obtained using {@link #borrowObject()} or
      * a related method as defined in an implementation or sub-interface.
@@ -201,4 +224,5 @@ public interface ObjectPool<T> extends Closeable {
      * @throws Exception if an instance cannot be returned to the pool
      */
     void returnObject(T obj) throws Exception;
+
 }
diff --git a/java/org/apache/tomcat/dbcp/pool2/PooledObjectFactory.java b/java/org/apache/tomcat/dbcp/pool2/PooledObjectFactory.java
index 4973a1c..9c95d0d 100644
--- a/java/org/apache/tomcat/dbcp/pool2/PooledObjectFactory.java
+++ b/java/org/apache/tomcat/dbcp/pool2/PooledObjectFactory.java
@@ -84,7 +84,8 @@ public interface PooledObjectFactory<T> {
   PooledObject<T> makeObject() throws Exception;
 
   /**
-   * Destroys an instance no longer needed by the pool.
+   * Destroys an instance no longer needed by the pool, using the default (NORMAL)
+   * DestroyMode.
    * <p>
    * It is important for implementations of this method to be aware that there
    * is no guarantee about what state {@code obj} will be in and the
@@ -106,6 +107,26 @@ public interface PooledObjectFactory<T> {
   void destroyObject(PooledObject<T> p) throws Exception;
 
   /**
+   * Destroys an instance no longer needed by the pool, using the provided
+   * DestroyMode.
+   *
+   * @param p a {@code PooledObject} wrapping the instance to be destroyed
+   * @param mode DestroyMode providing context to the factory
+   *
+   * @throws Exception should be avoided as it may be swallowed by
+   *    the pool implementation.
+   *
+   * @see #validateObject
+   * @see ObjectPool#invalidateObject
+   * @see #destroyObject(PooledObject)
+   * @see DestroyMode
+   * @since 2.9.0
+   */
+  default void destroyObject(final PooledObject<T> p, final DestroyMode mode) throws Exception {
+      destroyObject(p);
+  }
+
+  /**
    * Ensures that the instance is safe to be returned by the pool.
    *
    * @param p a {@code PooledObject} wrapping the instance to be validated
diff --git a/java/org/apache/tomcat/dbcp/pool2/impl/EvictionTimer.java b/java/org/apache/tomcat/dbcp/pool2/impl/EvictionTimer.java
index 31e93d9..0e5759c 100644
--- a/java/org/apache/tomcat/dbcp/pool2/impl/EvictionTimer.java
+++ b/java/org/apache/tomcat/dbcp/pool2/impl/EvictionTimer.java
@@ -203,7 +203,7 @@ class EvictionTimer {
          *
          * @param ref the reference to track.
          */
-        private WeakRunner(WeakReference<Runnable> ref) {
+        private WeakRunner(final WeakReference<Runnable> ref) {
            this.ref = ref;
         }
 
diff --git a/java/org/apache/tomcat/dbcp/pool2/impl/GenericKeyedObjectPool.java b/java/org/apache/tomcat/dbcp/pool2/impl/GenericKeyedObjectPool.java
index 44f9c56..ebe4027 100644
--- a/java/org/apache/tomcat/dbcp/pool2/impl/GenericKeyedObjectPool.java
+++ b/java/org/apache/tomcat/dbcp/pool2/impl/GenericKeyedObjectPool.java
@@ -33,6 +33,7 @@ import java.util.concurrent.locks.Lock;
 import java.util.concurrent.locks.ReadWriteLock;
 import java.util.concurrent.locks.ReentrantReadWriteLock;
 
+import org.apache.tomcat.dbcp.pool2.DestroyMode;
 import org.apache.tomcat.dbcp.pool2.KeyedObjectPool;
 import org.apache.tomcat.dbcp.pool2.KeyedPooledObjectFactory;
 import org.apache.tomcat.dbcp.pool2.PoolUtils;
@@ -375,7 +376,7 @@ public class GenericKeyedObjectPool<K, T> extends BaseGenericObjectPool<T>
                         factory.activateObject(key, p);
                     } catch (final Exception e) {
                         try {
-                            destroy(key, p, true);
+                            destroy(key, p, true, DestroyMode.NORMAL);
                         } catch (final Exception e1) {
                             // Ignore - activation failure is more important
                         }
@@ -398,7 +399,7 @@ public class GenericKeyedObjectPool<K, T> extends BaseGenericObjectPool<T>
                         }
                         if (!validate) {
                             try {
-                                destroy(key, p, true);
+                                destroy(key, p, true, DestroyMode.NORMAL);
                                 destroyedByBorrowValidationCount.incrementAndGet();
                             } catch (final Exception e) {
                                 // Ignore - validation failure is more important
@@ -471,7 +472,7 @@ public class GenericKeyedObjectPool<K, T> extends BaseGenericObjectPool<T>
         try {
             if (getTestOnReturn() && !factory.validateObject(key, p)) {
                 try {
-                    destroy(key, p, true);
+                    destroy(key, p, true, DestroyMode.NORMAL);
                 } catch (final Exception e) {
                     swallowException(e);
                 }
@@ -484,7 +485,7 @@ public class GenericKeyedObjectPool<K, T> extends BaseGenericObjectPool<T>
             } catch (final Exception e1) {
                 swallowException(e1);
                 try {
-                    destroy(key, p, true);
+                    destroy(key, p, true, DestroyMode.NORMAL);
                 } catch (final Exception e) {
                     swallowException(e);
                 }
@@ -503,7 +504,7 @@ public class GenericKeyedObjectPool<K, T> extends BaseGenericObjectPool<T>
 
             if (isClosed() || maxIdle > -1 && maxIdle <= idleObjects.size()) {
                 try {
-                    destroy(key, p, true);
+                    destroy(key, p, true, DestroyMode.NORMAL);
                 } catch (final Exception e) {
                     swallowException(e);
                 }
@@ -559,6 +560,27 @@ public class GenericKeyedObjectPool<K, T> extends BaseGenericObjectPool<T>
      */
     @Override
     public void invalidateObject(final K key, final T obj) throws Exception {
+        invalidateObject(key, obj, DestroyMode.NORMAL);
+    }
+
+    /**
+     * {@inheritDoc}
+     * <p>
+     * Activation of this method decrements the active count associated with
+     * the given keyed pool and attempts to destroy {@code obj.}
+     *
+     * @param key pool key
+     * @param obj instance to invalidate
+     * @param mode DestroyMode context provided to factory
+     *
+     * @throws Exception             if an exception occurs destroying the
+     *                               object
+     * @throws IllegalStateException if obj does not belong to the pool
+     *                               under the given key
+     * @since 2.9.0
+     */
+    @Override
+    public void invalidateObject(final K key, final T obj, final DestroyMode mode) throws Exception {
 
         final ObjectDeque<T> objectDeque = poolMap.get(key);
 
@@ -569,7 +591,7 @@ public class GenericKeyedObjectPool<K, T> extends BaseGenericObjectPool<T>
         }
         synchronized (p) {
             if (p.getState() != PooledObjectState.INVALID) {
-                destroy(key, p, true);
+                destroy(key, p, true, mode);
             }
         }
         if (objectDeque.idleObjects.hasTakeWaiters()) {
@@ -627,7 +649,7 @@ public class GenericKeyedObjectPool<K, T> extends BaseGenericObjectPool<T>
 
             while (p != null) {
                 try {
-                    destroy(key, p, true);
+                    destroy(key, p, true, DestroyMode.NORMAL);
                 } catch (final Exception e) {
                     swallowException(e);
                 }
@@ -759,7 +781,7 @@ public class GenericKeyedObjectPool<K, T> extends BaseGenericObjectPool<T>
             // Assume the destruction succeeds
             boolean destroyed = true;
             try {
-                destroyed = destroy(key, p, false);
+                destroyed = destroy(key, p, false, DestroyMode.NORMAL);
             } catch (final Exception e) {
                 swallowException(e);
             }
@@ -936,7 +958,7 @@ public class GenericKeyedObjectPool<K, T> extends BaseGenericObjectPool<T>
                 }
 
                 if (evict) {
-                    destroy(evictionKey, underTest, true);
+                    destroy(evictionKey, underTest, true, DestroyMode.NORMAL);
                     destroyedByEvictorCount.incrementAndGet();
                 } else {
                     if (testWhileIdle) {
@@ -945,18 +967,18 @@ public class GenericKeyedObjectPool<K, T> extends BaseGenericObjectPool<T>
                             factory.activateObject(evictionKey, underTest);
                             active = true;
                         } catch (final Exception e) {
-                            destroy(evictionKey, underTest, true);
+                            destroy(evictionKey, underTest, true, DestroyMode.NORMAL);
                             destroyedByEvictorCount.incrementAndGet();
                         }
                         if (active) {
                             if (!factory.validateObject(evictionKey, underTest)) {
-                                destroy(evictionKey, underTest, true);
+                                destroy(evictionKey, underTest, true, DestroyMode.NORMAL);
                                 destroyedByEvictorCount.incrementAndGet();
                             } else {
                                 try {
                                     factory.passivateObject(evictionKey, underTest);
                                 } catch (final Exception e) {
-                                    destroy(evictionKey, underTest, true);
+                                    destroy(evictionKey, underTest, true, DestroyMode.NORMAL);
                                     destroyedByEvictorCount.incrementAndGet();
                                 }
                             }
@@ -1076,10 +1098,12 @@ public class GenericKeyedObjectPool<K, T> extends BaseGenericObjectPool<T>
      * @param toDestroy The wrapped object to be destroyed
      * @param always Should the object be destroyed even if it is not currently
      *               in the set of idle objects for the given key
+     * @param mode DestroyMode context provided to the factory
+     *
      * @return {@code true} if the object was destroyed, otherwise {@code false}
      * @throws Exception If the object destruction failed
      */
-    private boolean destroy(final K key, final PooledObject<T> toDestroy, final boolean always)
+    private boolean destroy(final K key, final PooledObject<T> toDestroy, final boolean always, final DestroyMode mode)
             throws Exception {
 
         final ObjectDeque<T> objectDeque = register(key);
@@ -1100,7 +1124,7 @@ public class GenericKeyedObjectPool<K, T> extends BaseGenericObjectPool<T>
                 toDestroy.invalidate();
 
                 try {
-                    factory.destroyObject(key, toDestroy);
+                    factory.destroyObject(key, toDestroy, mode);
                 } finally {
                     objectDeque.getCreateCount().decrementAndGet();
                     destroyedCount.incrementAndGet();
diff --git a/java/org/apache/tomcat/dbcp/pool2/impl/GenericObjectPool.java b/java/org/apache/tomcat/dbcp/pool2/impl/GenericObjectPool.java
index 81e66ee..b2bca4f 100644
--- a/java/org/apache/tomcat/dbcp/pool2/impl/GenericObjectPool.java
+++ b/java/org/apache/tomcat/dbcp/pool2/impl/GenericObjectPool.java
@@ -25,6 +25,7 @@ import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicLong;
 
+import org.apache.tomcat.dbcp.pool2.DestroyMode;
 import org.apache.tomcat.dbcp.pool2.ObjectPool;
 import org.apache.tomcat.dbcp.pool2.PoolUtils;
 import org.apache.tomcat.dbcp.pool2.PooledObject;
@@ -456,7 +457,7 @@ public class GenericObjectPool<T> extends BaseGenericObjectPool<T>
                     factory.activateObject(p);
                 } catch (final Exception e) {
                     try {
-                        destroy(p);
+                        destroy(p, DestroyMode.NORMAL);
                     } catch (final Exception e1) {
                         // Ignore - activation failure is more important
                     }
@@ -479,7 +480,7 @@ public class GenericObjectPool<T> extends BaseGenericObjectPool<T>
                     }
                     if (!validate) {
                         try {
-                            destroy(p);
+                            destroy(p, DestroyMode.NORMAL);
                             destroyedByBorrowValidationCount.incrementAndGet();
                         } catch (final Exception e) {
                             // Ignore - validation failure is more important
@@ -537,7 +538,7 @@ public class GenericObjectPool<T> extends BaseGenericObjectPool<T>
 
         if (getTestOnReturn() && !factory.validateObject(p)) {
             try {
-                destroy(p);
+                destroy(p, DestroyMode.NORMAL);
             } catch (final Exception e) {
                 swallowException(e);
             }
@@ -555,7 +556,7 @@ public class GenericObjectPool<T> extends BaseGenericObjectPool<T>
         } catch (final Exception e1) {
             swallowException(e1);
             try {
-                destroy(p);
+                destroy(p, DestroyMode.NORMAL);
             } catch (final Exception e) {
                 swallowException(e);
             }
@@ -576,7 +577,7 @@ public class GenericObjectPool<T> extends BaseGenericObjectPool<T>
         final int maxIdleSave = getMaxIdle();
         if (isClosed() || maxIdleSave > -1 && maxIdleSave <= idleObjects.size()) {
             try {
-                destroy(p);
+                destroy(p, DestroyMode.NORMAL);
             } catch (final Exception e) {
                 swallowException(e);
             }
@@ -605,7 +606,7 @@ public class GenericObjectPool<T> extends BaseGenericObjectPool<T>
      * {@inheritDoc}
      * <p>
      * Activation of this method decrements the active count and attempts to
-     * destroy the instance.
+     * destroy the instance, using the default (NORMAL) {@link DestroyMode}.
      * </p>
      *
      * @throws Exception             if an exception occurs destroying the
@@ -614,6 +615,23 @@ public class GenericObjectPool<T> extends BaseGenericObjectPool<T>
      */
     @Override
     public void invalidateObject(final T obj) throws Exception {
+        invalidateObject(obj, DestroyMode.NORMAL);
+    }
+
+    /**
+     * {@inheritDoc}
+     * <p>
+     * Activation of this method decrements the active count and attempts to
+     * destroy the instance, using the provided {@link DestroyMode}.
+     * </p>
+     *
+     * @throws Exception             if an exception occurs destroying the
+     *                               object
+     * @throws IllegalStateException if obj does not belong to this pool
+     * @since 2.9.0
+     */
+    @Override
+    public void invalidateObject(final T obj, final DestroyMode mode) throws Exception {
         final PooledObject<T> p = allObjects.get(new IdentityWrapper<>(obj));
         if (p == null) {
             if (isAbandonedConfig()) {
@@ -624,7 +642,7 @@ public class GenericObjectPool<T> extends BaseGenericObjectPool<T>
         }
         synchronized (p) {
             if (p.getState() != PooledObjectState.INVALID) {
-                destroy(p);
+                destroy(p, mode);
             }
         }
         ensureIdle(1, false);
@@ -655,7 +673,7 @@ public class GenericObjectPool<T> extends BaseGenericObjectPool<T>
 
         while (p != null) {
             try {
-                destroy(p);
+                destroy(p, DestroyMode.NORMAL);
             } catch (final Exception e) {
                 swallowException(e);
             }
@@ -775,7 +793,7 @@ public class GenericObjectPool<T> extends BaseGenericObjectPool<T>
                     }
 
                     if (evict) {
-                        destroy(underTest);
+                        destroy(underTest, DestroyMode.NORMAL);
                         destroyedByEvictorCount.incrementAndGet();
                     } else {
                         if (testWhileIdle) {
@@ -784,18 +802,18 @@ public class GenericObjectPool<T> extends BaseGenericObjectPool<T>
                                 factory.activateObject(underTest);
                                 active = true;
                             } catch (final Exception e) {
-                                destroy(underTest);
+                                destroy(underTest, DestroyMode.NORMAL);
                                 destroyedByEvictorCount.incrementAndGet();
                             }
                             if (active) {
                                 if (!factory.validateObject(underTest)) {
-                                    destroy(underTest);
+                                    destroy(underTest, DestroyMode.NORMAL);
                                     destroyedByEvictorCount.incrementAndGet();
                                 } else {
                                     try {
                                         factory.passivateObject(underTest);
                                     } catch (final Exception e) {
-                                        destroy(underTest);
+                                        destroy(underTest, DestroyMode.NORMAL);
                                         destroyedByEvictorCount.incrementAndGet();
                                     }
                                 }
@@ -926,16 +944,17 @@ public class GenericObjectPool<T> extends BaseGenericObjectPool<T>
      * Destroys a wrapped pooled object.
      *
      * @param toDestroy The wrapped pooled object to destroy
+     * @param mode DestroyMode context provided to the factory
      *
      * @throws Exception If the factory fails to destroy the pooled object
      *                   cleanly
      */
-    private void destroy(final PooledObject<T> toDestroy) throws Exception {
+    private void destroy(final PooledObject<T> toDestroy, final DestroyMode mode) throws Exception {
         toDestroy.invalidate();
         idleObjects.remove(toDestroy);
         allObjects.remove(new IdentityWrapper<>(toDestroy.getObject()));
         try {
-            factory.destroyObject(toDestroy);
+            factory.destroyObject(toDestroy, mode);
         } finally {
             destroyedCount.incrementAndGet();
             createCount.decrementAndGet();
@@ -1043,13 +1062,13 @@ public class GenericObjectPool<T> extends BaseGenericObjectPool<T>
      * Recovers abandoned objects which have been checked out but
      * not used since longer than the removeAbandonedTimeout.
      *
-     * @param ac The configuration to use to identify abandoned objects
+     * @param abandonedConfig The configuration to use to identify abandoned objects
      */
-    private void removeAbandoned(final AbandonedConfig ac) {
+    private void removeAbandoned(final AbandonedConfig abandonedConfig) {
         // Generate a list of abandoned objects to remove
         final long now = System.currentTimeMillis();
         final long timeout =
-                now - (ac.getRemoveAbandonedTimeout() * 1000L);
+                now - (abandonedConfig.getRemoveAbandonedTimeout() * 1000L);
         final ArrayList<PooledObject<T>> remove = new ArrayList<>();
         for (PooledObject<T> pooledObject : allObjects.values()) {
             synchronized (pooledObject) {
@@ -1063,11 +1082,11 @@ public class GenericObjectPool<T> extends BaseGenericObjectPool<T>
 
         // Now remove the abandoned objects
         for (PooledObject<T> pooledObject : remove) {
-            if (ac.getLogAbandoned()) {
-                pooledObject.printStackTrace(ac.getLogWriter());
+            if (abandonedConfig.getLogAbandoned()) {
+                pooledObject.printStackTrace(abandonedConfig.getLogWriter());
             }
             try {
-                invalidateObject(pooledObject.getObject());
+                invalidateObject(pooledObject.getObject(), DestroyMode.ABANDONED);
             } catch (final Exception e) {
                 e.printStackTrace();
             }
@@ -1079,8 +1098,8 @@ public class GenericObjectPool<T> extends BaseGenericObjectPool<T>
 
     @Override
     public void use(final T pooledObject) {
-        final AbandonedConfig ac = this.abandonedConfig;
-        if (ac != null && ac.getUseUsageTracking()) {
+        final AbandonedConfig abandonedCfg = this.abandonedConfig;
+        if (abandonedCfg != null && abandonedCfg.getUseUsageTracking()) {
             final PooledObject<T> wrapper = allObjects.get(new IdentityWrapper<>(pooledObject));
             wrapper.use();
         }
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index 6d871c4..539a0c6 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -214,6 +214,10 @@
         Update the packaged version of the Tomcat Native Library to 1.2.26.
         (markt)
       </update>
+      <add>
+        Update the internal fork of Apache Commons Pool to 2.9.1-SNAPSHOT
+        (2021-01-15). (markt)
+      </add>
     </changelog>
   </subsection>
 </section>


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