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 2019/12/07 17:14:07 UTC
[tomcat] 04/18: Merge in Pool 2 changes to 6092f92 (2019-12-06,
2.8.0-SNAPSHOT)
This is an automated email from the ASF dual-hosted git repository.
markt pushed a commit to branch 8.5.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git
commit a3fd9eee952b99974b23f0b328f5fb3f25f79c5e
Author: Mark Thomas <ma...@apache.org>
AuthorDate: Fri Dec 6 15:43:08 2019 +0000
Merge in Pool 2 changes to 6092f92 (2019-12-06, 2.8.0-SNAPSHOT)
---
MERGE.txt | 12 +-
.../dbcp/pool2/BaseKeyedPooledObjectFactory.java | 2 +
.../apache/tomcat/dbcp/pool2/BaseObjectPool.java | 18 +
.../apache/tomcat/dbcp/pool2/KeyedObjectPool.java | 211 ++--
java/org/apache/tomcat/dbcp/pool2/ObjectPool.java | 134 ++-
java/org/apache/tomcat/dbcp/pool2/PoolUtils.java | 1270 ++------------------
.../org/apache/tomcat/dbcp/pool2/PooledObject.java | 3 +-
.../dbcp/pool2/impl/DefaultEvictionPolicy.java | 2 +
.../tomcat/dbcp/pool2/impl/EvictionConfig.java | 1 +
.../dbcp/pool2/impl/GenericKeyedObjectPool.java | 78 +-
.../tomcat/dbcp/pool2/impl/GenericObjectPool.java | 46 +-
.../pool2/impl/InterruptibleReentrantLock.java | 1 +
.../dbcp/pool2/impl/LinkedBlockingDeque.java | 4 +
.../dbcp/pool2/impl/SoftReferenceObjectPool.java | 3 +
webapps/docs/changelog.xml | 4 +
15 files changed, 421 insertions(+), 1368 deletions(-)
diff --git a/MERGE.txt b/MERGE.txt
index 893ac89..7daec6d 100644
--- a/MERGE.txt
+++ b/MERGE.txt
@@ -58,15 +58,15 @@ Note: Tomcat's copy of fileupload also includes classes copied manually from
DBCP
----
+Pool2
+Sub-tree
+src/main/java/org/apache/commons/pool2
+The SHA1 ID for the most recent commit to be merged to Tomcat is:
+6092f924b36061353ff92b18c88400ab3bc05327 (2019-12-06)
+
DBCP2
Sub-tree
src/main/java/org/apache/commons/dbcp2
src/main/resources/org/apache/commons/dbcp2
The SHA1 ID for the most recent commit to be merged to Tomcat is:
4813b7f5456c1f4fecc4f701ac731a71f57db249 (2019-08-09)
-
-Pool2
-Sub-tree
-src/main/java/org/apache/commons/pool2
-The SHA1 ID for the most recent commit to be merged to Tomcat is:
-796e32d53cc0d870ba0db3a7faf4c5b24ff76f3f (2019-08-01)
diff --git a/java/org/apache/tomcat/dbcp/pool2/BaseKeyedPooledObjectFactory.java b/java/org/apache/tomcat/dbcp/pool2/BaseKeyedPooledObjectFactory.java
index 3dd7429..dfbc5a9 100644
--- a/java/org/apache/tomcat/dbcp/pool2/BaseKeyedPooledObjectFactory.java
+++ b/java/org/apache/tomcat/dbcp/pool2/BaseKeyedPooledObjectFactory.java
@@ -21,7 +21,9 @@ package org.apache.tomcat.dbcp.pool2;
* <p>
* All operations defined here are essentially no-op's.
* </p>
+ * <p>
* This class is immutable, and therefore thread-safe.
+ * </p>
*
* @see KeyedPooledObjectFactory
*
diff --git a/java/org/apache/tomcat/dbcp/pool2/BaseObjectPool.java b/java/org/apache/tomcat/dbcp/pool2/BaseObjectPool.java
index 29f189a..96d3c00 100644
--- a/java/org/apache/tomcat/dbcp/pool2/BaseObjectPool.java
+++ b/java/org/apache/tomcat/dbcp/pool2/BaseObjectPool.java
@@ -22,6 +22,7 @@ package org.apache.tomcat.dbcp.pool2;
* indicating it is unsupported or throw {@link UnsupportedOperationException}.
* <p>
* This class is intended to be thread-safe.
+ * </p>
*
* @param <T> Type of element pooled in this pool.
*
@@ -82,6 +83,23 @@ public abstract class BaseObjectPool<T> extends BaseObject implements ObjectPool
}
/**
+ * Calls {@link ObjectPool#addObject()} <code>count</code>
+ * number of times.
+ *
+ * @param count
+ * the number of idle objects to add.
+ * @throws Exception
+ * when {@link ObjectPool#addObject()} fails.
+ * @since 2.8.0
+ */
+ @Override
+ public void addObjects(final int count) throws Exception {
+ for (int i = 0; i < count; i++) {
+ addObject();
+ }
+ }
+
+ /**
* {@inheritDoc}
* <p>
* This affects the behavior of <code>isClosed</code> and
diff --git a/java/org/apache/tomcat/dbcp/pool2/KeyedObjectPool.java b/java/org/apache/tomcat/dbcp/pool2/KeyedObjectPool.java
index 4df37d8..df325ed 100644
--- a/java/org/apache/tomcat/dbcp/pool2/KeyedObjectPool.java
+++ b/java/org/apache/tomcat/dbcp/pool2/KeyedObjectPool.java
@@ -17,6 +17,7 @@
package org.apache.tomcat.dbcp.pool2;
import java.io.Closeable;
+import java.util.Collection;
import java.util.NoSuchElementException;
/**
@@ -66,6 +67,60 @@ import java.util.NoSuchElementException;
* @since 2.0
*/
public interface KeyedObjectPool<K, V> extends Closeable {
+
+ /**
+ * Create an object using the {@link KeyedPooledObjectFactory factory} or
+ * other implementation dependent mechanism, passivate it, and then place it
+ * in the idle object pool. <code>addObject</code> is useful for
+ * "pre-loading" a pool with idle objects (Optional operation).
+ *
+ * @param key the key a new instance should be added to
+ *
+ * @throws Exception
+ * when {@link KeyedPooledObjectFactory#makeObject} fails.
+ * @throws IllegalStateException
+ * after {@link #close} has been called on this pool.
+ * @throws UnsupportedOperationException
+ * when this pool cannot add new idle objects.
+ */
+ void addObject(K key) throws Exception, IllegalStateException,
+ UnsupportedOperationException;
+
+ /**
+ * Calls {@link KeyedObjectPool#addObject(Object)} with each
+ * key in <code>keys</code> for <code>count</code> number of times. This has
+ * the same effect as calling {@link #addObjects(Object, int)}
+ * for each key in the <code>keys</code> collection.
+ *
+ * @param keys
+ * {@link Collection} of keys to add objects for.
+ * @param count
+ * the number of idle objects to add for each <code>key</code>.
+ * @throws Exception
+ * when {@link KeyedObjectPool#addObject(Object)} fails.
+ * @throws IllegalArgumentException
+ * when <code>keyedPool</code>, <code>keys</code>, or any value
+ * in <code>keys</code> is <code>null</code>.
+ * @see #addObjects(Object, int)
+ */
+ void addObjects(final Collection<K> keys, final int count) throws Exception, IllegalArgumentException;
+
+ /**
+ * Calls {@link KeyedObjectPool#addObject(Object)}
+ * <code>key</code> <code>count</code> number of times.
+ *
+ * @param key
+ * the key to add objects for.
+ * @param count
+ * the number of idle objects to add for <code>key</code>.
+ * @throws Exception
+ * when {@link KeyedObjectPool#addObject(Object)} fails.
+ * @throws IllegalArgumentException
+ * when <code>key</code> is <code>null</code>.
+ * @since 2.8.0
+ */
+ void addObjects(final K key, final int count) throws Exception, IllegalArgumentException;
+
/**
* Obtains an instance from this pool for the specified <code>key</code>.
* <p>
@@ -105,75 +160,50 @@ public interface KeyedObjectPool<K, V> extends Closeable {
V borrowObject(K key) throws Exception, NoSuchElementException, IllegalStateException;
/**
- * Return an instance to the pool. By contract, <code>obj</code>
- * <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</code> that is
- * equivalent to the one used to borrow the instance in the first place.
- *
- * @param key the key used to obtain the object
- * @param obj a {@link #borrowObject borrowed} instance to be returned.
+ * Clears the pool, removing all pooled instances (optional operation).
*
- * @throws IllegalStateException
- * if an attempt is made to return an object to the pool that
- * is in any state other than allocated (i.e. borrowed).
- * Attempting to return an object more than once or attempting
- * to return an object that was never borrowed from the pool
- * will trigger this exception.
+ * @throws UnsupportedOperationException when this implementation doesn't
+ * support the operation
*
- * @throws Exception if an instance cannot be returned to the pool
+ * @throws Exception if the pool cannot be cleared
*/
- void returnObject(K key, V obj) throws Exception;
+ void clear() throws Exception, UnsupportedOperationException;
/**
- * Invalidates an object from the pool.
- * <p>
- * By contract, <code>obj</code> <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</code> that is
- * equivalent to the one used to borrow the <code>Object</code> 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>
+ * Clears the specified pool, removing all pooled instances corresponding to
+ * the given <code>key</code> (optional operation).
*
- * @param key the key used to obtain the object
- * @param obj a {@link #borrowObject borrowed} instance to be returned.
+ * @param key the key to clear
*
- * @throws Exception if the instance cannot be invalidated
+ * @throws UnsupportedOperationException when this implementation doesn't
+ * support the operation
+ *
+ * @throws Exception if the key cannot be cleared
*/
- void invalidateObject(K key, V obj) throws Exception;
+ void clear(K key) throws Exception, UnsupportedOperationException;
/**
- * Create an object using the {@link KeyedPooledObjectFactory factory} or
- * other implementation dependent mechanism, passivate it, and then place it
- * in the idle object pool. <code>addObject</code> is useful for
- * "pre-loading" a pool with idle objects (Optional operation).
- *
- * @param key the key a new instance should be added to
- *
- * @throws Exception
- * when {@link KeyedPooledObjectFactory#makeObject} fails.
- * @throws IllegalStateException
- * after {@link #close} has been called on this pool.
- * @throws UnsupportedOperationException
- * when this pool cannot add new idle objects.
+ * Close this pool, and free any resources associated with it.
+ * <p>
+ * Calling {@link #addObject addObject} or
+ * {@link #borrowObject borrowObject} after invoking this method on a pool
+ * will cause them to throw an {@link IllegalStateException}.
+ * </p>
+ * <p>
+ * Implementations should silently fail if not all resources can be freed.
+ * </p>
*/
- void addObject(K key) throws Exception, IllegalStateException,
- UnsupportedOperationException;
+ @Override
+ void close();
/**
- * Returns the number of instances corresponding to the given
- * <code>key</code> currently idle in this pool. Returns a negative value if
- * this information is not available.
- *
- * @param key the key to query
- * @return the number of instances corresponding to the given
- * <code>key</code> currently idle in this pool.
+ * Returns the total number of instances currently borrowed from this pool but
+ * not yet returned. Returns a negative value if this information is not
+ * available.
+ * @return the total number of instances currently borrowed from this pool but
+ * not yet returned.
*/
- int getNumIdle(K key);
+ int getNumActive();
/**
* Returns the number of instances currently borrowed from but not yet
@@ -194,48 +224,55 @@ public interface KeyedObjectPool<K, V> extends Closeable {
int getNumIdle();
/**
- * Returns the total number of instances currently borrowed from this pool but
- * not yet returned. Returns a negative value if this information is not
- * available.
- * @return the total number of instances currently borrowed from this pool but
- * not yet returned.
+ * Returns the number of instances corresponding to the given
+ * <code>key</code> currently idle in this pool. Returns a negative value if
+ * this information is not available.
+ *
+ * @param key the key to query
+ * @return the number of instances corresponding to the given
+ * <code>key</code> currently idle in this pool.
*/
- int getNumActive();
+ int getNumIdle(K key);
/**
- * Clears the pool, removing all pooled instances (optional operation).
+ * Invalidates an object from the pool.
+ * <p>
+ * By contract, <code>obj</code> <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</code> that is
+ * equivalent to the one used to borrow the <code>Object</code> 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>
*
- * @throws UnsupportedOperationException when this implementation doesn't
- * support the operation
+ * @param key the key used to obtain the object
+ * @param obj a {@link #borrowObject borrowed} instance to be returned.
*
- * @throws Exception if the pool cannot be cleared
+ * @throws Exception if the instance cannot be invalidated
*/
- void clear() throws Exception, UnsupportedOperationException;
+ void invalidateObject(K key, V obj) throws Exception;
/**
- * Clears the specified pool, removing all pooled instances corresponding to
- * the given <code>key</code> (optional operation).
+ * Return an instance to the pool. By contract, <code>obj</code>
+ * <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</code> that is
+ * equivalent to the one used to borrow the instance in the first place.
*
- * @param key the key to clear
+ * @param key the key used to obtain the object
+ * @param obj a {@link #borrowObject borrowed} instance to be returned.
*
- * @throws UnsupportedOperationException when this implementation doesn't
- * support the operation
+ * @throws IllegalStateException
+ * if an attempt is made to return an object to the pool that
+ * is in any state other than allocated (i.e. borrowed).
+ * Attempting to return an object more than once or attempting
+ * to return an object that was never borrowed from the pool
+ * will trigger this exception.
*
- * @throws Exception if the key cannot be cleared
- */
- void clear(K key) throws Exception, UnsupportedOperationException;
-
- /**
- * Close this pool, and free any resources associated with it.
- * <p>
- * Calling {@link #addObject addObject} or
- * {@link #borrowObject borrowObject} after invoking this method on a pool
- * will cause them to throw an {@link IllegalStateException}.
- * </p>
- * <p>
- * Implementations should silently fail if not all resources can be freed.
- * </p>
+ * @throws Exception if an instance cannot be returned to the pool
*/
- @Override
- void close();
+ void returnObject(K key, V obj) throws Exception;
}
diff --git a/java/org/apache/tomcat/dbcp/pool2/ObjectPool.java b/java/org/apache/tomcat/dbcp/pool2/ObjectPool.java
index 6303245..22eb12a 100644
--- a/java/org/apache/tomcat/dbcp/pool2/ObjectPool.java
+++ b/java/org/apache/tomcat/dbcp/pool2/ObjectPool.java
@@ -60,6 +60,34 @@ import java.util.NoSuchElementException;
public interface ObjectPool<T> extends Closeable {
/**
+ * Creates an object using the {@link PooledObjectFactory factory} or other
+ * implementation dependent mechanism, passivate it, and then place it in
+ * the idle object pool. <code>addObject</code> is useful for "pre-loading"
+ * a pool with idle objects. (Optional operation).
+ *
+ * @throws Exception
+ * when {@link PooledObjectFactory#makeObject} fails.
+ * @throws IllegalStateException
+ * after {@link #close} has been called on this pool.
+ * @throws UnsupportedOperationException
+ * when this pool cannot add new idle objects.
+ */
+ void addObject() throws Exception, IllegalStateException,
+ UnsupportedOperationException;
+
+ /**
+ * Calls {@link ObjectPool#addObject()} <code>count</code>
+ * number of times.
+ *
+ * @param count
+ * the number of idle objects to add.
+ * @throws Exception
+ * when {@link ObjectPool#addObject()} fails.
+ * @since 2.8.0
+ */
+ void addObjects(final int count) throws Exception;
+
+ /**
* Obtains an instance from this pool.
* <p>
* Instances returned from this method will have been either newly created
@@ -94,56 +122,36 @@ public interface ObjectPool<T> extends Closeable {
IllegalStateException;
/**
- * Returns an instance to the pool. By contract, <code>obj</code>
- * <strong>must</strong> have been obtained using {@link #borrowObject()} or
- * a related method as defined in an implementation or sub-interface.
- *
- * @param obj a {@link #borrowObject borrowed} instance to be returned.
+ * Clears any objects sitting idle in the pool, releasing any associated
+ * resources (optional operation). Idle objects cleared must be
+ * {@link PooledObjectFactory#destroyObject(PooledObject)}.
*
- * @throws IllegalStateException
- * if an attempt is made to return an object to the pool that
- * is in any state other than allocated (i.e. borrowed).
- * Attempting to return an object more than once or attempting
- * to return an object that was never borrowed from the pool
- * will trigger this exception.
+ * @throws UnsupportedOperationException
+ * if this implementation does not support the operation
*
- * @throws Exception if an instance cannot be returned to the pool
+ * @throws Exception if the pool cannot be cleared
*/
- void returnObject(T obj) throws Exception;
+ void clear() throws Exception, UnsupportedOperationException;
/**
- * Invalidates an object from the pool.
+ * Closes this pool, and free any resources associated with it.
* <p>
- * By contract, <code>obj</code> <strong>must</strong> have been obtained
- * using {@link #borrowObject} or a related method as defined in an
- * implementation or sub-interface.
+ * Calling {@link #addObject} or {@link #borrowObject} after invoking this
+ * method on a pool will cause them to throw an {@link IllegalStateException}.
* </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.
+ * Implementations should silently fail if not all resources can be freed.
* </p>
- *
- * @param obj a {@link #borrowObject borrowed} instance to be disposed.
- *
- * @throws Exception if the instance cannot be invalidated
*/
- void invalidateObject(T obj) throws Exception;
+ @Override
+ void close();
/**
- * Creates an object using the {@link PooledObjectFactory factory} or other
- * implementation dependent mechanism, passivate it, and then place it in
- * the idle object pool. <code>addObject</code> is useful for "pre-loading"
- * a pool with idle objects. (Optional operation).
- *
- * @throws Exception
- * when {@link PooledObjectFactory#makeObject} fails.
- * @throws IllegalStateException
- * after {@link #close} has been called on this pool.
- * @throws UnsupportedOperationException
- * when this pool cannot add new idle objects.
+ * Returns the number of instances currently borrowed from this pool. Returns
+ * a negative value if this information is not available.
+ * @return the number of instances currently borrowed from this pool.
*/
- void addObject() throws Exception, IllegalStateException,
- UnsupportedOperationException;
+ int getNumActive();
/**
* Returns the number of instances currently idle in this pool. This may be
@@ -155,34 +163,38 @@ public interface ObjectPool<T> extends Closeable {
int getNumIdle();
/**
- * Returns the number of instances currently borrowed from this pool. Returns
- * a negative value if this information is not available.
- * @return the number of instances currently borrowed from this pool.
- */
- int getNumActive();
-
- /**
- * Clears any objects sitting idle in the pool, releasing any associated
- * resources (optional operation). Idle objects cleared must be
- * {@link PooledObjectFactory#destroyObject(PooledObject)}.
+ * Invalidates an object from the pool.
+ * <p>
+ * By contract, <code>obj</code> <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>
*
- * @throws UnsupportedOperationException
- * if this implementation does not support the operation
+ * @param obj a {@link #borrowObject borrowed} instance to be disposed.
*
- * @throws Exception if the pool cannot be cleared
+ * @throws Exception if the instance cannot be invalidated
*/
- void clear() throws Exception, UnsupportedOperationException;
+ void invalidateObject(T obj) throws Exception;
/**
- * Closes this pool, and free any resources associated with it.
- * <p>
- * Calling {@link #addObject} or {@link #borrowObject} after invoking this
- * method on a pool will cause them to throw an {@link IllegalStateException}.
- * </p>
- * <p>
- * Implementations should silently fail if not all resources can be freed.
- * </p>
+ * Returns an instance to the pool. By contract, <code>obj</code>
+ * <strong>must</strong> have been obtained using {@link #borrowObject()} or
+ * a related method as defined in an implementation or sub-interface.
+ *
+ * @param obj a {@link #borrowObject borrowed} instance to be returned.
+ *
+ * @throws IllegalStateException
+ * if an attempt is made to return an object to the pool that
+ * is in any state other than allocated (i.e. borrowed).
+ * Attempting to return an object more than once or attempting
+ * to return an object that was never borrowed from the pool
+ * will trigger this exception.
+ *
+ * @throws Exception if an instance cannot be returned to the pool
*/
- @Override
- void close();
+ void returnObject(T obj) throws Exception;
}
diff --git a/java/org/apache/tomcat/dbcp/pool2/PoolUtils.java b/java/org/apache/tomcat/dbcp/pool2/PoolUtils.java
index 2494351..7df2f9a 100644
--- a/java/org/apache/tomcat/dbcp/pool2/PoolUtils.java
+++ b/java/org/apache/tomcat/dbcp/pool2/PoolUtils.java
@@ -17,15 +17,12 @@
package org.apache.tomcat.dbcp.pool2;
import java.util.Collection;
-import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
-import java.util.NoSuchElementException;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.locks.ReentrantReadWriteLock;
-import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
/**
@@ -36,11 +33,10 @@ import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
*/
public final class PoolUtils {
- private static final String MSG_FACTOR_NEGATIVE = "factor must be positive.";
private static final String MSG_MIN_IDLE = "minIdle must be non-negative.";
- private static final String MSG_NULL_KEY = "key must not be null.";
+ public static final String MSG_NULL_KEY = "key must not be null.";
private static final String MSG_NULL_KEYED_POOL = "keyedPool must not be null.";
- private static final String MSG_NULL_KEYS = "keys must not be null.";
+ public static final String MSG_NULL_KEYS = "keys must not be null.";
private static final String MSG_NULL_POOL = "pool must not be null.";
/**
@@ -220,15 +216,15 @@ public final class PoolUtils {
* when {@link ObjectPool#addObject()} fails.
* @throws IllegalArgumentException
* when <code>pool</code> is <code>null</code>.
+ * @deprecated Use {@link ObjectPool#addObjects(int)}.
*/
+ @Deprecated
public static <T> void prefill(final ObjectPool<T> pool, final int count)
throws Exception, IllegalArgumentException {
if (pool == null) {
throw new IllegalArgumentException(MSG_NULL_POOL);
}
- for (int i = 0; i < count; i++) {
- pool.addObject();
- }
+ pool.addObjects(count);
}
/**
@@ -248,19 +244,16 @@ public final class PoolUtils {
* @throws IllegalArgumentException
* when <code>keyedPool</code> or <code>key</code> is
* <code>null</code>.
+ * @deprecated Use {@link KeyedObjectPool#addObjects(Object, int)}.
*/
+ @Deprecated
public static <K, V> void prefill(final KeyedObjectPool<K, V> keyedPool,
final K key, final int count) throws Exception,
IllegalArgumentException {
if (keyedPool == null) {
throw new IllegalArgumentException(MSG_NULL_KEYED_POOL);
}
- if (key == null) {
- throw new IllegalArgumentException(MSG_NULL_KEY);
- }
- for (int i = 0; i < count; i++) {
- keyedPool.addObject(key);
- }
+ keyedPool.addObjects(key, count);
}
/**
@@ -283,85 +276,16 @@ public final class PoolUtils {
* when <code>keyedPool</code>, <code>keys</code>, or any value
* in <code>keys</code> is <code>null</code>.
* @see #prefill(KeyedObjectPool, Object, int)
+ * @deprecated Use {@link KeyedObjectPool#addObjects(Collection, int)}.
*/
+ @Deprecated
public static <K, V> void prefill(final KeyedObjectPool<K, V> keyedPool,
final Collection<K> keys, final int count) throws Exception,
IllegalArgumentException {
if (keys == null) {
throw new IllegalArgumentException(MSG_NULL_KEYS);
}
- final Iterator<K> iter = keys.iterator();
- while (iter.hasNext()) {
- prefill(keyedPool, iter.next(), count);
- }
- }
-
- /**
- * Returns a synchronized (thread-safe) ObjectPool backed by the specified
- * ObjectPool.
- * <p>
- * <b>Note:</b> This should not be used on pool implementations that already
- * provide proper synchronization such as the pools provided in the Commons
- * Pool library. Wrapping a pool that {@link #wait() waits} for poolable
- * objects to be returned before allowing another one to be borrowed with
- * another layer of synchronization will cause liveliness issues or a
- * deadlock.
- * </p>
- *
- * @param pool
- * the ObjectPool to be "wrapped" in a synchronized ObjectPool.
- * @param <T> the type of objects in the pool
- * @return a synchronized view of the specified ObjectPool.
- */
- public static <T> ObjectPool<T> synchronizedPool(final ObjectPool<T> pool) {
- if (pool == null) {
- throw new IllegalArgumentException(MSG_NULL_POOL);
- }
- /*
- * assert !(pool instanceof GenericObjectPool) :
- * "GenericObjectPool is already thread-safe"; assert !(pool instanceof
- * SoftReferenceObjectPool) :
- * "SoftReferenceObjectPool is already thread-safe"; assert !(pool
- * instanceof StackObjectPool) :
- * "StackObjectPool is already thread-safe"; assert
- * !"org.apache.commons.pool.composite.CompositeObjectPool"
- * .equals(pool.getClass().getName()) :
- * "CompositeObjectPools are already thread-safe";
- */
- return new SynchronizedObjectPool<>(pool);
- }
-
- /**
- * Returns a synchronized (thread-safe) KeyedObjectPool backed by the
- * specified KeyedObjectPool.
- * <p>
- * <b>Note:</b> This should not be used on pool implementations that already
- * provide proper synchronization such as the pools provided in the Commons
- * Pool library. Wrapping a pool that {@link #wait() waits} for poolable
- * objects to be returned before allowing another one to be borrowed with
- * another layer of synchronization will cause liveliness issues or a
- * deadlock.
- * </p>
- *
- * @param keyedPool
- * the KeyedObjectPool to be "wrapped" in a synchronized
- * KeyedObjectPool.
- * @param <K> the type of the pool key
- * @param <V> the type of pool entries
- * @return a synchronized view of the specified KeyedObjectPool.
- */
- public static <K, V> KeyedObjectPool<K, V> synchronizedPool(
- final KeyedObjectPool<K, V> keyedPool) {
- /*
- * assert !(keyedPool instanceof GenericKeyedObjectPool) :
- * "GenericKeyedObjectPool is already thread-safe"; assert !(keyedPool
- * instanceof StackKeyedObjectPool) :
- * "StackKeyedObjectPool is already thread-safe"; assert
- * !"org.apache.commons.pool.composite.CompositeKeyedObjectPool"
- * .equals(keyedPool.getClass().getName()) :
- * "CompositeKeyedObjectPools are already thread-safe";
- */
- return new SynchronizedKeyedObjectPool<>(keyedPool);
+ keyedPool.addObjects(keys, count);
}
/**
@@ -396,167 +320,6 @@ public final class PoolUtils {
}
/**
- * Returns a pool that adaptively decreases its size when idle objects are
- * no longer needed. This is intended as an always thread-safe alternative
- * to using an idle object evictor provided by many pool implementations.
- * This is also an effective way to shrink FIFO ordered pools that
- * experience load spikes.
- *
- * @param pool
- * the ObjectPool to be decorated so it shrinks its idle count
- * when possible.
- * @param <T> the type of objects in the pool
- * @return a pool that adaptively decreases its size when idle objects are
- * no longer needed.
- * @see #erodingPool(ObjectPool, float)
- */
- public static <T> ObjectPool<T> erodingPool(final ObjectPool<T> pool) {
- return erodingPool(pool, 1f);
- }
-
- /**
- * Returns a pool that adaptively decreases its size when idle objects are
- * no longer needed. This is intended as an always thread-safe alternative
- * to using an idle object evictor provided by many pool implementations.
- * This is also an effective way to shrink FIFO ordered pools that
- * experience load spikes.
- * <p>
- * The factor parameter provides a mechanism to tweak the rate at which the
- * pool tries to shrink its size. Values between 0 and 1 cause the pool to
- * try to shrink its size more often. Values greater than 1 cause the pool
- * to less frequently try to shrink its size.
- * </p>
- *
- * @param pool
- * the ObjectPool to be decorated so it shrinks its idle count
- * when possible.
- * @param factor
- * a positive value to scale the rate at which the pool tries to
- * reduce its size. If 0 < factor < 1 then the pool
- * shrinks more aggressively. If 1 < factor then the pool
- * shrinks less aggressively.
- * @param <T> the type of objects in the pool
- * @return a pool that adaptively decreases its size when idle objects are
- * no longer needed.
- * @see #erodingPool(ObjectPool)
- */
- public static <T> ObjectPool<T> erodingPool(final ObjectPool<T> pool,
- final float factor) {
- if (pool == null) {
- throw new IllegalArgumentException(MSG_NULL_POOL);
- }
- if (factor <= 0f) {
- throw new IllegalArgumentException(MSG_FACTOR_NEGATIVE);
- }
- return new ErodingObjectPool<>(pool, factor);
- }
-
- /**
- * Returns a pool that adaptively decreases its size when idle objects are
- * no longer needed. This is intended as an always thread-safe alternative
- * to using an idle object evictor provided by many pool implementations.
- * This is also an effective way to shrink FIFO ordered pools that
- * experience load spikes.
- *
- * @param keyedPool
- * the KeyedObjectPool to be decorated so it shrinks its idle
- * count when possible.
- * @param <K> the type of the pool key
- * @param <V> the type of pool entries
- * @return a pool that adaptively decreases its size when idle objects are
- * no longer needed.
- * @see #erodingPool(KeyedObjectPool, float)
- * @see #erodingPool(KeyedObjectPool, float, boolean)
- */
- public static <K, V> KeyedObjectPool<K, V> erodingPool(
- final KeyedObjectPool<K, V> keyedPool) {
- return erodingPool(keyedPool, 1f);
- }
-
- /**
- * Returns a pool that adaptively decreases its size when idle objects are
- * no longer needed. This is intended as an always thread-safe alternative
- * to using an idle object evictor provided by many pool implementations.
- * This is also an effective way to shrink FIFO ordered pools that
- * experience load spikes.
- * <p>
- * The factor parameter provides a mechanism to tweak the rate at which the
- * pool tries to shrink its size. Values between 0 and 1 cause the pool to
- * try to shrink its size more often. Values greater than 1 cause the pool
- * to less frequently try to shrink its size.
- * </p>
- *
- * @param keyedPool
- * the KeyedObjectPool to be decorated so it shrinks its idle
- * count when possible.
- * @param factor
- * a positive value to scale the rate at which the pool tries to
- * reduce its size. If 0 < factor < 1 then the pool
- * shrinks more aggressively. If 1 < factor then the pool
- * shrinks less aggressively.
- * @param <K> the type of the pool key
- * @param <V> the type of pool entries
- * @return a pool that adaptively decreases its size when idle objects are
- * no longer needed.
- * @see #erodingPool(KeyedObjectPool, float, boolean)
- */
- public static <K, V> KeyedObjectPool<K, V> erodingPool(
- final KeyedObjectPool<K, V> keyedPool, final float factor) {
- return erodingPool(keyedPool, factor, false);
- }
-
- /**
- * Returns a pool that adaptively decreases its size when idle objects are
- * no longer needed. This is intended as an always thread-safe alternative
- * to using an idle object evictor provided by many pool implementations.
- * This is also an effective way to shrink FIFO ordered pools that
- * experience load spikes.
- * <p>
- * The factor parameter provides a mechanism to tweak the rate at which the
- * pool tries to shrink its size. Values between 0 and 1 cause the pool to
- * try to shrink its size more often. Values greater than 1 cause the pool
- * to less frequently try to shrink its size.
- * </p>
- * <p>
- * The perKey parameter determines if the pool shrinks on a whole pool basis
- * or a per key basis. When perKey is false, the keys do not have an effect
- * on the rate at which the pool tries to shrink its size. When perKey is
- * true, each key is shrunk independently.
- * </p>
- *
- * @param keyedPool
- * the KeyedObjectPool to be decorated so it shrinks its idle
- * count when possible.
- * @param factor
- * a positive value to scale the rate at which the pool tries to
- * reduce its size. If 0 < factor < 1 then the pool
- * shrinks more aggressively. If 1 < factor then the pool
- * shrinks less aggressively.
- * @param perKey
- * when true, each key is treated independently.
- * @param <K> the type of the pool key
- * @param <V> the type of pool entries
- * @return a pool that adaptively decreases its size when idle objects are
- * no longer needed.
- * @see #erodingPool(KeyedObjectPool)
- * @see #erodingPool(KeyedObjectPool, float)
- */
- public static <K, V> KeyedObjectPool<K, V> erodingPool(
- final KeyedObjectPool<K, V> keyedPool, final float factor,
- final boolean perKey) {
- if (keyedPool == null) {
- throw new IllegalArgumentException(MSG_NULL_KEYED_POOL);
- }
- if (factor <= 0f) {
- throw new IllegalArgumentException(MSG_FACTOR_NEGATIVE);
- }
- if (perKey) {
- return new ErodingPerKeyKeyedObjectPool<>(keyedPool, factor);
- }
- return new ErodingKeyedObjectPool<>(keyedPool, factor);
- }
-
- /**
* Gets the <code>Timer</code> for checking keyedPool's idle count.
*
* @return the {@link Timer} for checking keyedPool's idle count.
@@ -718,73 +481,51 @@ public final class PoolUtils {
}
/**
- * A synchronized (thread-safe) ObjectPool backed by the specified
- * ObjectPool.
+ * A fully synchronized PooledObjectFactory that wraps a
+ * PooledObjectFactory and synchronizes access to the wrapped factory
+ * methods.
* <p>
* <b>Note:</b> This should not be used on pool implementations that already
* provide proper synchronization such as the pools provided in the Commons
- * Pool library. Wrapping a pool that {@link #wait() waits} for poolable
- * objects to be returned before allowing another one to be borrowed with
- * another layer of synchronization will cause liveliness issues or a
- * deadlock.
+ * Pool library.
* </p>
*
- * @param <T> type of objects in the pool
+ * @param <T> pooled object factory type
*/
- private static final class SynchronizedObjectPool<T> implements ObjectPool<T> {
+ private static final class SynchronizedPooledObjectFactory<T> implements
+ PooledObjectFactory<T> {
- /**
- * Object whose monitor is used to synchronize methods on the wrapped
- * pool.
- */
- private final ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();
+ /** Synchronization lock */
+ private final WriteLock writeLock = new ReentrantReadWriteLock().writeLock();
- /** the underlying object pool */
- private final ObjectPool<T> pool;
+ /** Wrapped factory */
+ private final PooledObjectFactory<T> factory;
/**
- * Creates a new SynchronizedObjectPool wrapping the given pool.
+ * Creates a SynchronizedPoolableObjectFactory wrapping the given
+ * factory.
*
- * @param pool
- * the ObjectPool to be "wrapped" in a synchronized
- * ObjectPool.
+ * @param factory
+ * underlying factory to wrap
* @throws IllegalArgumentException
- * if the pool is null
+ * if the factory is null
*/
- SynchronizedObjectPool(final ObjectPool<T> pool)
+ SynchronizedPooledObjectFactory(final PooledObjectFactory<T> factory)
throws IllegalArgumentException {
- if (pool == null) {
- throw new IllegalArgumentException(MSG_NULL_POOL);
- }
- this.pool = pool;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public T borrowObject() throws Exception, NoSuchElementException,
- IllegalStateException {
- final WriteLock writeLock = readWriteLock.writeLock();
- writeLock.lock();
- try {
- return pool.borrowObject();
- } finally {
- writeLock.unlock();
+ if (factory == null) {
+ throw new IllegalArgumentException("factory must not be null.");
}
+ this.factory = factory;
}
/**
* {@inheritDoc}
*/
@Override
- public void returnObject(final T obj) {
- final WriteLock writeLock = readWriteLock.writeLock();
+ public PooledObject<T> makeObject() throws Exception {
writeLock.lock();
try {
- pool.returnObject(obj);
- } catch (final Exception e) {
- // swallowed as of Pool 2
+ return factory.makeObject();
} finally {
writeLock.unlock();
}
@@ -794,13 +535,10 @@ public final class PoolUtils {
* {@inheritDoc}
*/
@Override
- public void invalidateObject(final T obj) {
- final WriteLock writeLock = readWriteLock.writeLock();
+ public void destroyObject(final PooledObject<T> p) throws Exception {
writeLock.lock();
try {
- pool.invalidateObject(obj);
- } catch (final Exception e) {
- // swallowed as of Pool 2
+ factory.destroyObject(p);
} finally {
writeLock.unlock();
}
@@ -810,12 +548,10 @@ public final class PoolUtils {
* {@inheritDoc}
*/
@Override
- public void addObject() throws Exception, IllegalStateException,
- UnsupportedOperationException {
- final WriteLock writeLock = readWriteLock.writeLock();
+ public boolean validateObject(final PooledObject<T> p) {
writeLock.lock();
try {
- pool.addObject();
+ return factory.validateObject(p);
} finally {
writeLock.unlock();
}
@@ -825,39 +561,10 @@ public final class PoolUtils {
* {@inheritDoc}
*/
@Override
- public int getNumIdle() {
- final ReadLock readLock = readWriteLock.readLock();
- readLock.lock();
- try {
- return pool.getNumIdle();
- } finally {
- readLock.unlock();
- }
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public int getNumActive() {
- final ReadLock readLock = readWriteLock.readLock();
- readLock.lock();
- try {
- return pool.getNumActive();
- } finally {
- readLock.unlock();
- }
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void clear() throws Exception, UnsupportedOperationException {
- final WriteLock writeLock = readWriteLock.writeLock();
+ public void activateObject(final PooledObject<T> p) throws Exception {
writeLock.lock();
try {
- pool.clear();
+ factory.activateObject(p);
} finally {
writeLock.unlock();
}
@@ -867,13 +574,10 @@ public final class PoolUtils {
* {@inheritDoc}
*/
@Override
- public void close() {
- final WriteLock writeLock = readWriteLock.writeLock();
+ public void passivateObject(final PooledObject<T> p) throws Exception {
writeLock.lock();
try {
- pool.close();
- } catch (final Exception e) {
- // swallowed as of Pool 2
+ factory.passivateObject(p);
} finally {
writeLock.unlock();
}
@@ -885,83 +589,62 @@ public final class PoolUtils {
@Override
public String toString() {
final StringBuilder sb = new StringBuilder();
- sb.append("SynchronizedObjectPool");
- sb.append("{pool=").append(pool);
+ sb.append("SynchronizedPoolableObjectFactory");
+ sb.append("{factory=").append(factory);
sb.append('}');
return sb.toString();
}
}
/**
- * A synchronized (thread-safe) KeyedObjectPool backed by the specified
- * KeyedObjectPool.
+ * A fully synchronized KeyedPooledObjectFactory that wraps a
+ * KeyedPooledObjectFactory and synchronizes access to the wrapped factory
+ * methods.
* <p>
* <b>Note:</b> This should not be used on pool implementations that already
* provide proper synchronization such as the pools provided in the Commons
- * Pool library. Wrapping a pool that {@link #wait() waits} for poolable
- * objects to be returned before allowing another one to be borrowed with
- * another layer of synchronization will cause liveliness issues or a
- * deadlock.
+ * Pool library.
* </p>
*
- * @param <K> object pool key type
- * @param <V> object pool value type
+ * @param <K> pooled object factory key type
+ * @param <V> pooled object factory key value
*/
- private static final class SynchronizedKeyedObjectPool<K, V> implements
- KeyedObjectPool<K, V> {
+ private static final class SynchronizedKeyedPooledObjectFactory<K, V>
+ implements KeyedPooledObjectFactory<K, V> {
- /**
- * Object whose monitor is used to synchronize methods on the wrapped
- * pool.
- */
- private final ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();
+ /** Synchronization lock */
+ private final WriteLock writeLock = new ReentrantReadWriteLock().writeLock();
- /** Underlying object pool */
- private final KeyedObjectPool<K, V> keyedPool;
+ /** Wrapped factory */
+ private final KeyedPooledObjectFactory<K, V> keyedFactory;
/**
- * Creates a new SynchronizedKeyedObjectPool wrapping the given pool
+ * Creates a SynchronizedKeyedPoolableObjectFactory wrapping the given
+ * factory.
*
- * @param keyedPool
- * KeyedObjectPool to wrap
+ * @param keyedFactory
+ * underlying factory to wrap
* @throws IllegalArgumentException
- * if keyedPool is null
+ * if the factory is null
*/
- SynchronizedKeyedObjectPool(final KeyedObjectPool<K, V> keyedPool)
+ SynchronizedKeyedPooledObjectFactory(
+ final KeyedPooledObjectFactory<K, V> keyedFactory)
throws IllegalArgumentException {
- if (keyedPool == null) {
+ if (keyedFactory == null) {
throw new IllegalArgumentException(
- MSG_NULL_KEYED_POOL);
- }
- this.keyedPool = keyedPool;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public V borrowObject(final K key) throws Exception,
- NoSuchElementException, IllegalStateException {
- final WriteLock writeLock = readWriteLock.writeLock();
- writeLock.lock();
- try {
- return keyedPool.borrowObject(key);
- } finally {
- writeLock.unlock();
+ "keyedFactory must not be null.");
}
+ this.keyedFactory = keyedFactory;
}
/**
* {@inheritDoc}
*/
@Override
- public void returnObject(final K key, final V obj) {
- final WriteLock writeLock = readWriteLock.writeLock();
+ public PooledObject<V> makeObject(final K key) throws Exception {
writeLock.lock();
try {
- keyedPool.returnObject(key, obj);
- } catch (final Exception e) {
- // swallowed
+ return keyedFactory.makeObject(key);
} finally {
writeLock.unlock();
}
@@ -971,13 +654,10 @@ public final class PoolUtils {
* {@inheritDoc}
*/
@Override
- public void invalidateObject(final K key, final V obj) {
- final WriteLock writeLock = readWriteLock.writeLock();
+ public void destroyObject(final K key, final PooledObject<V> p) throws Exception {
writeLock.lock();
try {
- keyedPool.invalidateObject(key, obj);
- } catch (final Exception e) {
- // swallowed as of Pool 2
+ keyedFactory.destroyObject(key, p);
} finally {
writeLock.unlock();
}
@@ -987,12 +667,10 @@ public final class PoolUtils {
* {@inheritDoc}
*/
@Override
- public void addObject(final K key) throws Exception,
- IllegalStateException, UnsupportedOperationException {
- final WriteLock writeLock = readWriteLock.writeLock();
+ public boolean validateObject(final K key, final PooledObject<V> p) {
writeLock.lock();
try {
- keyedPool.addObject(key);
+ return keyedFactory.validateObject(key, p);
} finally {
writeLock.unlock();
}
@@ -1002,67 +680,10 @@ public final class PoolUtils {
* {@inheritDoc}
*/
@Override
- public int getNumIdle(final K key) {
- final ReadLock readLock = readWriteLock.readLock();
- readLock.lock();
- try {
- return keyedPool.getNumIdle(key);
- } finally {
- readLock.unlock();
- }
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public int getNumActive(final K key) {
- final ReadLock readLock = readWriteLock.readLock();
- readLock.lock();
- try {
- return keyedPool.getNumActive(key);
- } finally {
- readLock.unlock();
- }
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public int getNumIdle() {
- final ReadLock readLock = readWriteLock.readLock();
- readLock.lock();
- try {
- return keyedPool.getNumIdle();
- } finally {
- readLock.unlock();
- }
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public int getNumActive() {
- final ReadLock readLock = readWriteLock.readLock();
- readLock.lock();
- try {
- return keyedPool.getNumActive();
- } finally {
- readLock.unlock();
- }
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void clear() throws Exception, UnsupportedOperationException {
- final WriteLock writeLock = readWriteLock.writeLock();
+ public void activateObject(final K key, final PooledObject<V> p) throws Exception {
writeLock.lock();
try {
- keyedPool.clear();
+ keyedFactory.activateObject(key, p);
} finally {
writeLock.unlock();
}
@@ -1072,263 +693,10 @@ public final class PoolUtils {
* {@inheritDoc}
*/
@Override
- public void clear(final K key) throws Exception,
- UnsupportedOperationException {
- final WriteLock writeLock = readWriteLock.writeLock();
+ public void passivateObject(final K key, final PooledObject<V> p) throws Exception {
writeLock.lock();
try {
- keyedPool.clear(key);
- } finally {
- writeLock.unlock();
- }
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void close() {
- final WriteLock writeLock = readWriteLock.writeLock();
- writeLock.lock();
- try {
- keyedPool.close();
- } catch (final Exception e) {
- // swallowed as of Pool 2
- } finally {
- writeLock.unlock();
- }
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public String toString() {
- final StringBuilder sb = new StringBuilder();
- sb.append("SynchronizedKeyedObjectPool");
- sb.append("{keyedPool=").append(keyedPool);
- sb.append('}');
- return sb.toString();
- }
- }
-
- /**
- * A fully synchronized PooledObjectFactory that wraps a
- * PooledObjectFactory and synchronizes access to the wrapped factory
- * methods.
- * <p>
- * <b>Note:</b> This should not be used on pool implementations that already
- * provide proper synchronization such as the pools provided in the Commons
- * Pool library.
- * </p>
- *
- * @param <T> pooled object factory type
- */
- private static final class SynchronizedPooledObjectFactory<T> implements
- PooledObjectFactory<T> {
-
- /** Synchronization lock */
- private final WriteLock writeLock = new ReentrantReadWriteLock().writeLock();
-
- /** Wrapped factory */
- private final PooledObjectFactory<T> factory;
-
- /**
- * Creates a SynchronizedPoolableObjectFactory wrapping the given
- * factory.
- *
- * @param factory
- * underlying factory to wrap
- * @throws IllegalArgumentException
- * if the factory is null
- */
- SynchronizedPooledObjectFactory(final PooledObjectFactory<T> factory)
- throws IllegalArgumentException {
- if (factory == null) {
- throw new IllegalArgumentException("factory must not be null.");
- }
- this.factory = factory;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public PooledObject<T> makeObject() throws Exception {
- writeLock.lock();
- try {
- return factory.makeObject();
- } finally {
- writeLock.unlock();
- }
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void destroyObject(final PooledObject<T> p) throws Exception {
- writeLock.lock();
- try {
- factory.destroyObject(p);
- } finally {
- writeLock.unlock();
- }
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public boolean validateObject(final PooledObject<T> p) {
- writeLock.lock();
- try {
- return factory.validateObject(p);
- } finally {
- writeLock.unlock();
- }
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void activateObject(final PooledObject<T> p) throws Exception {
- writeLock.lock();
- try {
- factory.activateObject(p);
- } finally {
- writeLock.unlock();
- }
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void passivateObject(final PooledObject<T> p) throws Exception {
- writeLock.lock();
- try {
- factory.passivateObject(p);
- } finally {
- writeLock.unlock();
- }
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public String toString() {
- final StringBuilder sb = new StringBuilder();
- sb.append("SynchronizedPoolableObjectFactory");
- sb.append("{factory=").append(factory);
- sb.append('}');
- return sb.toString();
- }
- }
-
- /**
- * A fully synchronized KeyedPooledObjectFactory that wraps a
- * KeyedPooledObjectFactory and synchronizes access to the wrapped factory
- * methods.
- * <p>
- * <b>Note:</b> This should not be used on pool implementations that already
- * provide proper synchronization such as the pools provided in the Commons
- * Pool library.
- * </p>
- *
- * @param <K> pooled object factory key type
- * @param <V> pooled object factory key value
- */
- private static final class SynchronizedKeyedPooledObjectFactory<K, V>
- implements KeyedPooledObjectFactory<K, V> {
-
- /** Synchronization lock */
- private final WriteLock writeLock = new ReentrantReadWriteLock().writeLock();
-
- /** Wrapped factory */
- private final KeyedPooledObjectFactory<K, V> keyedFactory;
-
- /**
- * Creates a SynchronizedKeyedPoolableObjectFactory wrapping the given
- * factory.
- *
- * @param keyedFactory
- * underlying factory to wrap
- * @throws IllegalArgumentException
- * if the factory is null
- */
- SynchronizedKeyedPooledObjectFactory(
- final KeyedPooledObjectFactory<K, V> keyedFactory)
- throws IllegalArgumentException {
- if (keyedFactory == null) {
- throw new IllegalArgumentException(
- "keyedFactory must not be null.");
- }
- this.keyedFactory = keyedFactory;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public PooledObject<V> makeObject(final K key) throws Exception {
- writeLock.lock();
- try {
- return keyedFactory.makeObject(key);
- } finally {
- writeLock.unlock();
- }
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void destroyObject(final K key, final PooledObject<V> p) throws Exception {
- writeLock.lock();
- try {
- keyedFactory.destroyObject(key, p);
- } finally {
- writeLock.unlock();
- }
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public boolean validateObject(final K key, final PooledObject<V> p) {
- writeLock.lock();
- try {
- return keyedFactory.validateObject(key, p);
- } finally {
- writeLock.unlock();
- }
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void activateObject(final K key, final PooledObject<V> p) throws Exception {
- writeLock.lock();
- try {
- keyedFactory.activateObject(key, p);
- } finally {
- writeLock.unlock();
- }
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void passivateObject(final K key, final PooledObject<V> p) throws Exception {
- writeLock.lock();
- try {
- keyedFactory.passivateObject(key, p);
+ keyedFactory.passivateObject(key, p);
} finally {
writeLock.unlock();
}
@@ -1346,492 +714,4 @@ public final class PoolUtils {
return sb.toString();
}
}
-
- /**
- * Encapsulate the logic for when the next poolable object should be
- * discarded. Each time update is called, the next time to shrink is
- * recomputed, based on the float factor, number of idle instances in the
- * pool and high water mark. Float factor is assumed to be between 0 and 1.
- * Values closer to 1 cause less frequent erosion events. Erosion event
- * timing also depends on numIdle. When this value is relatively high (close
- * to previously established high water mark), erosion occurs more
- * frequently.
- */
- private static final class ErodingFactor {
- /** Determines frequency of "erosion" events */
- private final float factor;
-
- /** Time of next shrink event */
- private transient volatile long nextShrink;
-
- /** High water mark - largest numIdle encountered */
- private transient volatile int idleHighWaterMark;
-
- /**
- * Creates a new ErodingFactor with the given erosion factor.
- *
- * @param factor
- * erosion factor
- */
- public ErodingFactor(final float factor) {
- this.factor = factor;
- nextShrink = System.currentTimeMillis() + (long) (900000 * factor); // now
- // +
- // 15
- // min
- // *
- // factor
- idleHighWaterMark = 1;
- }
-
- /**
- * Updates internal state using the supplied time and numIdle.
- *
- * @param now
- * current time
- * @param numIdle
- * number of idle elements in the pool
- */
- public void update(final long now, final int numIdle) {
- final int idle = Math.max(0, numIdle);
- idleHighWaterMark = Math.max(idle, idleHighWaterMark);
- final float maxInterval = 15f;
- final float minutes = maxInterval +
- ((1f - maxInterval) / idleHighWaterMark) * idle;
- nextShrink = now + (long) (minutes * 60000f * factor);
- }
-
- /**
- * Returns the time of the next erosion event.
- *
- * @return next shrink time
- */
- public long getNextShrink() {
- return nextShrink;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public String toString() {
- return "ErodingFactor{" + "factor=" + factor +
- ", idleHighWaterMark=" + idleHighWaterMark + '}';
- }
- }
-
- /**
- * Decorates an object pool, adding "eroding" behavior. Based on the
- * configured {@link #factor erosion factor}, objects returning to the pool
- * may be invalidated instead of being added to idle capacity.
- *
- * @param <T> type of objects in the pool
- */
- private static class ErodingObjectPool<T> implements ObjectPool<T> {
-
- /** Underlying object pool */
- private final ObjectPool<T> pool;
-
- /** Erosion factor */
- private final ErodingFactor factor;
-
- /**
- * Creates an ErodingObjectPool wrapping the given pool using the
- * specified erosion factor.
- *
- * @param pool
- * underlying pool
- * @param factor
- * erosion factor - determines the frequency of erosion
- * events
- * @see #factor
- */
- public ErodingObjectPool(final ObjectPool<T> pool, final float factor) {
- this.pool = pool;
- this.factor = new ErodingFactor(factor);
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public T borrowObject() throws Exception, NoSuchElementException,
- IllegalStateException {
- return pool.borrowObject();
- }
-
- /**
- * Returns obj to the pool, unless erosion is triggered, in which case
- * obj is invalidated. Erosion is triggered when there are idle
- * instances in the pool and more than the {@link #factor erosion
- * factor}-determined time has elapsed since the last returnObject
- * activation.
- *
- * @param obj
- * object to return or invalidate
- * @see #factor
- */
- @Override
- public void returnObject(final T obj) {
- boolean discard = false;
- final long now = System.currentTimeMillis();
- synchronized (pool) {
- if (factor.getNextShrink() < now) { // XXX: Pool 3: move test
- // out of sync block
- final int numIdle = pool.getNumIdle();
- if (numIdle > 0) {
- discard = true;
- }
-
- factor.update(now, numIdle);
- }
- }
- try {
- if (discard) {
- pool.invalidateObject(obj);
- } else {
- pool.returnObject(obj);
- }
- } catch (final Exception e) {
- // swallowed
- }
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void invalidateObject(final T obj) {
- try {
- pool.invalidateObject(obj);
- } catch (final Exception e) {
- // swallowed
- }
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void addObject() throws Exception, IllegalStateException,
- UnsupportedOperationException {
- pool.addObject();
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public int getNumIdle() {
- return pool.getNumIdle();
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public int getNumActive() {
- return pool.getNumActive();
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void clear() throws Exception, UnsupportedOperationException {
- pool.clear();
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void close() {
- try {
- pool.close();
- } catch (final Exception e) {
- // swallowed
- }
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public String toString() {
- return "ErodingObjectPool{" + "factor=" + factor + ", pool=" +
- pool + '}';
- }
- }
-
- /**
- * Decorates a keyed object pool, adding "eroding" behavior. Based on the
- * configured erosion factor, objects returning to the pool
- * may be invalidated instead of being added to idle capacity.
- *
- * @param <K> object pool key type
- * @param <V> object pool value type
- */
- private static class ErodingKeyedObjectPool<K, V> implements
- KeyedObjectPool<K, V> {
-
- /** Underlying pool */
- private final KeyedObjectPool<K, V> keyedPool;
-
- /** Erosion factor */
- private final ErodingFactor erodingFactor;
-
- /**
- * Creates an ErodingObjectPool wrapping the given pool using the
- * specified erosion factor.
- *
- * @param keyedPool
- * underlying pool
- * @param factor
- * erosion factor - determines the frequency of erosion
- * events
- * @see #erodingFactor
- */
- public ErodingKeyedObjectPool(final KeyedObjectPool<K, V> keyedPool,
- final float factor) {
- this(keyedPool, new ErodingFactor(factor));
- }
-
- /**
- * Creates an ErodingObjectPool wrapping the given pool using the
- * specified erosion factor.
- *
- * @param keyedPool
- * underlying pool - must not be null
- * @param erodingFactor
- * erosion factor - determines the frequency of erosion
- * events
- * @see #erodingFactor
- */
- protected ErodingKeyedObjectPool(final KeyedObjectPool<K, V> keyedPool,
- final ErodingFactor erodingFactor) {
- if (keyedPool == null) {
- throw new IllegalArgumentException(
- MSG_NULL_KEYED_POOL);
- }
- this.keyedPool = keyedPool;
- this.erodingFactor = erodingFactor;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public V borrowObject(final K key) throws Exception,
- NoSuchElementException, IllegalStateException {
- return keyedPool.borrowObject(key);
- }
-
- /**
- * Returns obj to the pool, unless erosion is triggered, in which case
- * obj is invalidated. Erosion is triggered when there are idle
- * instances in the pool associated with the given key and more than the
- * configured {@link #erodingFactor erosion factor} time has elapsed
- * since the last returnObject activation.
- *
- * @param obj
- * object to return or invalidate
- * @param key
- * key
- * @see #erodingFactor
- */
- @Override
- public void returnObject(final K key, final V obj) throws Exception {
- boolean discard = false;
- final long now = System.currentTimeMillis();
- final ErodingFactor factor = getErodingFactor(key);
- synchronized (keyedPool) {
- if (factor.getNextShrink() < now) {
- final int numIdle = getNumIdle(key);
- if (numIdle > 0) {
- discard = true;
- }
-
- factor.update(now, numIdle);
- }
- }
- try {
- if (discard) {
- keyedPool.invalidateObject(key, obj);
- } else {
- keyedPool.returnObject(key, obj);
- }
- } catch (final Exception e) {
- // swallowed
- }
- }
-
- /**
- * Returns the eroding factor for the given key
- *
- * @param key
- * key
- * @return eroding factor for the given keyed pool
- */
- protected ErodingFactor getErodingFactor(final K key) {
- return erodingFactor;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void invalidateObject(final K key, final V obj) {
- try {
- keyedPool.invalidateObject(key, obj);
- } catch (final Exception e) {
- // swallowed
- }
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void addObject(final K key) throws Exception,
- IllegalStateException, UnsupportedOperationException {
- keyedPool.addObject(key);
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public int getNumIdle() {
- return keyedPool.getNumIdle();
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public int getNumIdle(final K key) {
- return keyedPool.getNumIdle(key);
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public int getNumActive() {
- return keyedPool.getNumActive();
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public int getNumActive(final K key) {
- return keyedPool.getNumActive(key);
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void clear() throws Exception, UnsupportedOperationException {
- keyedPool.clear();
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void clear(final K key) throws Exception,
- UnsupportedOperationException {
- keyedPool.clear(key);
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void close() {
- try {
- keyedPool.close();
- } catch (final Exception e) {
- // swallowed
- }
- }
-
- /**
- * Returns the underlying pool
- *
- * @return the keyed pool that this ErodingKeyedObjectPool wraps
- */
- protected KeyedObjectPool<K, V> getKeyedPool() {
- return keyedPool;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public String toString() {
- return "ErodingKeyedObjectPool{" + "factor=" +
- erodingFactor + ", keyedPool=" + keyedPool + '}';
- }
- }
-
- /**
- * Extends ErodingKeyedObjectPool to allow erosion to take place on a
- * per-key basis. Timing of erosion events is tracked separately for
- * separate keyed pools.
- *
- * @param <K> object pool key type
- * @param <V> object pool value type
- */
- private static final class ErodingPerKeyKeyedObjectPool<K, V> extends
- ErodingKeyedObjectPool<K, V> {
-
- /** Erosion factor - same for all pools */
- private final float factor;
-
- /** Map of ErodingFactor instances keyed on pool keys */
- private final Map<K, ErodingFactor> factors = Collections.synchronizedMap(new HashMap<K, ErodingFactor>());
-
- /**
- * Creates a new ErordingPerKeyKeyedObjectPool decorating the given keyed
- * pool with the specified erosion factor.
- *
- * @param keyedPool
- * underlying keyed pool
- * @param factor
- * erosion factor
- */
- public ErodingPerKeyKeyedObjectPool(
- final KeyedObjectPool<K, V> keyedPool, final float factor) {
- super(keyedPool, null);
- this.factor = factor;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- protected ErodingFactor getErodingFactor(final K key) {
- ErodingFactor eFactor = factors.get(key);
- // this may result in two ErodingFactors being created for a key
- // since they are small and cheap this is okay.
- if (eFactor == null) {
- eFactor = new ErodingFactor(this.factor);
- factors.put(key, eFactor);
- }
- return eFactor;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public String toString() {
- return "ErodingPerKeyKeyedObjectPool{" + "factor=" + factor +
- ", keyedPool=" + getKeyedPool() + '}';
- }
- }
}
diff --git a/java/org/apache/tomcat/dbcp/pool2/PooledObject.java b/java/org/apache/tomcat/dbcp/pool2/PooledObject.java
index 361b3d8..1bfb803 100644
--- a/java/org/apache/tomcat/dbcp/pool2/PooledObject.java
+++ b/java/org/apache/tomcat/dbcp/pool2/PooledObject.java
@@ -24,6 +24,7 @@ import java.util.Deque;
* state, for the pooled objects.
* <p>
* Implementations of this class are required to be thread-safe.
+ * </p>
*
* @param <T> the type of object in the pool
*
@@ -185,7 +186,7 @@ public interface PooledObject<T> extends Comparable<PooledObject<T>> {
* @param requireFullStackTrace the new configuration setting for abandoned object logging
* @since 2.7.0
*/
- void setRequireFullStackTrace(boolean requireFullStackTrace);
+ void setRequireFullStackTrace(final boolean requireFullStackTrace);
/**
* Record the current stack trace as the last time the object was used.
diff --git a/java/org/apache/tomcat/dbcp/pool2/impl/DefaultEvictionPolicy.java b/java/org/apache/tomcat/dbcp/pool2/impl/DefaultEvictionPolicy.java
index fdacc6e..fc618a5 100644
--- a/java/org/apache/tomcat/dbcp/pool2/impl/DefaultEvictionPolicy.java
+++ b/java/org/apache/tomcat/dbcp/pool2/impl/DefaultEvictionPolicy.java
@@ -31,7 +31,9 @@ import org.apache.tomcat.dbcp.pool2.PooledObject;
* {@link GenericObjectPool#getSoftMinEvictableIdleTimeMillis()} /
* {@link GenericKeyedObjectPool#getSoftMinEvictableIdleTimeMillis()}
* </ul>
+ * <p>
* This class is immutable and thread-safe.
+ * </p>
*
* @param <T> the type of objects in the pool
*
diff --git a/java/org/apache/tomcat/dbcp/pool2/impl/EvictionConfig.java b/java/org/apache/tomcat/dbcp/pool2/impl/EvictionConfig.java
index 49766f0..b124676 100644
--- a/java/org/apache/tomcat/dbcp/pool2/impl/EvictionConfig.java
+++ b/java/org/apache/tomcat/dbcp/pool2/impl/EvictionConfig.java
@@ -22,6 +22,7 @@ package org.apache.tomcat.dbcp.pool2.impl;
* its own specific configuration attributes.
* <p>
* This class is immutable and thread-safe.
+ * </p>
*
* @since 2.0
*/
diff --git a/java/org/apache/tomcat/dbcp/pool2/impl/GenericKeyedObjectPool.java b/java/org/apache/tomcat/dbcp/pool2/impl/GenericKeyedObjectPool.java
index 01dc542..93c7a84 100644
--- a/java/org/apache/tomcat/dbcp/pool2/impl/GenericKeyedObjectPool.java
+++ b/java/org/apache/tomcat/dbcp/pool2/impl/GenericKeyedObjectPool.java
@@ -17,6 +17,7 @@
package org.apache.tomcat.dbcp.pool2.impl;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.Deque;
import java.util.HashMap;
import java.util.Iterator;
@@ -50,10 +51,12 @@ import org.apache.tomcat.dbcp.pool2.PooledObjectState;
* {@link #borrowObject borrowObject} methods. Each time a new key value is
* provided to one of these methods, a sub-new pool is created under the given
* key to be managed by the containing <code>GenericKeyedObjectPool.</code>
+ * </p>
* <p>
* Note that the current implementation uses a ConcurrentHashMap which uses
* equals() to compare keys.
* This means that distinct instance keys must be distinguishable using equals.
+ * </p>
* <p>
* Optionally, one may configure the pool to examine and possibly evict objects
* as they sit idle in the pool and to ensure that a minimum number of idle
@@ -62,12 +65,15 @@ import org.apache.tomcat.dbcp.pool2.PooledObjectState;
* configuring this optional feature. Eviction runs contend with client threads
* for access to objects in the pool, so if they run too frequently performance
* issues may result.
+ * </p>
* <p>
* Implementation note: To prevent possible deadlocks, care has been taken to
* ensure that no call to a factory method will occur within a synchronization
* block. See POOL-125 and DBCP-44 for more information.
+ * </p>
* <p>
* This class is intended to be thread-safe.
+ * </p>
*
* @see GenericObjectPool
*
@@ -447,6 +453,11 @@ public class GenericKeyedObjectPool<K, T> extends BaseGenericObjectPool<T>
final ObjectDeque<T> objectDeque = poolMap.get(key);
+ if (objectDeque == null) {
+ throw new IllegalStateException(
+ "No keyed pool found under the given key.");
+ }
+
final PooledObject<T> p = objectDeque.getAllObjects().get(new IdentityWrapper<>(obj));
if (p == null) {
@@ -1077,8 +1088,16 @@ public class GenericKeyedObjectPool<K, T> extends BaseGenericObjectPool<T>
final ObjectDeque<T> objectDeque = register(key);
try {
- final boolean isIdle = objectDeque.getIdleObjects().remove(toDestroy);
-
+ boolean isIdle;
+ synchronized(toDestroy) {
+ // Check idle state directly
+ isIdle = toDestroy.getState().equals(PooledObjectState.IDLE);
+ // If idle, not under eviction test, or always is true, remove instance,
+ // updating isIdle if instance is found in idle objects
+ if (isIdle || always) {
+ isIdle = objectDeque.getIdleObjects().remove(toDestroy);
+ }
+ }
if (isIdle || always) {
objectDeque.getAllObjects().remove(new IdentityWrapper<>(toDestroy.getObject()));
toDestroy.invalidate();
@@ -1151,10 +1170,9 @@ public class GenericKeyedObjectPool<K, T> extends BaseGenericObjectPool<T>
*/
private void deregister(final K k) {
Lock lock = keyLock.readLock();
- ObjectDeque<T> objectDeque;
try {
lock.lock();
- objectDeque = poolMap.get(k);
+ final ObjectDeque<T> objectDeque = poolMap.get(k);
final long numInterested = objectDeque.getNumInterested().decrementAndGet();
if (numInterested == 0 && objectDeque.getCreateCount().get() == 0) {
// Potential to remove key
@@ -1244,6 +1262,58 @@ public class GenericKeyedObjectPool<K, T> extends BaseGenericObjectPool<T>
}
/**
+ * Calls {@link KeyedObjectPool#addObject(Object)} with each
+ * key in <code>keys</code> for <code>count</code> number of times. This has
+ * the same effect as calling {@link #addObjects(Object, int)}
+ * for each key in the <code>keys</code> collection.
+ *
+ * @param keys
+ * {@link Collection} of keys to add objects for.
+ * @param count
+ * the number of idle objects to add for each <code>key</code>.
+ * @throws Exception
+ * when {@link KeyedObjectPool#addObject(Object)} fails.
+ * @throws IllegalArgumentException
+ * when <code>keyedPool</code>, <code>keys</code>, or any value
+ * in <code>keys</code> is <code>null</code>.
+ * @see #addObjects(Object, int)
+ */
+ @Override
+ public void addObjects(final Collection<K> keys, final int count) throws Exception, IllegalArgumentException {
+ if (keys == null) {
+ throw new IllegalArgumentException(PoolUtils.MSG_NULL_KEYS);
+ }
+ final Iterator<K> iter = keys.iterator();
+ while (iter.hasNext()) {
+ addObjects(iter.next(), count);
+ }
+ }
+
+ /**
+ * Calls {@link KeyedObjectPool#addObject(Object)}
+ * <code>key</code> <code>count</code> number of times.
+ *
+ * @param key
+ * the key to add objects for.
+ * @param count
+ * the number of idle objects to add for <code>key</code>.
+ * @throws Exception
+ * when {@link KeyedObjectPool#addObject(Object)} fails.
+ * @throws IllegalArgumentException
+ * when <code>key</code> is <code>null</code>.
+ * @since 2.8.0
+ */
+ @Override
+ public void addObjects(final K key, final int count) throws Exception, IllegalArgumentException {
+ if (key == null) {
+ throw new IllegalArgumentException(PoolUtils.MSG_NULL_KEY);
+ }
+ for (int i = 0; i < count; i++) {
+ addObject(key);
+ }
+ }
+
+ /**
* Add an object to the set of idle objects for a given key.
*
* @param key The key to associate with the idle object
diff --git a/java/org/apache/tomcat/dbcp/pool2/impl/GenericObjectPool.java b/java/org/apache/tomcat/dbcp/pool2/impl/GenericObjectPool.java
index c72b701..4a9909d 100644
--- a/java/org/apache/tomcat/dbcp/pool2/impl/GenericObjectPool.java
+++ b/java/org/apache/tomcat/dbcp/pool2/impl/GenericObjectPool.java
@@ -38,7 +38,8 @@ import org.apache.tomcat.dbcp.pool2.UsageTracking;
* <p>
* When coupled with the appropriate {@link PooledObjectFactory},
* <code>GenericObjectPool</code> provides robust pooling functionality for
- * arbitrary objects.</p>
+ * arbitrary objects.
+ * </p>
* <p>
* Optionally, one may configure the pool to examine and possibly evict objects
* as they sit idle in the pool and to ensure that a minimum number of idle
@@ -46,7 +47,8 @@ import org.apache.tomcat.dbcp.pool2.UsageTracking;
* which runs asynchronously. Caution should be used when configuring this
* optional feature. Eviction runs contend with client threads for access to
* objects in the pool, so if they run too frequently performance issues may
- * result.</p>
+ * result.
+ * </p>
* <p>
* The pool can also be configured to detect and remove "abandoned" objects,
* i.e. objects that have been checked out of the pool but neither used nor
@@ -59,13 +61,16 @@ import org.apache.tomcat.dbcp.pool2.UsageTracking;
* their last use will be queried
* using the <code>getLastUsed</code> method on that interface; otherwise
* abandonment is determined by how long an object has been checked out from
- * the pool.</p>
+ * the pool.
+ * </p>
* <p>
* Implementation note: To prevent possible deadlocks, care has been taken to
* ensure that no call to a factory method will occur within a synchronization
- * block. See POOL-125 and DBCP-44 for more information.</p>
+ * block. See POOL-125 and DBCP-44 for more information.
+ * </p>
* <p>
- * This class is intended to be thread-safe.</p>
+ * This class is intended to be thread-safe.
+ * </p>
*
* @see GenericKeyedObjectPool
*
@@ -576,6 +581,11 @@ public class GenericObjectPool<T> extends BaseGenericObjectPool<T>
} catch (final Exception e) {
swallowException(e);
}
+ try {
+ ensureIdle(1, false);
+ } catch (final Exception e) {
+ swallowException(e);
+ }
} else {
if (getLifo()) {
idleObjects.addFirst(p);
@@ -931,15 +941,6 @@ public class GenericObjectPool<T> extends BaseGenericObjectPool<T>
destroyedCount.incrementAndGet();
createCount.decrementAndGet();
}
-
- if (idleObjects.isEmpty() && idleObjects.hasTakeWaiters()) {
- // POOL-356.
- // In case there are already threads waiting on something in the pool
- // (e.g. idleObjects.takeFirst(); then we need to provide them a fresh instance.
- // Otherwise they will be stuck forever (or until timeout)
- final PooledObject<T> freshPooled = create();
- idleObjects.put(freshPooled);
- }
}
@Override
@@ -1005,6 +1006,23 @@ public class GenericObjectPool<T> extends BaseGenericObjectPool<T>
}
/**
+ * Calls {@link ObjectPool#addObject()} <code>count</code>
+ * number of times.
+ *
+ * @param count
+ * the number of idle objects to add.
+ * @throws Exception
+ * when {@link ObjectPool#addObject()} fails.
+ * @since 2.8.0
+ */
+ @Override
+ public void addObjects(final int count) throws Exception {
+ for (int i = 0; i < count; i++) {
+ addObject();
+ }
+ }
+
+ /**
* Adds the provided wrapped pooled object to the set of idle objects for
* 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).
diff --git a/java/org/apache/tomcat/dbcp/pool2/impl/InterruptibleReentrantLock.java b/java/org/apache/tomcat/dbcp/pool2/impl/InterruptibleReentrantLock.java
index 5a51b92..b539aed 100644
--- a/java/org/apache/tomcat/dbcp/pool2/impl/InterruptibleReentrantLock.java
+++ b/java/org/apache/tomcat/dbcp/pool2/impl/InterruptibleReentrantLock.java
@@ -26,6 +26,7 @@ import java.util.concurrent.locks.ReentrantLock;
* class is intended for internal use only.
* <p>
* This class is intended to be thread-safe.
+ * </p>
*
* @since 2.0
*/
diff --git a/java/org/apache/tomcat/dbcp/pool2/impl/LinkedBlockingDeque.java b/java/org/apache/tomcat/dbcp/pool2/impl/LinkedBlockingDeque.java
index be92f91..75e925e 100644
--- a/java/org/apache/tomcat/dbcp/pool2/impl/LinkedBlockingDeque.java
+++ b/java/org/apache/tomcat/dbcp/pool2/impl/LinkedBlockingDeque.java
@@ -34,6 +34,7 @@ import java.util.concurrent.locks.Condition;
* is equal to {@link Integer#MAX_VALUE}. Linked nodes are
* dynamically created upon each insertion unless this would bring the
* deque above capacity.
+ * </p>
*
* <p>Most operations run in constant time (ignoring time spent
* blocking). Exceptions include {@link #remove(Object) remove},
@@ -41,14 +42,17 @@ import java.util.concurrent.locks.Condition;
* #removeLastOccurrence removeLastOccurrence}, {@link #contains
* contains}, {@link #iterator iterator.remove()}, and the bulk
* operations, all of which run in linear time.
+ * </p>
*
* <p>This class and its iterator implement all of the
* <em>optional</em> methods of the {@link Collection} and {@link
* Iterator} interfaces.
+ * </p>
*
* <p>This class is a member of the
* <a href="{@docRoot}/../technotes/guides/collections/index.html">
* Java Collections Framework</a>.
+ * </p>
*
* @param <E> the type of elements held in this collection
*
diff --git a/java/org/apache/tomcat/dbcp/pool2/impl/SoftReferenceObjectPool.java b/java/org/apache/tomcat/dbcp/pool2/impl/SoftReferenceObjectPool.java
index 61741be..e417b48 100644
--- a/java/org/apache/tomcat/dbcp/pool2/impl/SoftReferenceObjectPool.java
+++ b/java/org/apache/tomcat/dbcp/pool2/impl/SoftReferenceObjectPool.java
@@ -32,6 +32,7 @@ import org.apache.tomcat.dbcp.pool2.PooledObjectFactory;
* {@link org.apache.tomcat.dbcp.pool2.ObjectPool}.
* <p>
* This class is intended to be thread-safe.
+ * </p>
*
* @param <T>
* Type of element pooled in this pool.
@@ -185,6 +186,8 @@ public class SoftReferenceObjectPool<T> extends BaseObjectPool<T> {
*
* @param obj
* instance to return to the pool
+ * @throws IllegalArgumentException
+ * if obj is not currently part of this pool
*/
@Override
public synchronized void returnObject(final T obj) throws Exception {
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index 9b8c487..86adeab 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -213,6 +213,10 @@
Update the internal fork of Apache Commons FileUpload to 2317552
(2019-12-06, 2.0-SNAPSHOT). Refactoring. (markt)
</add>
+ <add>
+ Update the internal fork of Apache Commons Pool 2 to 6092f92 (2019-12-06,
+ 2.8.0-SNAPSHOT). Clean-up and minor refactoring. (markt)
+ </add>
</changelog>
</subsection>
</section>
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org