init
This commit is contained in:
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* A base implementation of <code>KeyedPooledObjectFactory</code>.
|
||||
* <p>
|
||||
* All operations defined here are essentially no-op's.
|
||||
* </p>
|
||||
* <p>
|
||||
* This class is immutable, and therefore thread-safe.
|
||||
* </p>
|
||||
*
|
||||
* @see KeyedPooledObjectFactory
|
||||
*
|
||||
* @param <K> The type of keys managed by this factory.
|
||||
* @param <V> Type of element managed by this factory.
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public abstract class BaseKeyedPooledObjectFactory<K, V> extends BaseObject
|
||||
implements KeyedPooledObjectFactory<K, V> {
|
||||
|
||||
/**
|
||||
* Create an instance that can be served by the pool.
|
||||
*
|
||||
* @param key the key used when constructing the object
|
||||
* @return an instance that can be served by the pool
|
||||
*
|
||||
* @throws Exception if there is a problem creating a new instance,
|
||||
* this will be propagated to the code requesting an object.
|
||||
*/
|
||||
public abstract V create(K key)
|
||||
throws Exception;
|
||||
|
||||
/**
|
||||
* Wrap the provided instance with an implementation of
|
||||
* {@link PooledObject}.
|
||||
*
|
||||
* @param value the instance to wrap
|
||||
*
|
||||
* @return The provided instance, wrapped by a {@link PooledObject}
|
||||
*/
|
||||
public abstract PooledObject<V> wrap(V value);
|
||||
|
||||
@Override
|
||||
public PooledObject<V> makeObject(final K key) throws Exception {
|
||||
return wrap(create(key));
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroy an instance no longer needed by the pool.
|
||||
* <p>
|
||||
* The default implementation is a no-op.
|
||||
* </p>
|
||||
*
|
||||
* @param key the key used when selecting the instance
|
||||
* @param p a {@code PooledObject} wrapping the instance to be destroyed
|
||||
*/
|
||||
@Override
|
||||
public void destroyObject(final K key, final PooledObject<V> p)
|
||||
throws Exception {
|
||||
// The default implementation is a no-op.
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures that the instance is safe to be returned by the pool.
|
||||
* <p>
|
||||
* The default implementation always returns {@code true}.
|
||||
* </p>
|
||||
*
|
||||
* @param key the key used when selecting the object
|
||||
* @param p a {@code PooledObject} wrapping the instance to be validated
|
||||
* @return always <code>true</code> in the default implementation
|
||||
*/
|
||||
@Override
|
||||
public boolean validateObject(final K key, final PooledObject<V> p) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reinitialize an instance to be returned by the pool.
|
||||
* <p>
|
||||
* The default implementation is a no-op.
|
||||
* </p>
|
||||
*
|
||||
* @param key the key used when selecting the object
|
||||
* @param p a {@code PooledObject} wrapping the instance to be activated
|
||||
*/
|
||||
@Override
|
||||
public void activateObject(final K key, final PooledObject<V> p)
|
||||
throws Exception {
|
||||
// The default implementation is a no-op.
|
||||
}
|
||||
|
||||
/**
|
||||
* Uninitialize an instance to be returned to the idle object pool.
|
||||
* <p>
|
||||
* The default implementation is a no-op.
|
||||
* </p>
|
||||
*
|
||||
* @param key the key used when selecting the object
|
||||
* @param p a {@code PooledObject} wrapping the instance to be passivated
|
||||
*/
|
||||
@Override
|
||||
public void passivateObject(final K key, final PooledObject<V> p)
|
||||
throws Exception {
|
||||
// The default implementation is a no-op.
|
||||
}
|
||||
}
|
||||
45
java/org/apache/tomcat/dbcp/pool2/BaseObject.java
Normal file
45
java/org/apache/tomcat/dbcp/pool2/BaseObject.java
Normal file
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* A base class for common functionality.
|
||||
*
|
||||
* @since 2.4.3
|
||||
*/
|
||||
public abstract class BaseObject {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
final StringBuilder builder = new StringBuilder();
|
||||
builder.append(getClass().getSimpleName());
|
||||
builder.append(" [");
|
||||
toStringAppendFields(builder);
|
||||
builder.append("]");
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Used by sub-classes to include the fields defined by the sub-class in the
|
||||
* {@link #toString()} output.
|
||||
*
|
||||
* @param builder Field names and values are appended to this object
|
||||
*/
|
||||
protected void toStringAppendFields(final StringBuilder builder) {
|
||||
// do nothing by default, needed for b/w compatibility.
|
||||
}
|
||||
}
|
||||
144
java/org/apache/tomcat/dbcp/pool2/BaseObjectPool.java
Normal file
144
java/org/apache/tomcat/dbcp/pool2/BaseObjectPool.java
Normal file
@@ -0,0 +1,144 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* A simple base implementation of {@link ObjectPool}.
|
||||
* Optional operations are implemented to either do nothing, return a value
|
||||
* 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.
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public abstract class BaseObjectPool<T> extends BaseObject implements ObjectPool<T> {
|
||||
|
||||
@Override
|
||||
public abstract T borrowObject() throws Exception;
|
||||
|
||||
@Override
|
||||
public abstract void returnObject(T obj) throws Exception;
|
||||
|
||||
@Override
|
||||
public abstract void invalidateObject(T obj) throws Exception;
|
||||
|
||||
/**
|
||||
* Not supported in this base implementation.
|
||||
*
|
||||
* @return a negative value.
|
||||
*/
|
||||
@Override
|
||||
public int getNumIdle() {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Not supported in this base implementation.
|
||||
*
|
||||
* @return a negative value.
|
||||
*/
|
||||
@Override
|
||||
public int getNumActive() {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Not supported in this base implementation.
|
||||
*
|
||||
* @throws UnsupportedOperationException if the pool does not implement this
|
||||
* method
|
||||
*/
|
||||
@Override
|
||||
public void clear() throws Exception, UnsupportedOperationException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Not supported in this base implementation. Subclasses should override
|
||||
* this behavior.
|
||||
*
|
||||
* @throws UnsupportedOperationException if the pool does not implement this
|
||||
* method
|
||||
*/
|
||||
@Override
|
||||
public void addObject() throws Exception, UnsupportedOperationException {
|
||||
throw new 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
|
||||
*/
|
||||
@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
|
||||
* <code>assertOpen</code>.
|
||||
* </p>
|
||||
*/
|
||||
@Override
|
||||
public void close() {
|
||||
closed = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Has this pool instance been closed.
|
||||
*
|
||||
* @return <code>true</code> when this pool has been closed.
|
||||
*/
|
||||
public final boolean isClosed() {
|
||||
return closed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Throws an <code>IllegalStateException</code> when this pool has been
|
||||
* closed.
|
||||
*
|
||||
* @throws IllegalStateException when this pool has been closed.
|
||||
*
|
||||
* @see #isClosed()
|
||||
*/
|
||||
protected final void assertOpen() throws IllegalStateException {
|
||||
if (isClosed()) {
|
||||
throw new IllegalStateException("Pool not open");
|
||||
}
|
||||
}
|
||||
|
||||
private volatile boolean closed = false;
|
||||
|
||||
@Override
|
||||
protected void toStringAppendFields(final StringBuilder builder) {
|
||||
builder.append("closed=");
|
||||
builder.append(closed);
|
||||
}
|
||||
}
|
||||
104
java/org/apache/tomcat/dbcp/pool2/BasePooledObjectFactory.java
Normal file
104
java/org/apache/tomcat/dbcp/pool2/BasePooledObjectFactory.java
Normal file
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* A base implementation of <code>PoolableObjectFactory</code>.
|
||||
* <p>
|
||||
* All operations defined here are essentially no-op's.
|
||||
* <p>
|
||||
* This class is immutable, and therefore thread-safe
|
||||
*
|
||||
* @param <T> Type of element managed in this factory.
|
||||
*
|
||||
* @see PooledObjectFactory
|
||||
* @see BaseKeyedPooledObjectFactory
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public abstract class BasePooledObjectFactory<T> extends BaseObject implements PooledObjectFactory<T> {
|
||||
/**
|
||||
* Creates an object instance, to be wrapped in a {@link PooledObject}.
|
||||
* <p>This method <strong>must</strong> support concurrent, multi-threaded
|
||||
* activation.</p>
|
||||
*
|
||||
* @return an instance to be served by the pool
|
||||
*
|
||||
* @throws Exception if there is a problem creating a new instance,
|
||||
* this will be propagated to the code requesting an object.
|
||||
*/
|
||||
public abstract T create() throws Exception;
|
||||
|
||||
/**
|
||||
* Wrap the provided instance with an implementation of
|
||||
* {@link PooledObject}.
|
||||
*
|
||||
* @param obj the instance to wrap
|
||||
*
|
||||
* @return The provided instance, wrapped by a {@link PooledObject}
|
||||
*/
|
||||
public abstract PooledObject<T> wrap(T obj);
|
||||
|
||||
@Override
|
||||
public PooledObject<T> makeObject() throws Exception {
|
||||
return wrap(create());
|
||||
}
|
||||
|
||||
/**
|
||||
* No-op.
|
||||
*
|
||||
* @param p ignored
|
||||
*/
|
||||
@Override
|
||||
public void destroyObject(final PooledObject<T> p)
|
||||
throws Exception {
|
||||
// The default implementation is a no-op.
|
||||
}
|
||||
|
||||
/**
|
||||
* This implementation always returns {@code true}.
|
||||
*
|
||||
* @param p ignored
|
||||
*
|
||||
* @return {@code true}
|
||||
*/
|
||||
@Override
|
||||
public boolean validateObject(final PooledObject<T> p) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* No-op.
|
||||
*
|
||||
* @param p ignored
|
||||
*/
|
||||
@Override
|
||||
public void activateObject(final PooledObject<T> p) throws Exception {
|
||||
// The default implementation is a no-op.
|
||||
}
|
||||
|
||||
/**
|
||||
* No-op.
|
||||
*
|
||||
* @param p ignored
|
||||
*/
|
||||
@Override
|
||||
public void passivateObject(final PooledObject<T> p)
|
||||
throws Exception {
|
||||
// The default implementation is a no-op.
|
||||
}
|
||||
}
|
||||
278
java/org/apache/tomcat/dbcp/pool2/KeyedObjectPool.java
Normal file
278
java/org/apache/tomcat/dbcp/pool2/KeyedObjectPool.java
Normal file
@@ -0,0 +1,278 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.util.Collection;
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
/**
|
||||
* A "keyed" pooling interface.
|
||||
* <p>
|
||||
* A keyed pool maintains a pool of instances for each key value.
|
||||
* </p>
|
||||
* <p>
|
||||
* Example of use:
|
||||
* </p>
|
||||
* <pre style="border:solid thin; padding: 1ex;"
|
||||
* > Object obj = <code style="color:#00C">null</code>;
|
||||
* Object key = <code style="color:#C00">"Key"</code>;
|
||||
*
|
||||
* <code style="color:#00C">try</code> {
|
||||
* obj = pool.borrowObject(key);
|
||||
* <code style="color:#0C0">//...use the object...</code>
|
||||
* } <code style="color:#00C">catch</code>(Exception e) {
|
||||
* <code style="color:#0C0">// invalidate the object</code>
|
||||
* pool.invalidateObject(key, obj);
|
||||
* <code style="color:#0C0">// do not return the object to the pool twice</code>
|
||||
* obj = <code style="color:#00C">null</code>;
|
||||
* } <code style="color:#00C">finally</code> {
|
||||
* <code style="color:#0C0">// make sure the object is returned to the pool</code>
|
||||
* <code style="color:#00C">if</code>(<code style="color:#00C">null</code> != obj) {
|
||||
* pool.returnObject(key, obj);
|
||||
* }
|
||||
* }</pre>
|
||||
* <p>
|
||||
* {@link KeyedObjectPool} implementations <i>may</i> choose to store at most
|
||||
* one instance per key value, or may choose to maintain a pool of instances
|
||||
* for each key (essentially creating a {@link java.util.Map Map} of
|
||||
* {@link ObjectPool pools}).
|
||||
* </p>
|
||||
* <p>
|
||||
* See {@link org.apache.tomcat.dbcp.pool2.impl.GenericKeyedObjectPool
|
||||
* GenericKeyedObjectPool} for an implementation.
|
||||
* </p>
|
||||
*
|
||||
* @param <K> The type of keys maintained by this pool.
|
||||
* @param <V> Type of element pooled in this pool.
|
||||
*
|
||||
* @see KeyedPooledObjectFactory
|
||||
* @see ObjectPool
|
||||
* @see org.apache.tomcat.dbcp.pool2.impl.GenericKeyedObjectPool GenericKeyedObjectPool
|
||||
*
|
||||
* @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>
|
||||
* Instances returned from this method will have been either newly created
|
||||
* with {@link KeyedPooledObjectFactory#makeObject makeObject} or will be
|
||||
* a previously idle object and have been activated with
|
||||
* {@link KeyedPooledObjectFactory#activateObject activateObject} and then
|
||||
* (optionally) validated with
|
||||
* {@link KeyedPooledObjectFactory#validateObject validateObject}.
|
||||
* </p>
|
||||
* <p>
|
||||
* By contract, clients <strong>must</strong> return the borrowed object
|
||||
* using {@link #returnObject returnObject},
|
||||
* {@link #invalidateObject invalidateObject}, or a related method as
|
||||
* defined in an implementation or sub-interface, using a <code>key</code>
|
||||
* that is {@link Object#equals equivalent} to the one used to borrow the
|
||||
* instance in the first place.
|
||||
* </p>
|
||||
* <p>
|
||||
* The behaviour of this method when the pool has been exhausted is not
|
||||
* strictly specified (although it may be specified by implementations).
|
||||
* </p>
|
||||
*
|
||||
* @param key the key used to obtain the object
|
||||
*
|
||||
* @return an instance from this pool.
|
||||
*
|
||||
* @throws IllegalStateException
|
||||
* after {@link #close close} has been called on this pool
|
||||
* @throws Exception
|
||||
* when {@link KeyedPooledObjectFactory#makeObject
|
||||
* makeObject} throws an exception
|
||||
* @throws NoSuchElementException
|
||||
* when the pool is exhausted and cannot or will not return
|
||||
* another instance
|
||||
*/
|
||||
V borrowObject(K key) throws Exception, NoSuchElementException, IllegalStateException;
|
||||
|
||||
/**
|
||||
* Clears the pool, removing all pooled instances (optional operation).
|
||||
*
|
||||
* @throws UnsupportedOperationException when this implementation doesn't
|
||||
* support the operation
|
||||
*
|
||||
* @throws Exception if the pool cannot be cleared
|
||||
*/
|
||||
void clear() throws Exception, UnsupportedOperationException;
|
||||
|
||||
/**
|
||||
* Clears the specified pool, removing all pooled instances corresponding to
|
||||
* the given <code>key</code> (optional operation).
|
||||
*
|
||||
* @param key the key to clear
|
||||
*
|
||||
* @throws UnsupportedOperationException when this implementation doesn't
|
||||
* support the operation
|
||||
*
|
||||
* @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>
|
||||
*/
|
||||
@Override
|
||||
void close();
|
||||
|
||||
/**
|
||||
* 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 getNumActive();
|
||||
|
||||
/**
|
||||
* Returns the number of instances currently borrowed from but not yet
|
||||
* returned to the pool corresponding to the given <code>key</code>.
|
||||
* Returns a negative value if this information is not available.
|
||||
*
|
||||
* @param key the key to query
|
||||
* @return the number of instances currently borrowed from but not yet
|
||||
* returned to the pool corresponding to the given <code>key</code>.
|
||||
*/
|
||||
int getNumActive(K key);
|
||||
|
||||
/**
|
||||
* Returns the total number of instances currently idle in this pool.
|
||||
* Returns a negative value if this information is not available.
|
||||
* @return the total number of instances currently idle in this pool.
|
||||
*/
|
||||
int getNumIdle();
|
||||
|
||||
/**
|
||||
* 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 getNumIdle(K key);
|
||||
|
||||
/**
|
||||
* 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>
|
||||
*
|
||||
* @param key the key used to obtain the object
|
||||
* @param obj a {@link #borrowObject borrowed} instance to be returned.
|
||||
*
|
||||
* @throws Exception if the instance cannot be invalidated
|
||||
*/
|
||||
void invalidateObject(K key, V obj) throws Exception;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* @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
|
||||
*/
|
||||
void returnObject(K key, V obj) throws Exception;
|
||||
}
|
||||
153
java/org/apache/tomcat/dbcp/pool2/KeyedPooledObjectFactory.java
Normal file
153
java/org/apache/tomcat/dbcp/pool2/KeyedPooledObjectFactory.java
Normal file
@@ -0,0 +1,153 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* An interface defining life-cycle methods for
|
||||
* instances to be served by a {@link KeyedObjectPool}.
|
||||
* <p>
|
||||
* By contract, when an {@link KeyedObjectPool}
|
||||
* delegates to a {@link KeyedPooledObjectFactory},
|
||||
* </p>
|
||||
* <ol>
|
||||
* <li>
|
||||
* {@link #makeObject} is called whenever a new instance is needed.
|
||||
* </li>
|
||||
* <li>
|
||||
* {@link #activateObject} is invoked on every instance that has been
|
||||
* {@link #passivateObject passivated} before it is
|
||||
* {@link KeyedObjectPool#borrowObject borrowed} from the pool.
|
||||
* </li>
|
||||
* <li>
|
||||
* {@link #validateObject} may be invoked on {@link #activateObject activated}
|
||||
* instances to make sure they can be
|
||||
* {@link KeyedObjectPool#borrowObject borrowed} from the pool.
|
||||
* <code>validateObject</code> may also be used to test an
|
||||
* instance being {@link KeyedObjectPool#returnObject returned} to the pool
|
||||
* before it is {@link #passivateObject passivated}. It will only be invoked
|
||||
* on an activated instance.
|
||||
* </li>
|
||||
* <li>
|
||||
* {@link #passivateObject passivateObject}
|
||||
* is invoked on every instance when it is returned to the pool.
|
||||
* </li>
|
||||
* <li>
|
||||
* {@link #destroyObject destroyObject}
|
||||
* is invoked on every instance when it is being "dropped" from the
|
||||
* pool (whether due to the response from <code>validateObject</code>,
|
||||
* or for reasons specific to the pool implementation.) There is no
|
||||
* guarantee that the instance being destroyed will
|
||||
* be considered active, passive or in a generally consistent state.
|
||||
* </li>
|
||||
* </ol>
|
||||
* {@link KeyedPooledObjectFactory} must be thread-safe. The only promise
|
||||
* an {@link KeyedObjectPool} makes is that the same instance of an object will
|
||||
* not be passed to more than one method of a
|
||||
* <code>KeyedPoolableObjectFactory</code> at a time.
|
||||
* <p>
|
||||
* While clients of a {@link KeyedObjectPool} borrow and return instances of
|
||||
* the underlying value type V, the factory methods act on instances of
|
||||
* {@link PooledObject PooledObject<V>}. These are the object wrappers that
|
||||
* pools use to track and maintain state informations about the objects that
|
||||
* they manage.
|
||||
* </p>
|
||||
*
|
||||
* @see KeyedObjectPool
|
||||
* @see BaseKeyedPooledObjectFactory
|
||||
*
|
||||
* @param <K> The type of keys managed by this factory.
|
||||
* @param <V> Type of element managed by this factory.
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public interface KeyedPooledObjectFactory<K, V> {
|
||||
|
||||
/**
|
||||
* Create an instance that can be served by the pool and
|
||||
* wrap it in a {@link PooledObject} to be managed by the pool.
|
||||
*
|
||||
* @param key the key used when constructing the object
|
||||
*
|
||||
* @return a {@code PooledObject} wrapping an instance that can
|
||||
* be served by the pool.
|
||||
*
|
||||
* @throws Exception if there is a problem creating a new instance,
|
||||
* this will be propagated to the code requesting an object.
|
||||
*/
|
||||
PooledObject<V> makeObject(K key) throws Exception;
|
||||
|
||||
/**
|
||||
* Destroy an instance no longer needed by the pool.
|
||||
* <p>
|
||||
* It is important for implementations of this method to be aware that there
|
||||
* is no guarantee about what state <code>obj</code> will be in and the
|
||||
* implementation should be prepared to handle unexpected errors.
|
||||
* </p>
|
||||
* <p>
|
||||
* Also, an implementation must take in to consideration that instances lost
|
||||
* to the garbage collector may never be destroyed.
|
||||
* </p>
|
||||
*
|
||||
* @param key the key used when selecting the instance
|
||||
* @param p a {@code PooledObject} wrapping the instance to be destroyed
|
||||
*
|
||||
* @throws Exception should be avoided as it may be swallowed by
|
||||
* the pool implementation.
|
||||
*
|
||||
* @see #validateObject
|
||||
* @see KeyedObjectPool#invalidateObject
|
||||
*/
|
||||
void destroyObject(K key, PooledObject<V> p) throws Exception;
|
||||
|
||||
/**
|
||||
* Ensures that the instance is safe to be returned by the pool.
|
||||
*
|
||||
* @param key the key used when selecting the object
|
||||
* @param p a {@code PooledObject} wrapping the instance to be validated
|
||||
*
|
||||
* @return <code>false</code> if <code>obj</code> is not valid and should
|
||||
* be dropped from the pool, <code>true</code> otherwise.
|
||||
*/
|
||||
boolean validateObject(K key, PooledObject<V> p);
|
||||
|
||||
/**
|
||||
* Reinitialize an instance to be returned by the pool.
|
||||
*
|
||||
* @param key the key used when selecting the object
|
||||
* @param p a {@code PooledObject} wrapping the instance to be activated
|
||||
*
|
||||
* @throws Exception if there is a problem activating <code>obj</code>,
|
||||
* this exception may be swallowed by the pool.
|
||||
*
|
||||
* @see #destroyObject
|
||||
*/
|
||||
void activateObject(K key, PooledObject<V> p) throws Exception;
|
||||
|
||||
/**
|
||||
* Uninitialize an instance to be returned to the idle object pool.
|
||||
*
|
||||
* @param key the key used when selecting the object
|
||||
* @param p a {@code PooledObject} wrapping the instance to be passivated
|
||||
*
|
||||
* @throws Exception if there is a problem passivating <code>obj</code>,
|
||||
* this exception may be swallowed by the pool.
|
||||
*
|
||||
* @see #destroyObject
|
||||
*/
|
||||
void passivateObject(K key, PooledObject<V> p) throws Exception;
|
||||
}
|
||||
|
||||
200
java/org/apache/tomcat/dbcp/pool2/ObjectPool.java
Normal file
200
java/org/apache/tomcat/dbcp/pool2/ObjectPool.java
Normal file
@@ -0,0 +1,200 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
/**
|
||||
* A pooling simple interface.
|
||||
* <p>
|
||||
* Example of use:
|
||||
* </p>
|
||||
* <pre style="border:solid thin; padding: 1ex;"
|
||||
* > Object obj = <code style="color:#00C">null</code>;
|
||||
*
|
||||
* <code style="color:#00C">try</code> {
|
||||
* obj = pool.borrowObject();
|
||||
* <code style="color:#00C">try</code> {
|
||||
* <code style="color:#0C0">//...use the object...</code>
|
||||
* } <code style="color:#00C">catch</code>(Exception e) {
|
||||
* <code style="color:#0C0">// invalidate the object</code>
|
||||
* pool.invalidateObject(obj);
|
||||
* <code style="color:#0C0">// do not return the object to the pool twice</code>
|
||||
* obj = <code style="color:#00C">null</code>;
|
||||
* } <code style="color:#00C">finally</code> {
|
||||
* <code style="color:#0C0">// make sure the object is returned to the pool</code>
|
||||
* <code style="color:#00C">if</code>(<code style="color:#00C">null</code> != obj) {
|
||||
* pool.returnObject(obj);
|
||||
* }
|
||||
* }
|
||||
* } <code style="color:#00C">catch</code>(Exception e) {
|
||||
* <code style="color:#0C0">// failed to borrow an object</code>
|
||||
* }</pre>
|
||||
* <p>
|
||||
* See {@link BaseObjectPool} for a simple base implementation.
|
||||
* </p>
|
||||
*
|
||||
* @param <T> Type of element pooled in this pool.
|
||||
*
|
||||
* @see PooledObjectFactory
|
||||
* @see KeyedObjectPool
|
||||
* @see BaseObjectPool
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
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
|
||||
* with {@link PooledObjectFactory#makeObject} or will be a previously
|
||||
* idle object and have been activated with
|
||||
* {@link PooledObjectFactory#activateObject} and then validated with
|
||||
* {@link PooledObjectFactory#validateObject}.
|
||||
* </p>
|
||||
* <p>
|
||||
* By contract, clients <strong>must</strong> return the borrowed instance
|
||||
* using {@link #returnObject}, {@link #invalidateObject}, or a related
|
||||
* method as defined in an implementation or sub-interface.
|
||||
* </p>
|
||||
* <p>
|
||||
* The behaviour of this method when the pool has been exhausted
|
||||
* is not strictly specified (although it may be specified by
|
||||
* implementations).
|
||||
* </p>
|
||||
*
|
||||
* @return an instance from this pool.
|
||||
*
|
||||
* @throws IllegalStateException
|
||||
* after {@link #close close} has been called on this pool.
|
||||
* @throws Exception
|
||||
* when {@link PooledObjectFactory#makeObject} throws an
|
||||
* exception.
|
||||
* @throws NoSuchElementException
|
||||
* when the pool is exhausted and cannot or will not return
|
||||
* another instance.
|
||||
*/
|
||||
T borrowObject() throws Exception, NoSuchElementException,
|
||||
IllegalStateException;
|
||||
|
||||
/**
|
||||
* Clears any objects sitting idle in the pool, releasing any associated
|
||||
* resources (optional operation). Idle objects cleared must be
|
||||
* {@link PooledObjectFactory#destroyObject(PooledObject)}.
|
||||
*
|
||||
* @throws UnsupportedOperationException
|
||||
* if this implementation does not support the operation
|
||||
*
|
||||
* @throws Exception if the pool cannot be cleared
|
||||
*/
|
||||
void clear() throws Exception, UnsupportedOperationException;
|
||||
|
||||
/**
|
||||
* 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>
|
||||
*/
|
||||
@Override
|
||||
void close();
|
||||
|
||||
/**
|
||||
* 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();
|
||||
|
||||
/**
|
||||
* Returns the number of instances currently idle in this pool. This may be
|
||||
* considered an approximation of the number of objects that can be
|
||||
* {@link #borrowObject borrowed} without creating any new instances.
|
||||
* Returns a negative value if this information is not available.
|
||||
* @return the number of instances currently idle in this pool.
|
||||
*/
|
||||
int getNumIdle();
|
||||
|
||||
/**
|
||||
* 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>
|
||||
*
|
||||
* @param obj a {@link #borrowObject borrowed} instance to be disposed.
|
||||
*
|
||||
* @throws Exception if the instance cannot be invalidated
|
||||
*/
|
||||
void invalidateObject(T obj) throws Exception;
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
void returnObject(T obj) throws Exception;
|
||||
}
|
||||
717
java/org/apache/tomcat/dbcp/pool2/PoolUtils.java
Normal file
717
java/org/apache/tomcat/dbcp/pool2/PoolUtils.java
Normal file
@@ -0,0 +1,717 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
|
||||
|
||||
/**
|
||||
* This class consists exclusively of static methods that operate on or return
|
||||
* ObjectPool or KeyedObjectPool related interfaces.
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public final class PoolUtils {
|
||||
|
||||
private static final String MSG_MIN_IDLE = "minIdle must be non-negative.";
|
||||
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.";
|
||||
public static final String MSG_NULL_KEYS = "keys must not be null.";
|
||||
private static final String MSG_NULL_POOL = "pool must not be null.";
|
||||
|
||||
/**
|
||||
* Timer used to periodically check pools idle object count. Because a
|
||||
* {@link Timer} creates a {@link Thread}, an IODH is used.
|
||||
*/
|
||||
static class TimerHolder {
|
||||
static final Timer MIN_IDLE_TIMER = new Timer(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* PoolUtils instances should NOT be constructed in standard programming.
|
||||
* Instead, the class should be used procedurally: PoolUtils.adapt(aPool);.
|
||||
* This constructor is public to permit tools that require a JavaBean
|
||||
* instance to operate.
|
||||
*/
|
||||
public PoolUtils() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Should the supplied Throwable be re-thrown (eg if it is an instance of
|
||||
* one of the Throwables that should never be swallowed). Used by the pool
|
||||
* error handling for operations that throw exceptions that normally need to
|
||||
* be ignored.
|
||||
*
|
||||
* @param t
|
||||
* The Throwable to check
|
||||
* @throws ThreadDeath
|
||||
* if that is passed in
|
||||
* @throws VirtualMachineError
|
||||
* if that is passed in
|
||||
*/
|
||||
public static void checkRethrow(final Throwable t) {
|
||||
if (t instanceof ThreadDeath) {
|
||||
throw (ThreadDeath) t;
|
||||
}
|
||||
if (t instanceof VirtualMachineError) {
|
||||
throw (VirtualMachineError) t;
|
||||
}
|
||||
// All other instances of Throwable will be silently swallowed
|
||||
}
|
||||
|
||||
/**
|
||||
* Periodically check the idle object count for the pool. At most one idle
|
||||
* object will be added per period. If there is an exception when calling
|
||||
* {@link ObjectPool#addObject()} then no more checks will be performed.
|
||||
*
|
||||
* @param pool
|
||||
* the pool to check periodically.
|
||||
* @param minIdle
|
||||
* if the {@link ObjectPool#getNumIdle()} is less than this then
|
||||
* add an idle object.
|
||||
* @param period
|
||||
* the frequency to check the number of idle objects in a pool,
|
||||
* see {@link Timer#schedule(TimerTask, long, long)}.
|
||||
* @param <T> the type of objects in the pool
|
||||
* @return the {@link TimerTask} that will periodically check the pools idle
|
||||
* object count.
|
||||
* @throws IllegalArgumentException
|
||||
* when <code>pool</code> is <code>null</code> or when
|
||||
* <code>minIdle</code> is negative or when <code>period</code>
|
||||
* isn't valid for {@link Timer#schedule(TimerTask, long, long)}
|
||||
*/
|
||||
public static <T> TimerTask checkMinIdle(final ObjectPool<T> pool,
|
||||
final int minIdle, final long period)
|
||||
throws IllegalArgumentException {
|
||||
if (pool == null) {
|
||||
throw new IllegalArgumentException(MSG_NULL_KEYED_POOL);
|
||||
}
|
||||
if (minIdle < 0) {
|
||||
throw new IllegalArgumentException(MSG_MIN_IDLE);
|
||||
}
|
||||
final TimerTask task = new ObjectPoolMinIdleTimerTask<>(pool, minIdle);
|
||||
getMinIdleTimer().schedule(task, 0L, period);
|
||||
return task;
|
||||
}
|
||||
|
||||
/**
|
||||
* Periodically check the idle object count for the key in the keyedPool. At
|
||||
* most one idle object will be added per period. If there is an exception
|
||||
* when calling {@link KeyedObjectPool#addObject(Object)} then no more
|
||||
* checks for that key will be performed.
|
||||
*
|
||||
* @param keyedPool
|
||||
* the keyedPool to check periodically.
|
||||
* @param key
|
||||
* the key to check the idle count of.
|
||||
* @param minIdle
|
||||
* if the {@link KeyedObjectPool#getNumIdle(Object)} is less than
|
||||
* this then add an idle object.
|
||||
* @param period
|
||||
* the frequency to check the number of idle objects in a
|
||||
* keyedPool, see {@link Timer#schedule(TimerTask, long, long)}.
|
||||
* @param <K> the type of the pool key
|
||||
* @param <V> the type of pool entries
|
||||
* @return the {@link TimerTask} that will periodically check the pools idle
|
||||
* object count.
|
||||
* @throws IllegalArgumentException
|
||||
* when <code>keyedPool</code>, <code>key</code> is
|
||||
* <code>null</code> or when <code>minIdle</code> is negative or
|
||||
* when <code>period</code> isn't valid for
|
||||
* {@link Timer#schedule(TimerTask, long, long)}.
|
||||
*/
|
||||
public static <K, V> TimerTask checkMinIdle(
|
||||
final KeyedObjectPool<K, V> keyedPool, final K key,
|
||||
final int minIdle, final long period)
|
||||
throws IllegalArgumentException {
|
||||
if (keyedPool == null) {
|
||||
throw new IllegalArgumentException(MSG_NULL_KEYED_POOL);
|
||||
}
|
||||
if (key == null) {
|
||||
throw new IllegalArgumentException(MSG_NULL_KEY);
|
||||
}
|
||||
if (minIdle < 0) {
|
||||
throw new IllegalArgumentException(MSG_MIN_IDLE);
|
||||
}
|
||||
final TimerTask task = new KeyedObjectPoolMinIdleTimerTask<>(
|
||||
keyedPool, key, minIdle);
|
||||
getMinIdleTimer().schedule(task, 0L, period);
|
||||
return task;
|
||||
}
|
||||
|
||||
/**
|
||||
* Periodically check the idle object count for each key in the
|
||||
* <code>Collection</code> <code>keys</code> in the keyedPool. At most one
|
||||
* idle object will be added per period.
|
||||
*
|
||||
* @param keyedPool
|
||||
* the keyedPool to check periodically.
|
||||
* @param keys
|
||||
* a collection of keys to check the idle object count.
|
||||
* @param minIdle
|
||||
* if the {@link KeyedObjectPool#getNumIdle(Object)} is less than
|
||||
* this then add an idle object.
|
||||
* @param period
|
||||
* the frequency to check the number of idle objects in a
|
||||
* keyedPool, see {@link Timer#schedule(TimerTask, long, long)}.
|
||||
* @param <K> the type of the pool key
|
||||
* @param <V> the type of pool entries
|
||||
* @return a {@link Map} of key and {@link TimerTask} pairs that will
|
||||
* periodically check the pools idle object count.
|
||||
* @throws IllegalArgumentException
|
||||
* when <code>keyedPool</code>, <code>keys</code>, or any of the
|
||||
* values in the collection is <code>null</code> or when
|
||||
* <code>minIdle</code> is negative or when <code>period</code>
|
||||
* isn't valid for {@link Timer#schedule(TimerTask, long, long)}
|
||||
* .
|
||||
* @see #checkMinIdle(KeyedObjectPool, Object, int, long)
|
||||
*/
|
||||
public static <K, V> Map<K, TimerTask> checkMinIdle(
|
||||
final KeyedObjectPool<K, V> keyedPool, final Collection<K> keys,
|
||||
final int minIdle, final long period)
|
||||
throws IllegalArgumentException {
|
||||
if (keys == null) {
|
||||
throw new IllegalArgumentException(MSG_NULL_KEYS);
|
||||
}
|
||||
final Map<K, TimerTask> tasks = new HashMap<>(keys.size());
|
||||
final Iterator<K> iter = keys.iterator();
|
||||
while (iter.hasNext()) {
|
||||
final K key = iter.next();
|
||||
final TimerTask task = checkMinIdle(keyedPool, key, minIdle, period);
|
||||
tasks.put(key, task);
|
||||
}
|
||||
return tasks;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls {@link ObjectPool#addObject()} on <code>pool</code> <code>count</code>
|
||||
* number of times.
|
||||
*
|
||||
* @param pool
|
||||
* the pool to prefill.
|
||||
* @param count
|
||||
* the number of idle objects to add.
|
||||
* @param <T> the type of objects in the pool
|
||||
* @throws Exception
|
||||
* 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);
|
||||
}
|
||||
pool.addObjects(count);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls {@link KeyedObjectPool#addObject(Object)} on <code>keyedPool</code> with
|
||||
* <code>key</code> <code>count</code> number of times.
|
||||
*
|
||||
* @param keyedPool
|
||||
* the keyedPool to prefill.
|
||||
* @param key
|
||||
* the key to add objects for.
|
||||
* @param count
|
||||
* the number of idle objects to add for <code>key</code>.
|
||||
* @param <K> the type of the pool key
|
||||
* @param <V> the type of pool entries
|
||||
* @throws Exception
|
||||
* when {@link KeyedObjectPool#addObject(Object)} fails.
|
||||
* @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);
|
||||
}
|
||||
keyedPool.addObjects(key, count);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls {@link KeyedObjectPool#addObject(Object)} on <code>keyedPool</code> with each
|
||||
* key in <code>keys</code> for <code>count</code> number of times. This has
|
||||
* the same effect as calling {@link #prefill(KeyedObjectPool, Object, int)}
|
||||
* for each key in the <code>keys</code> collection.
|
||||
*
|
||||
* @param keyedPool
|
||||
* the keyedPool to prefill.
|
||||
* @param keys
|
||||
* {@link Collection} of keys to add objects for.
|
||||
* @param count
|
||||
* the number of idle objects to add for each <code>key</code>.
|
||||
* @param <K> the type of the pool key
|
||||
* @param <V> the type of pool entries
|
||||
* @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 #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);
|
||||
}
|
||||
keyedPool.addObjects(keys, count);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a synchronized (thread-safe) PooledObjectFactory backed by the
|
||||
* specified PooledObjectFactory.
|
||||
*
|
||||
* @param factory
|
||||
* the PooledObjectFactory to be "wrapped" in a synchronized
|
||||
* PooledObjectFactory.
|
||||
* @param <T> the type of objects in the pool
|
||||
* @return a synchronized view of the specified PooledObjectFactory.
|
||||
*/
|
||||
public static <T> PooledObjectFactory<T> synchronizedPooledFactory(
|
||||
final PooledObjectFactory<T> factory) {
|
||||
return new SynchronizedPooledObjectFactory<>(factory);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a synchronized (thread-safe) KeyedPooledObjectFactory backed by
|
||||
* the specified KeyedPoolableObjectFactory.
|
||||
*
|
||||
* @param keyedFactory
|
||||
* the KeyedPooledObjectFactory to be "wrapped" in a
|
||||
* synchronized KeyedPooledObjectFactory.
|
||||
* @param <K> the type of the pool key
|
||||
* @param <V> the type of pool entries
|
||||
* @return a synchronized view of the specified KeyedPooledObjectFactory.
|
||||
*/
|
||||
public static <K, V> KeyedPooledObjectFactory<K, V> synchronizedKeyedPooledFactory(
|
||||
final KeyedPooledObjectFactory<K, V> keyedFactory) {
|
||||
return new SynchronizedKeyedPooledObjectFactory<>(keyedFactory);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the <code>Timer</code> for checking keyedPool's idle count.
|
||||
*
|
||||
* @return the {@link Timer} for checking keyedPool's idle count.
|
||||
*/
|
||||
private static Timer getMinIdleTimer() {
|
||||
return TimerHolder.MIN_IDLE_TIMER;
|
||||
}
|
||||
|
||||
/**
|
||||
* Timer task that adds objects to the pool until the number of idle
|
||||
* instances reaches the configured minIdle. Note that this is not the same
|
||||
* as the pool's minIdle setting.
|
||||
*
|
||||
* @param <T> type of objects in the pool
|
||||
*/
|
||||
private static final class ObjectPoolMinIdleTimerTask<T> extends TimerTask {
|
||||
|
||||
/** Minimum number of idle instances. Not the same as pool.getMinIdle(). */
|
||||
private final int minIdle;
|
||||
|
||||
/** Object pool */
|
||||
private final ObjectPool<T> pool;
|
||||
|
||||
/**
|
||||
* Create a new ObjectPoolMinIdleTimerTask for the given pool with the
|
||||
* given minIdle setting.
|
||||
*
|
||||
* @param pool
|
||||
* object pool
|
||||
* @param minIdle
|
||||
* number of idle instances to maintain
|
||||
* @throws IllegalArgumentException
|
||||
* if the pool is null
|
||||
*/
|
||||
ObjectPoolMinIdleTimerTask(final ObjectPool<T> pool, final int minIdle)
|
||||
throws IllegalArgumentException {
|
||||
if (pool == null) {
|
||||
throw new IllegalArgumentException(MSG_NULL_POOL);
|
||||
}
|
||||
this.pool = pool;
|
||||
this.minIdle = minIdle;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void run() {
|
||||
boolean success = false;
|
||||
try {
|
||||
if (pool.getNumIdle() < minIdle) {
|
||||
pool.addObject();
|
||||
}
|
||||
success = true;
|
||||
|
||||
} catch (final Exception e) {
|
||||
cancel();
|
||||
} finally {
|
||||
// detect other types of Throwable and cancel this Timer
|
||||
if (!success) {
|
||||
cancel();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
sb.append("ObjectPoolMinIdleTimerTask");
|
||||
sb.append("{minIdle=").append(minIdle);
|
||||
sb.append(", pool=").append(pool);
|
||||
sb.append('}');
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Timer task that adds objects to the pool until the number of idle
|
||||
* instances for the given key reaches the configured minIdle. Note that
|
||||
* this is not the same as the pool's minIdle setting.
|
||||
*
|
||||
* @param <K> object pool key type
|
||||
* @param <V> object pool value type
|
||||
*/
|
||||
private static final class KeyedObjectPoolMinIdleTimerTask<K, V> extends
|
||||
TimerTask {
|
||||
|
||||
/** Minimum number of idle instances. Not the same as pool.getMinIdle(). */
|
||||
private final int minIdle;
|
||||
|
||||
/** Key to ensure minIdle for */
|
||||
private final K key;
|
||||
|
||||
/** Keyed object pool */
|
||||
private final KeyedObjectPool<K, V> keyedPool;
|
||||
|
||||
/**
|
||||
* Creates a new KeyedObjecPoolMinIdleTimerTask.
|
||||
*
|
||||
* @param keyedPool
|
||||
* keyed object pool
|
||||
* @param key
|
||||
* key to ensure minimum number of idle instances
|
||||
* @param minIdle
|
||||
* minimum number of idle instances
|
||||
* @throws IllegalArgumentException
|
||||
* if the key is null
|
||||
*/
|
||||
KeyedObjectPoolMinIdleTimerTask(final KeyedObjectPool<K, V> keyedPool,
|
||||
final K key, final int minIdle) throws IllegalArgumentException {
|
||||
if (keyedPool == null) {
|
||||
throw new IllegalArgumentException(
|
||||
MSG_NULL_KEYED_POOL);
|
||||
}
|
||||
this.keyedPool = keyedPool;
|
||||
this.key = key;
|
||||
this.minIdle = minIdle;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void run() {
|
||||
boolean success = false;
|
||||
try {
|
||||
if (keyedPool.getNumIdle(key) < minIdle) {
|
||||
keyedPool.addObject(key);
|
||||
}
|
||||
success = true;
|
||||
|
||||
} catch (final Exception e) {
|
||||
cancel();
|
||||
|
||||
} finally {
|
||||
// detect other types of Throwable and cancel this Timer
|
||||
if (!success) {
|
||||
cancel();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
sb.append("KeyedObjectPoolMinIdleTimerTask");
|
||||
sb.append("{minIdle=").append(minIdle);
|
||||
sb.append(", key=").append(key);
|
||||
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);
|
||||
} finally {
|
||||
writeLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
sb.append("SynchronizedKeyedPoolableObjectFactory");
|
||||
sb.append("{keyedFactory=").append(keyedFactory);
|
||||
sb.append('}');
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
220
java/org/apache/tomcat/dbcp/pool2/PooledObject.java
Normal file
220
java/org/apache/tomcat/dbcp/pool2/PooledObject.java
Normal file
@@ -0,0 +1,220 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.util.Deque;
|
||||
|
||||
/**
|
||||
* Defines the wrapper that is used to track the additional information, such as
|
||||
* 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
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public interface PooledObject<T> extends Comparable<PooledObject<T>> {
|
||||
|
||||
/**
|
||||
* Obtains the underlying object that is wrapped by this instance of
|
||||
* {@link PooledObject}.
|
||||
*
|
||||
* @return The wrapped object
|
||||
*/
|
||||
T getObject();
|
||||
|
||||
/**
|
||||
* Obtains the time (using the same basis as
|
||||
* {@link System#currentTimeMillis()}) that this object was created.
|
||||
*
|
||||
* @return The creation time for the wrapped object
|
||||
*/
|
||||
long getCreateTime();
|
||||
|
||||
/**
|
||||
* Obtains the time in milliseconds that this object last spent in the
|
||||
* active state (it may still be active in which case subsequent calls will
|
||||
* return an increased value).
|
||||
*
|
||||
* @return The time in milliseconds last spent in the active state
|
||||
*/
|
||||
long getActiveTimeMillis();
|
||||
|
||||
/**
|
||||
* Gets the number of times this object has been borrowed.
|
||||
*
|
||||
* @return The number of times this object has been borrowed.
|
||||
* @since 2.7.0
|
||||
*/
|
||||
long getBorrowedCount();
|
||||
|
||||
/**
|
||||
* Obtains the time in milliseconds that this object last spend in the
|
||||
* idle state (it may still be idle in which case subsequent calls will
|
||||
* return an increased value).
|
||||
*
|
||||
* @return The time in milliseconds last spent in the idle state
|
||||
*/
|
||||
long getIdleTimeMillis();
|
||||
|
||||
/**
|
||||
* Obtains the time the wrapped object was last borrowed.
|
||||
*
|
||||
* @return The time the object was last borrowed
|
||||
*/
|
||||
long getLastBorrowTime();
|
||||
|
||||
/**
|
||||
* Obtains the time the wrapped object was last returned.
|
||||
*
|
||||
* @return The time the object was last returned
|
||||
*/
|
||||
long getLastReturnTime();
|
||||
|
||||
/**
|
||||
* Returns an estimate of the last time this object was used. If the class
|
||||
* of the pooled object implements {@link TrackedUse}, what is returned is
|
||||
* the maximum of {@link TrackedUse#getLastUsed()} and
|
||||
* {@link #getLastBorrowTime()}; otherwise this method gives the same
|
||||
* value as {@link #getLastBorrowTime()}.
|
||||
*
|
||||
* @return the last time this object was used
|
||||
*/
|
||||
long getLastUsedTime();
|
||||
|
||||
/**
|
||||
* Orders instances based on idle time - i.e. the length of time since the
|
||||
* instance was returned to the pool. Used by the GKOP idle object evictor.
|
||||
*<p>
|
||||
* Note: This class has a natural ordering that is inconsistent with
|
||||
* equals if distinct objects have the same identity hash code.
|
||||
* </p>
|
||||
* <p>
|
||||
* {@inheritDoc}
|
||||
* </p>
|
||||
*/
|
||||
@Override
|
||||
int compareTo(PooledObject<T> other);
|
||||
|
||||
@Override
|
||||
boolean equals(Object obj);
|
||||
|
||||
@Override
|
||||
int hashCode();
|
||||
|
||||
/**
|
||||
* Provides a String form of the wrapper for debug purposes. The format is
|
||||
* not fixed and may change at any time.
|
||||
* <p>
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
String toString();
|
||||
|
||||
/**
|
||||
* Attempts to place the pooled object in the
|
||||
* {@link PooledObjectState#EVICTION} state.
|
||||
*
|
||||
* @return <code>true</code> if the object was placed in the
|
||||
* {@link PooledObjectState#EVICTION} state otherwise
|
||||
* <code>false</code>
|
||||
*/
|
||||
boolean startEvictionTest();
|
||||
|
||||
/**
|
||||
* Called to inform the object that the eviction test has ended.
|
||||
*
|
||||
* @param idleQueue The queue of idle objects to which the object should be
|
||||
* returned
|
||||
*
|
||||
* @return Currently not used
|
||||
*/
|
||||
boolean endEvictionTest(Deque<PooledObject<T>> idleQueue);
|
||||
|
||||
/**
|
||||
* Allocates the object.
|
||||
*
|
||||
* @return {@code true} if the original state was {@link PooledObjectState#IDLE IDLE}
|
||||
*/
|
||||
boolean allocate();
|
||||
|
||||
/**
|
||||
* Deallocates the object and sets it {@link PooledObjectState#IDLE IDLE}
|
||||
* if it is currently {@link PooledObjectState#ALLOCATED ALLOCATED}.
|
||||
*
|
||||
* @return {@code true} if the state was {@link PooledObjectState#ALLOCATED ALLOCATED}
|
||||
*/
|
||||
boolean deallocate();
|
||||
|
||||
/**
|
||||
* Sets the state to {@link PooledObjectState#INVALID INVALID}
|
||||
*/
|
||||
void invalidate();
|
||||
|
||||
/**
|
||||
* Is abandoned object tracking being used? If this is true the
|
||||
* implementation will need to record the stack trace of the last caller to
|
||||
* borrow this object.
|
||||
*
|
||||
* @param logAbandoned The new configuration setting for abandoned
|
||||
* object tracking
|
||||
*/
|
||||
void setLogAbandoned(boolean logAbandoned);
|
||||
|
||||
/**
|
||||
* Configures the stack trace generation strategy based on whether or not fully detailed stack traces are required.
|
||||
* When set to false, abandoned logs may only include caller class information rather than method names, line
|
||||
* numbers, and other normal metadata available in a full stack trace.
|
||||
*
|
||||
* @param requireFullStackTrace the new configuration setting for abandoned object logging
|
||||
* @since 2.7.0
|
||||
*/
|
||||
void setRequireFullStackTrace(final boolean requireFullStackTrace);
|
||||
|
||||
/**
|
||||
* Record the current stack trace as the last time the object was used.
|
||||
*/
|
||||
void use();
|
||||
|
||||
/**
|
||||
* Prints the stack trace of the code that borrowed this pooled object and
|
||||
* the stack trace of the last code to use this object (if available) to
|
||||
* the supplied writer.
|
||||
*
|
||||
* @param writer The destination for the debug output
|
||||
*/
|
||||
void printStackTrace(PrintWriter writer);
|
||||
|
||||
/**
|
||||
* Returns the state of this object.
|
||||
* @return state
|
||||
*/
|
||||
PooledObjectState getState();
|
||||
|
||||
/**
|
||||
* Marks the pooled object as abandoned.
|
||||
*/
|
||||
void markAbandoned();
|
||||
|
||||
/**
|
||||
* Marks the object as returning to the pool.
|
||||
*/
|
||||
void markReturning();
|
||||
}
|
||||
141
java/org/apache/tomcat/dbcp/pool2/PooledObjectFactory.java
Normal file
141
java/org/apache/tomcat/dbcp/pool2/PooledObjectFactory.java
Normal file
@@ -0,0 +1,141 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* An interface defining life-cycle methods for instances to be served by an
|
||||
* {@link ObjectPool}.
|
||||
* <p>
|
||||
* By contract, when an {@link ObjectPool} delegates to a
|
||||
* {@link PooledObjectFactory},
|
||||
* </p>
|
||||
* <ol>
|
||||
* <li>
|
||||
* {@link #makeObject} is called whenever a new instance is needed.
|
||||
* </li>
|
||||
* <li>
|
||||
* {@link #activateObject} is invoked on every instance that has been
|
||||
* {@link #passivateObject passivated} before it is
|
||||
* {@link ObjectPool#borrowObject borrowed} from the pool.
|
||||
* </li>
|
||||
* <li>
|
||||
* {@link #validateObject} may be invoked on {@link #activateObject activated}
|
||||
* instances to make sure they can be {@link ObjectPool#borrowObject borrowed}
|
||||
* from the pool. {@link #validateObject} may also be used to
|
||||
* test an instance being {@link ObjectPool#returnObject returned} to the pool
|
||||
* before it is {@link #passivateObject passivated}. It will only be invoked
|
||||
* on an activated instance.
|
||||
* </li>
|
||||
* <li>
|
||||
* {@link #passivateObject} is invoked on every instance when it is returned
|
||||
* to the pool.
|
||||
* </li>
|
||||
* <li>
|
||||
* {@link #destroyObject} is invoked on every instance when it is being
|
||||
* "dropped" from the pool (whether due to the response from
|
||||
* {@link #validateObject}, or for reasons specific to the pool
|
||||
* implementation.) There is no guarantee that the instance being destroyed
|
||||
* will be considered active, passive or in a generally consistent state.
|
||||
* </li>
|
||||
* </ol>
|
||||
* {@link PooledObjectFactory} must be thread-safe. The only promise
|
||||
* an {@link ObjectPool} makes is that the same instance of an object will not
|
||||
* be passed to more than one method of a <code>PoolableObjectFactory</code>
|
||||
* at a time.
|
||||
* <p>
|
||||
* While clients of a {@link KeyedObjectPool} borrow and return instances of
|
||||
* the underlying value type {@code V}, the factory methods act on instances of
|
||||
* {@link PooledObject PooledObject<V>}. These are the object wrappers that
|
||||
* pools use to track and maintain state information about the objects that
|
||||
* they manage.
|
||||
* </p>
|
||||
*
|
||||
* @param <T> Type of element managed in this factory.
|
||||
*
|
||||
* @see ObjectPool
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public interface PooledObjectFactory<T> {
|
||||
|
||||
/**
|
||||
* Creates an instance that can be served by the pool and wrap it in a
|
||||
* {@link PooledObject} to be managed by the pool.
|
||||
*
|
||||
* @return a {@code PooledObject} wrapping an instance that can be served by the pool
|
||||
*
|
||||
* @throws Exception if there is a problem creating a new instance,
|
||||
* this will be propagated to the code requesting an object.
|
||||
*/
|
||||
PooledObject<T> makeObject() throws Exception;
|
||||
|
||||
/**
|
||||
* Destroys an instance no longer needed by the pool.
|
||||
* <p>
|
||||
* It is important for implementations of this method to be aware that there
|
||||
* is no guarantee about what state <code>obj</code> will be in and the
|
||||
* implementation should be prepared to handle unexpected errors.
|
||||
* </p>
|
||||
* <p>
|
||||
* Also, an implementation must take in to consideration that instances lost
|
||||
* to the garbage collector may never be destroyed.
|
||||
* </p>
|
||||
*
|
||||
* @param p a {@code PooledObject} wrapping the instance to be destroyed
|
||||
*
|
||||
* @throws Exception should be avoided as it may be swallowed by
|
||||
* the pool implementation.
|
||||
*
|
||||
* @see #validateObject
|
||||
* @see ObjectPool#invalidateObject
|
||||
*/
|
||||
void destroyObject(PooledObject<T> p) throws Exception;
|
||||
|
||||
/**
|
||||
* Ensures that the instance is safe to be returned by the pool.
|
||||
*
|
||||
* @param p a {@code PooledObject} wrapping the instance to be validated
|
||||
*
|
||||
* @return <code>false</code> if <code>obj</code> is not valid and should
|
||||
* be dropped from the pool, <code>true</code> otherwise.
|
||||
*/
|
||||
boolean validateObject(PooledObject<T> p);
|
||||
|
||||
/**
|
||||
* Reinitializes an instance to be returned by the pool.
|
||||
*
|
||||
* @param p a {@code PooledObject} wrapping the instance to be activated
|
||||
*
|
||||
* @throws Exception if there is a problem activating <code>obj</code>,
|
||||
* this exception may be swallowed by the pool.
|
||||
*
|
||||
* @see #destroyObject
|
||||
*/
|
||||
void activateObject(PooledObject<T> p) throws Exception;
|
||||
|
||||
/**
|
||||
* Uninitializes an instance to be returned to the idle object pool.
|
||||
*
|
||||
* @param p a {@code PooledObject} wrapping the instance to be passivated
|
||||
*
|
||||
* @throws Exception if there is a problem passivating <code>obj</code>,
|
||||
* this exception may be swallowed by the pool.
|
||||
*
|
||||
* @see #destroyObject
|
||||
*/
|
||||
void passivateObject(PooledObject<T> p) throws Exception;
|
||||
}
|
||||
87
java/org/apache/tomcat/dbcp/pool2/PooledObjectState.java
Normal file
87
java/org/apache/tomcat/dbcp/pool2/PooledObjectState.java
Normal file
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* Provides the possible states that a {@link PooledObject} may be in.
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public enum PooledObjectState {
|
||||
|
||||
/**
|
||||
* In the queue, not in use.
|
||||
*/
|
||||
IDLE,
|
||||
|
||||
/**
|
||||
* In use.
|
||||
*/
|
||||
ALLOCATED,
|
||||
|
||||
/**
|
||||
* In the queue, currently being tested for possible eviction.
|
||||
*/
|
||||
EVICTION,
|
||||
|
||||
/**
|
||||
* Not in the queue, currently being tested for possible eviction. An
|
||||
* attempt to borrow the object was made while being tested which removed it
|
||||
* from the queue. It should be returned to the head of the queue once
|
||||
* eviction testing completes.
|
||||
* TODO: Consider allocating object and ignoring the result of the eviction
|
||||
* test.
|
||||
*/
|
||||
EVICTION_RETURN_TO_HEAD,
|
||||
|
||||
/**
|
||||
* In the queue, currently being validated.
|
||||
*/
|
||||
VALIDATION,
|
||||
|
||||
/**
|
||||
* Not in queue, currently being validated. The object was borrowed while
|
||||
* being validated and since testOnBorrow was configured, it was removed
|
||||
* from the queue and pre-allocated. It should be allocated once validation
|
||||
* completes.
|
||||
*/
|
||||
VALIDATION_PREALLOCATED,
|
||||
|
||||
/**
|
||||
* Not in queue, currently being validated. An attempt to borrow the object
|
||||
* was made while previously being tested for eviction which removed it from
|
||||
* the queue. It should be returned to the head of the queue once validation
|
||||
* completes.
|
||||
*/
|
||||
VALIDATION_RETURN_TO_HEAD,
|
||||
|
||||
/**
|
||||
* Failed maintenance (e.g. eviction test or validation) and will be / has
|
||||
* been destroyed
|
||||
*/
|
||||
INVALID,
|
||||
|
||||
/**
|
||||
* Deemed abandoned, to be invalidated.
|
||||
*/
|
||||
ABANDONED,
|
||||
|
||||
/**
|
||||
* Returning to the pool.
|
||||
*/
|
||||
RETURNING
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* Pools that unavoidably swallow exceptions may be configured with an instance
|
||||
* of this listener so the user may receive notification of when this happens.
|
||||
* The listener should not throw an exception when called but pools calling
|
||||
* listeners should protect themselves against exceptions anyway.
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public interface SwallowedExceptionListener {
|
||||
|
||||
/**
|
||||
* This method is called every time the implementation unavoidably swallows
|
||||
* an exception.
|
||||
*
|
||||
* @param e The exception that was swallowed
|
||||
*/
|
||||
void onSwallowException(Exception e);
|
||||
}
|
||||
36
java/org/apache/tomcat/dbcp/pool2/TrackedUse.java
Normal file
36
java/org/apache/tomcat/dbcp/pool2/TrackedUse.java
Normal file
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* This interface allows pooled objects to make information available about when
|
||||
* and how they were used available to the object pool. The object pool may, but
|
||||
* is not required, to use this information to make more informed decisions when
|
||||
* determining the state of a pooled object - for instance whether or not the
|
||||
* object has been abandoned.
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public interface TrackedUse {
|
||||
|
||||
/**
|
||||
* Get the last time this object was used in ms.
|
||||
*
|
||||
* @return long time in ms
|
||||
*/
|
||||
long getLastUsed();
|
||||
}
|
||||
39
java/org/apache/tomcat/dbcp/pool2/UsageTracking.java
Normal file
39
java/org/apache/tomcat/dbcp/pool2/UsageTracking.java
Normal file
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* This interface may be implemented by an object pool to enable clients
|
||||
* (primarily those clients that wrap pools to provide pools with extended
|
||||
* features) to provide additional information to the pool relating to object
|
||||
* using allowing more informed decisions and reporting to be made regarding
|
||||
* abandoned objects.
|
||||
*
|
||||
* @param <T> The type of object provided by the pool.
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public interface UsageTracking<T> {
|
||||
|
||||
/**
|
||||
* This method is called every time a pooled object is used to enable the pool to
|
||||
* better track borrowed objects.
|
||||
*
|
||||
* @param pooledObject The object that is being used
|
||||
*/
|
||||
void use(T pooledObject);
|
||||
}
|
||||
292
java/org/apache/tomcat/dbcp/pool2/impl/AbandonedConfig.java
Normal file
292
java/org/apache/tomcat/dbcp/pool2/impl/AbandonedConfig.java
Normal file
@@ -0,0 +1,292 @@
|
||||
/*
|
||||
* 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.impl;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
|
||||
/**
|
||||
* Configuration settings for abandoned object removal.
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public class AbandonedConfig {
|
||||
|
||||
/**
|
||||
* Whether or not borrowObject performs abandoned object removal.
|
||||
*/
|
||||
private boolean removeAbandonedOnBorrow = false;
|
||||
|
||||
/**
|
||||
* <p>Flag to remove abandoned objects if they exceed the
|
||||
* removeAbandonedTimeout when borrowObject is invoked.</p>
|
||||
*
|
||||
* <p>The default value is false.</p>
|
||||
*
|
||||
* <p>If set to true, abandoned objects are removed by borrowObject if
|
||||
* there are fewer than 2 idle objects available in the pool and
|
||||
* <code>getNumActive() > getMaxTotal() - 3</code></p>
|
||||
*
|
||||
* @return true if abandoned objects are to be removed by borrowObject
|
||||
*/
|
||||
public boolean getRemoveAbandonedOnBorrow() {
|
||||
return this.removeAbandonedOnBorrow;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Flag to remove abandoned objects if they exceed the
|
||||
* removeAbandonedTimeout when borrowObject is invoked.</p>
|
||||
*
|
||||
* @param removeAbandonedOnBorrow true means abandoned objects will be
|
||||
* removed by borrowObject
|
||||
* @see #getRemoveAbandonedOnBorrow()
|
||||
*/
|
||||
public void setRemoveAbandonedOnBorrow(final boolean removeAbandonedOnBorrow) {
|
||||
this.removeAbandonedOnBorrow = removeAbandonedOnBorrow;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether or not pool maintenance (evictor) performs abandoned object
|
||||
* removal.
|
||||
*/
|
||||
private boolean removeAbandonedOnMaintenance = false;
|
||||
|
||||
/**
|
||||
* <p>Flag to remove abandoned objects if they exceed the
|
||||
* removeAbandonedTimeout when pool maintenance (the "evictor")
|
||||
* runs.</p>
|
||||
*
|
||||
* <p>The default value is false.</p>
|
||||
*
|
||||
* <p>If set to true, abandoned objects are removed by the pool
|
||||
* maintenance thread when it runs. This setting has no effect
|
||||
* unless maintenance is enabled by setting
|
||||
*{@link GenericObjectPool#getTimeBetweenEvictionRunsMillis() timeBetweenEvictionRunsMillis}
|
||||
* to a positive number.</p>
|
||||
*
|
||||
* @return true if abandoned objects are to be removed by the evictor
|
||||
*/
|
||||
public boolean getRemoveAbandonedOnMaintenance() {
|
||||
return this.removeAbandonedOnMaintenance;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Flag to remove abandoned objects if they exceed the
|
||||
* removeAbandonedTimeout when pool maintenance runs.</p>
|
||||
*
|
||||
* @param removeAbandonedOnMaintenance true means abandoned objects will be
|
||||
* removed by pool maintenance
|
||||
* @see #getRemoveAbandonedOnMaintenance
|
||||
*/
|
||||
public void setRemoveAbandonedOnMaintenance(final boolean removeAbandonedOnMaintenance) {
|
||||
this.removeAbandonedOnMaintenance = removeAbandonedOnMaintenance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Timeout in seconds before an abandoned object can be removed.
|
||||
*/
|
||||
private int removeAbandonedTimeout = 300;
|
||||
|
||||
/**
|
||||
* <p>Timeout in seconds before an abandoned object can be removed.</p>
|
||||
*
|
||||
* <p>The time of most recent use of an object is the maximum (latest) of
|
||||
* {@link org.apache.tomcat.dbcp.pool2.TrackedUse#getLastUsed()}
|
||||
* (if this class of the object implements
|
||||
* TrackedUse) and the time when the object was borrowed from the pool.</p>
|
||||
*
|
||||
* <p>The default value is 300 seconds.</p>
|
||||
*
|
||||
* @return the abandoned object timeout in seconds
|
||||
*/
|
||||
public int getRemoveAbandonedTimeout() {
|
||||
return this.removeAbandonedTimeout;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Sets the timeout in seconds before an abandoned object can be
|
||||
* removed</p>
|
||||
*
|
||||
* <p>Setting this property has no effect if
|
||||
* {@link #getRemoveAbandonedOnBorrow() removeAbandonedOnBorrow} and
|
||||
* {@link #getRemoveAbandonedOnMaintenance() removeAbandonedOnMaintenance}
|
||||
* are both false.</p>
|
||||
*
|
||||
* @param removeAbandonedTimeout new abandoned timeout in seconds
|
||||
* @see #getRemoveAbandonedTimeout()
|
||||
*/
|
||||
public void setRemoveAbandonedTimeout(final int removeAbandonedTimeout) {
|
||||
this.removeAbandonedTimeout = removeAbandonedTimeout;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether or not to log stack traces for application code
|
||||
* which abandoned an object.
|
||||
*/
|
||||
private boolean logAbandoned = false;
|
||||
|
||||
/**
|
||||
* Flag to log stack traces for application code which abandoned
|
||||
* an object.
|
||||
*
|
||||
* Defaults to false.
|
||||
* Logging of abandoned objects adds overhead for every object created
|
||||
* because a stack trace has to be generated.
|
||||
*
|
||||
* @return boolean true if stack trace logging is turned on for abandoned
|
||||
* objects
|
||||
*
|
||||
*/
|
||||
public boolean getLogAbandoned() {
|
||||
return this.logAbandoned;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the flag to log stack traces for application code which abandoned
|
||||
* an object.
|
||||
*
|
||||
* @param logAbandoned true turns on abandoned stack trace logging
|
||||
* @see #getLogAbandoned()
|
||||
*
|
||||
*/
|
||||
public void setLogAbandoned(final boolean logAbandoned) {
|
||||
this.logAbandoned = logAbandoned;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether or not to log full stack traces when logAbandoned is true.
|
||||
* If disabled, then a faster method for logging stack traces with only class data
|
||||
* may be used if possible.
|
||||
*
|
||||
* @since 2.5
|
||||
*/
|
||||
private boolean requireFullStackTrace = true;
|
||||
|
||||
/**
|
||||
* Indicates if full stack traces are required when {@link #getLogAbandoned() logAbandoned}
|
||||
* is true. Defaults to true. Logging of abandoned objects requiring a full stack trace will
|
||||
* generate an entire stack trace to generate for every object created. If this is disabled,
|
||||
* a faster but less informative stack walking mechanism may be used if available.
|
||||
*
|
||||
* @return true if full stack traces are required for logging abandoned connections, or false
|
||||
* if abbreviated stack traces are acceptable
|
||||
* @see CallStack
|
||||
* @since 2.5
|
||||
*/
|
||||
public boolean getRequireFullStackTrace() {
|
||||
return requireFullStackTrace;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the flag to require full stack traces for logging abandoned connections when enabled.
|
||||
*
|
||||
* @param requireFullStackTrace indicates whether or not full stack traces are required in
|
||||
* abandoned connection logs
|
||||
* @see CallStack
|
||||
* @see #getRequireFullStackTrace()
|
||||
* @since 2.5
|
||||
*/
|
||||
public void setRequireFullStackTrace(final boolean requireFullStackTrace) {
|
||||
this.requireFullStackTrace = requireFullStackTrace;
|
||||
}
|
||||
|
||||
/**
|
||||
* PrintWriter to use to log information on abandoned objects.
|
||||
* Use of default system encoding is deliberate.
|
||||
*/
|
||||
private PrintWriter logWriter = new PrintWriter(System.out);
|
||||
|
||||
/**
|
||||
* Returns the log writer being used by this configuration to log
|
||||
* information on abandoned objects. If not set, a PrintWriter based on
|
||||
* System.out with the system default encoding is used.
|
||||
*
|
||||
* @return log writer in use
|
||||
*/
|
||||
public PrintWriter getLogWriter() {
|
||||
return logWriter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the log writer to be used by this configuration to log
|
||||
* information on abandoned objects.
|
||||
*
|
||||
* @param logWriter The new log writer
|
||||
*/
|
||||
public void setLogWriter(final PrintWriter logWriter) {
|
||||
this.logWriter = logWriter;
|
||||
}
|
||||
|
||||
/**
|
||||
* If the pool implements
|
||||
* {@link org.apache.tomcat.dbcp.pool2.UsageTracking}, should the pool
|
||||
* record a stack trace every time a method is called on a pooled object and
|
||||
* retain the most recent stack trace to aid debugging of abandoned objects?
|
||||
*/
|
||||
private boolean useUsageTracking = false;
|
||||
|
||||
/**
|
||||
* If the pool implements
|
||||
* {@link org.apache.tomcat.dbcp.pool2.UsageTracking}, should the pool
|
||||
* record a
|
||||
* stack trace every time a method is called on a pooled object and retain
|
||||
* the most recent stack trace to aid debugging of abandoned objects?
|
||||
*
|
||||
* @return <code>true</code> if usage tracking is enabled
|
||||
*/
|
||||
public boolean getUseUsageTracking() {
|
||||
return useUsageTracking;
|
||||
}
|
||||
|
||||
/**
|
||||
* If the pool implements
|
||||
* {@link org.apache.tomcat.dbcp.pool2.UsageTracking}, configure whether the
|
||||
* pool
|
||||
* should record a stack trace every time a method is called on a pooled
|
||||
* object and retain the most recent stack trace to aid debugging of
|
||||
* abandoned objects.
|
||||
*
|
||||
* @param useUsageTracking A value of <code>true</code> will enable
|
||||
* the recording of a stack trace on every use
|
||||
* of a pooled object
|
||||
*/
|
||||
public void setUseUsageTracking(final boolean useUsageTracking) {
|
||||
this.useUsageTracking = useUsageTracking;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.4.3
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
final StringBuilder builder = new StringBuilder();
|
||||
builder.append("AbandonedConfig [removeAbandonedOnBorrow=");
|
||||
builder.append(removeAbandonedOnBorrow);
|
||||
builder.append(", removeAbandonedOnMaintenance=");
|
||||
builder.append(removeAbandonedOnMaintenance);
|
||||
builder.append(", removeAbandonedTimeout=");
|
||||
builder.append(removeAbandonedTimeout);
|
||||
builder.append(", logAbandoned=");
|
||||
builder.append(logAbandoned);
|
||||
builder.append(", logWriter=");
|
||||
builder.append(logWriter);
|
||||
builder.append(", useUsageTracking=");
|
||||
builder.append(useUsageTracking);
|
||||
builder.append("]");
|
||||
return builder.toString();
|
||||
}
|
||||
}
|
||||
1411
java/org/apache/tomcat/dbcp/pool2/impl/BaseGenericObjectPool.java
Normal file
1411
java/org/apache/tomcat/dbcp/pool2/impl/BaseGenericObjectPool.java
Normal file
File diff suppressed because it is too large
Load Diff
750
java/org/apache/tomcat/dbcp/pool2/impl/BaseObjectPoolConfig.java
Normal file
750
java/org/apache/tomcat/dbcp/pool2/impl/BaseObjectPoolConfig.java
Normal file
@@ -0,0 +1,750 @@
|
||||
/*
|
||||
* 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.impl;
|
||||
|
||||
import org.apache.tomcat.dbcp.pool2.BaseObject;
|
||||
|
||||
/**
|
||||
* Provides the implementation for the common attributes shared by the
|
||||
* sub-classes. New instances of this class will be created using the defaults
|
||||
* defined by the public constants.
|
||||
* <p>
|
||||
* This class is not thread-safe.
|
||||
* </p>
|
||||
*
|
||||
* @param <T> Type of element pooled.
|
||||
* @since 2.0
|
||||
*/
|
||||
public abstract class BaseObjectPoolConfig<T> extends BaseObject implements Cloneable {
|
||||
|
||||
/**
|
||||
* The default value for the {@code lifo} configuration attribute.
|
||||
* @see GenericObjectPool#getLifo()
|
||||
* @see GenericKeyedObjectPool#getLifo()
|
||||
*/
|
||||
public static final boolean DEFAULT_LIFO = true;
|
||||
|
||||
/**
|
||||
* The default value for the {@code fairness} configuration attribute.
|
||||
* @see GenericObjectPool#getFairness()
|
||||
* @see GenericKeyedObjectPool#getFairness()
|
||||
*/
|
||||
public static final boolean DEFAULT_FAIRNESS = false;
|
||||
|
||||
/**
|
||||
* The default value for the {@code maxWait} configuration attribute.
|
||||
* @see GenericObjectPool#getMaxWaitMillis()
|
||||
* @see GenericKeyedObjectPool#getMaxWaitMillis()
|
||||
*/
|
||||
public static final long DEFAULT_MAX_WAIT_MILLIS = -1L;
|
||||
|
||||
/**
|
||||
* The default value for the {@code minEvictableIdleTimeMillis}
|
||||
* configuration attribute.
|
||||
* @see GenericObjectPool#getMinEvictableIdleTimeMillis()
|
||||
* @see GenericKeyedObjectPool#getMinEvictableIdleTimeMillis()
|
||||
*/
|
||||
public static final long DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS =
|
||||
1000L * 60L * 30L;
|
||||
|
||||
/**
|
||||
* The default value for the {@code softMinEvictableIdleTimeMillis}
|
||||
* configuration attribute.
|
||||
* @see GenericObjectPool#getSoftMinEvictableIdleTimeMillis()
|
||||
* @see GenericKeyedObjectPool#getSoftMinEvictableIdleTimeMillis()
|
||||
*/
|
||||
public static final long DEFAULT_SOFT_MIN_EVICTABLE_IDLE_TIME_MILLIS = -1;
|
||||
|
||||
/**
|
||||
* The default value for {@code evictorShutdownTimeoutMillis} configuration
|
||||
* attribute.
|
||||
* @see GenericObjectPool#getEvictorShutdownTimeoutMillis()
|
||||
* @see GenericKeyedObjectPool#getEvictorShutdownTimeoutMillis()
|
||||
*/
|
||||
public static final long DEFAULT_EVICTOR_SHUTDOWN_TIMEOUT_MILLIS =
|
||||
10L * 1000L;
|
||||
|
||||
/**
|
||||
* The default value for the {@code numTestsPerEvictionRun} configuration
|
||||
* attribute.
|
||||
* @see GenericObjectPool#getNumTestsPerEvictionRun()
|
||||
* @see GenericKeyedObjectPool#getNumTestsPerEvictionRun()
|
||||
*/
|
||||
public static final int DEFAULT_NUM_TESTS_PER_EVICTION_RUN = 3;
|
||||
|
||||
/**
|
||||
* The default value for the {@code testOnCreate} configuration attribute.
|
||||
* @see GenericObjectPool#getTestOnCreate()
|
||||
* @see GenericKeyedObjectPool#getTestOnCreate()
|
||||
*
|
||||
* @since 2.2
|
||||
*/
|
||||
public static final boolean DEFAULT_TEST_ON_CREATE = false;
|
||||
|
||||
/**
|
||||
* The default value for the {@code testOnBorrow} configuration attribute.
|
||||
* @see GenericObjectPool#getTestOnBorrow()
|
||||
* @see GenericKeyedObjectPool#getTestOnBorrow()
|
||||
*/
|
||||
public static final boolean DEFAULT_TEST_ON_BORROW = false;
|
||||
|
||||
/**
|
||||
* The default value for the {@code testOnReturn} configuration attribute.
|
||||
* @see GenericObjectPool#getTestOnReturn()
|
||||
* @see GenericKeyedObjectPool#getTestOnReturn()
|
||||
*/
|
||||
public static final boolean DEFAULT_TEST_ON_RETURN = false;
|
||||
|
||||
/**
|
||||
* The default value for the {@code testWhileIdle} configuration attribute.
|
||||
* @see GenericObjectPool#getTestWhileIdle()
|
||||
* @see GenericKeyedObjectPool#getTestWhileIdle()
|
||||
*/
|
||||
public static final boolean DEFAULT_TEST_WHILE_IDLE = false;
|
||||
|
||||
/**
|
||||
* The default value for the {@code timeBetweenEvictionRunsMillis}
|
||||
* configuration attribute.
|
||||
* @see GenericObjectPool#getTimeBetweenEvictionRunsMillis()
|
||||
* @see GenericKeyedObjectPool#getTimeBetweenEvictionRunsMillis()
|
||||
*/
|
||||
public static final long DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS = -1L;
|
||||
|
||||
/**
|
||||
* The default value for the {@code blockWhenExhausted} configuration
|
||||
* attribute.
|
||||
* @see GenericObjectPool#getBlockWhenExhausted()
|
||||
* @see GenericKeyedObjectPool#getBlockWhenExhausted()
|
||||
*/
|
||||
public static final boolean DEFAULT_BLOCK_WHEN_EXHAUSTED = true;
|
||||
|
||||
/**
|
||||
* The default value for enabling JMX for pools created with a configuration
|
||||
* instance.
|
||||
*/
|
||||
public static final boolean DEFAULT_JMX_ENABLE = true;
|
||||
|
||||
/**
|
||||
* The default value for the prefix used to name JMX enabled pools created
|
||||
* with a configuration instance.
|
||||
* @see GenericObjectPool#getJmxName()
|
||||
* @see GenericKeyedObjectPool#getJmxName()
|
||||
*/
|
||||
public static final String DEFAULT_JMX_NAME_PREFIX = "pool";
|
||||
|
||||
/**
|
||||
* The default value for the base name to use to name JMX enabled pools
|
||||
* created with a configuration instance. The default is <code>null</code>
|
||||
* which means the pool will provide the base name to use.
|
||||
* @see GenericObjectPool#getJmxName()
|
||||
* @see GenericKeyedObjectPool#getJmxName()
|
||||
*/
|
||||
public static final String DEFAULT_JMX_NAME_BASE = null;
|
||||
|
||||
/**
|
||||
* The default value for the {@code evictionPolicyClassName} configuration
|
||||
* attribute.
|
||||
* @see GenericObjectPool#getEvictionPolicyClassName()
|
||||
* @see GenericKeyedObjectPool#getEvictionPolicyClassName()
|
||||
*/
|
||||
public static final String DEFAULT_EVICTION_POLICY_CLASS_NAME = DefaultEvictionPolicy.class.getName();
|
||||
|
||||
private boolean lifo = DEFAULT_LIFO;
|
||||
|
||||
private boolean fairness = DEFAULT_FAIRNESS;
|
||||
|
||||
private long maxWaitMillis = DEFAULT_MAX_WAIT_MILLIS;
|
||||
|
||||
private long minEvictableIdleTimeMillis =
|
||||
DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS;
|
||||
|
||||
private long evictorShutdownTimeoutMillis =
|
||||
DEFAULT_EVICTOR_SHUTDOWN_TIMEOUT_MILLIS;
|
||||
|
||||
private long softMinEvictableIdleTimeMillis =
|
||||
DEFAULT_SOFT_MIN_EVICTABLE_IDLE_TIME_MILLIS;
|
||||
|
||||
private int numTestsPerEvictionRun =
|
||||
DEFAULT_NUM_TESTS_PER_EVICTION_RUN;
|
||||
|
||||
private EvictionPolicy<T> evictionPolicy = null; // Only 2.6.0 applications set this
|
||||
|
||||
private String evictionPolicyClassName = DEFAULT_EVICTION_POLICY_CLASS_NAME;
|
||||
|
||||
private boolean testOnCreate = DEFAULT_TEST_ON_CREATE;
|
||||
|
||||
private boolean testOnBorrow = DEFAULT_TEST_ON_BORROW;
|
||||
|
||||
private boolean testOnReturn = DEFAULT_TEST_ON_RETURN;
|
||||
|
||||
private boolean testWhileIdle = DEFAULT_TEST_WHILE_IDLE;
|
||||
|
||||
private long timeBetweenEvictionRunsMillis =
|
||||
DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS;
|
||||
|
||||
private boolean blockWhenExhausted = DEFAULT_BLOCK_WHEN_EXHAUSTED;
|
||||
|
||||
private boolean jmxEnabled = DEFAULT_JMX_ENABLE;
|
||||
|
||||
// TODO Consider changing this to a single property for 3.x
|
||||
private String jmxNamePrefix = DEFAULT_JMX_NAME_PREFIX;
|
||||
|
||||
private String jmxNameBase = DEFAULT_JMX_NAME_BASE;
|
||||
|
||||
|
||||
/**
|
||||
* Get the value for the {@code lifo} configuration attribute for pools
|
||||
* created with this configuration instance.
|
||||
*
|
||||
* @return The current setting of {@code lifo} for this configuration
|
||||
* instance
|
||||
*
|
||||
* @see GenericObjectPool#getLifo()
|
||||
* @see GenericKeyedObjectPool#getLifo()
|
||||
*/
|
||||
public boolean getLifo() {
|
||||
return lifo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value for the {@code fairness} configuration attribute for pools
|
||||
* created with this configuration instance.
|
||||
*
|
||||
* @return The current setting of {@code fairness} for this configuration
|
||||
* instance
|
||||
*
|
||||
* @see GenericObjectPool#getFairness()
|
||||
* @see GenericKeyedObjectPool#getFairness()
|
||||
*/
|
||||
public boolean getFairness() {
|
||||
return fairness;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value for the {@code lifo} configuration attribute for pools
|
||||
* created with this configuration instance.
|
||||
*
|
||||
* @param lifo The new setting of {@code lifo}
|
||||
* for this configuration instance
|
||||
*
|
||||
* @see GenericObjectPool#getLifo()
|
||||
* @see GenericKeyedObjectPool#getLifo()
|
||||
*/
|
||||
public void setLifo(final boolean lifo) {
|
||||
this.lifo = lifo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value for the {@code fairness} configuration attribute for pools
|
||||
* created with this configuration instance.
|
||||
*
|
||||
* @param fairness The new setting of {@code fairness}
|
||||
* for this configuration instance
|
||||
*
|
||||
* @see GenericObjectPool#getFairness()
|
||||
* @see GenericKeyedObjectPool#getFairness()
|
||||
*/
|
||||
public void setFairness(final boolean fairness) {
|
||||
this.fairness = fairness;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value for the {@code maxWait} configuration attribute for pools
|
||||
* created with this configuration instance.
|
||||
*
|
||||
* @return The current setting of {@code maxWait} for this
|
||||
* configuration instance
|
||||
*
|
||||
* @see GenericObjectPool#getMaxWaitMillis()
|
||||
* @see GenericKeyedObjectPool#getMaxWaitMillis()
|
||||
*/
|
||||
public long getMaxWaitMillis() {
|
||||
return maxWaitMillis;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value for the {@code maxWait} configuration attribute for pools
|
||||
* created with this configuration instance.
|
||||
*
|
||||
* @param maxWaitMillis The new setting of {@code maxWaitMillis}
|
||||
* for this configuration instance
|
||||
*
|
||||
* @see GenericObjectPool#getMaxWaitMillis()
|
||||
* @see GenericKeyedObjectPool#getMaxWaitMillis()
|
||||
*/
|
||||
public void setMaxWaitMillis(final long maxWaitMillis) {
|
||||
this.maxWaitMillis = maxWaitMillis;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value for the {@code minEvictableIdleTimeMillis} configuration
|
||||
* attribute for pools created with this configuration instance.
|
||||
*
|
||||
* @return The current setting of {@code minEvictableIdleTimeMillis} for
|
||||
* this configuration instance
|
||||
*
|
||||
* @see GenericObjectPool#getMinEvictableIdleTimeMillis()
|
||||
* @see GenericKeyedObjectPool#getMinEvictableIdleTimeMillis()
|
||||
*/
|
||||
public long getMinEvictableIdleTimeMillis() {
|
||||
return minEvictableIdleTimeMillis;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value for the {@code minEvictableIdleTimeMillis} configuration
|
||||
* attribute for pools created with this configuration instance.
|
||||
*
|
||||
* @param minEvictableIdleTimeMillis The new setting of
|
||||
* {@code minEvictableIdleTimeMillis} for this configuration instance
|
||||
*
|
||||
* @see GenericObjectPool#getMinEvictableIdleTimeMillis()
|
||||
* @see GenericKeyedObjectPool#getMinEvictableIdleTimeMillis()
|
||||
*/
|
||||
public void setMinEvictableIdleTimeMillis(final long minEvictableIdleTimeMillis) {
|
||||
this.minEvictableIdleTimeMillis = minEvictableIdleTimeMillis;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value for the {@code softMinEvictableIdleTimeMillis}
|
||||
* configuration attribute for pools created with this configuration
|
||||
* instance.
|
||||
*
|
||||
* @return The current setting of {@code softMinEvictableIdleTimeMillis}
|
||||
* for this configuration instance
|
||||
*
|
||||
* @see GenericObjectPool#getSoftMinEvictableIdleTimeMillis()
|
||||
* @see GenericKeyedObjectPool#getSoftMinEvictableIdleTimeMillis()
|
||||
*/
|
||||
public long getSoftMinEvictableIdleTimeMillis() {
|
||||
return softMinEvictableIdleTimeMillis;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value for the {@code softMinEvictableIdleTimeMillis}
|
||||
* configuration attribute for pools created with this configuration
|
||||
* instance.
|
||||
*
|
||||
* @param softMinEvictableIdleTimeMillis The new setting of
|
||||
* {@code softMinEvictableIdleTimeMillis} for this configuration
|
||||
* instance
|
||||
*
|
||||
* @see GenericObjectPool#getSoftMinEvictableIdleTimeMillis()
|
||||
* @see GenericKeyedObjectPool#getSoftMinEvictableIdleTimeMillis()
|
||||
*/
|
||||
public void setSoftMinEvictableIdleTimeMillis(
|
||||
final long softMinEvictableIdleTimeMillis) {
|
||||
this.softMinEvictableIdleTimeMillis = softMinEvictableIdleTimeMillis;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value for the {@code numTestsPerEvictionRun} configuration
|
||||
* attribute for pools created with this configuration instance.
|
||||
*
|
||||
* @return The current setting of {@code numTestsPerEvictionRun} for this
|
||||
* configuration instance
|
||||
*
|
||||
* @see GenericObjectPool#getNumTestsPerEvictionRun()
|
||||
* @see GenericKeyedObjectPool#getNumTestsPerEvictionRun()
|
||||
*/
|
||||
public int getNumTestsPerEvictionRun() {
|
||||
return numTestsPerEvictionRun;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value for the {@code numTestsPerEvictionRun} configuration
|
||||
* attribute for pools created with this configuration instance.
|
||||
*
|
||||
* @param numTestsPerEvictionRun The new setting of
|
||||
* {@code numTestsPerEvictionRun} for this configuration instance
|
||||
*
|
||||
* @see GenericObjectPool#getNumTestsPerEvictionRun()
|
||||
* @see GenericKeyedObjectPool#getNumTestsPerEvictionRun()
|
||||
*/
|
||||
public void setNumTestsPerEvictionRun(final int numTestsPerEvictionRun) {
|
||||
this.numTestsPerEvictionRun = numTestsPerEvictionRun;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value for the {@code evictorShutdownTimeoutMillis} configuration
|
||||
* attribute for pools created with this configuration instance.
|
||||
*
|
||||
* @return The current setting of {@code evictorShutdownTimeoutMillis} for
|
||||
* this configuration instance
|
||||
*
|
||||
* @see GenericObjectPool#getEvictorShutdownTimeoutMillis()
|
||||
* @see GenericKeyedObjectPool#getEvictorShutdownTimeoutMillis()
|
||||
*/
|
||||
public long getEvictorShutdownTimeoutMillis() {
|
||||
return evictorShutdownTimeoutMillis;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value for the {@code evictorShutdownTimeoutMillis} configuration
|
||||
* attribute for pools created with this configuration instance.
|
||||
*
|
||||
* @param evictorShutdownTimeoutMillis The new setting of
|
||||
* {@code evictorShutdownTimeoutMillis} for this configuration
|
||||
* instance
|
||||
*
|
||||
* @see GenericObjectPool#getEvictorShutdownTimeoutMillis()
|
||||
* @see GenericKeyedObjectPool#getEvictorShutdownTimeoutMillis()
|
||||
*/
|
||||
public void setEvictorShutdownTimeoutMillis(
|
||||
final long evictorShutdownTimeoutMillis) {
|
||||
this.evictorShutdownTimeoutMillis = evictorShutdownTimeoutMillis;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value for the {@code testOnCreate} configuration attribute for
|
||||
* pools created with this configuration instance.
|
||||
*
|
||||
* @return The current setting of {@code testOnCreate} for this
|
||||
* configuration instance
|
||||
*
|
||||
* @see GenericObjectPool#getTestOnCreate()
|
||||
* @see GenericKeyedObjectPool#getTestOnCreate()
|
||||
*
|
||||
* @since 2.2
|
||||
*/
|
||||
public boolean getTestOnCreate() {
|
||||
return testOnCreate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value for the {@code testOnCreate} configuration attribute for
|
||||
* pools created with this configuration instance.
|
||||
*
|
||||
* @param testOnCreate The new setting of {@code testOnCreate}
|
||||
* for this configuration instance
|
||||
*
|
||||
* @see GenericObjectPool#getTestOnCreate()
|
||||
* @see GenericKeyedObjectPool#getTestOnCreate()
|
||||
*
|
||||
* @since 2.2
|
||||
*/
|
||||
public void setTestOnCreate(final boolean testOnCreate) {
|
||||
this.testOnCreate = testOnCreate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value for the {@code testOnBorrow} configuration attribute for
|
||||
* pools created with this configuration instance.
|
||||
*
|
||||
* @return The current setting of {@code testOnBorrow} for this
|
||||
* configuration instance
|
||||
*
|
||||
* @see GenericObjectPool#getTestOnBorrow()
|
||||
* @see GenericKeyedObjectPool#getTestOnBorrow()
|
||||
*/
|
||||
public boolean getTestOnBorrow() {
|
||||
return testOnBorrow;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value for the {@code testOnBorrow} configuration attribute for
|
||||
* pools created with this configuration instance.
|
||||
*
|
||||
* @param testOnBorrow The new setting of {@code testOnBorrow}
|
||||
* for this configuration instance
|
||||
*
|
||||
* @see GenericObjectPool#getTestOnBorrow()
|
||||
* @see GenericKeyedObjectPool#getTestOnBorrow()
|
||||
*/
|
||||
public void setTestOnBorrow(final boolean testOnBorrow) {
|
||||
this.testOnBorrow = testOnBorrow;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value for the {@code testOnReturn} configuration attribute for
|
||||
* pools created with this configuration instance.
|
||||
*
|
||||
* @return The current setting of {@code testOnReturn} for this
|
||||
* configuration instance
|
||||
*
|
||||
* @see GenericObjectPool#getTestOnReturn()
|
||||
* @see GenericKeyedObjectPool#getTestOnReturn()
|
||||
*/
|
||||
public boolean getTestOnReturn() {
|
||||
return testOnReturn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value for the {@code testOnReturn} configuration attribute for
|
||||
* pools created with this configuration instance.
|
||||
*
|
||||
* @param testOnReturn The new setting of {@code testOnReturn}
|
||||
* for this configuration instance
|
||||
*
|
||||
* @see GenericObjectPool#getTestOnReturn()
|
||||
* @see GenericKeyedObjectPool#getTestOnReturn()
|
||||
*/
|
||||
public void setTestOnReturn(final boolean testOnReturn) {
|
||||
this.testOnReturn = testOnReturn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value for the {@code testWhileIdle} configuration attribute for
|
||||
* pools created with this configuration instance.
|
||||
*
|
||||
* @return The current setting of {@code testWhileIdle} for this
|
||||
* configuration instance
|
||||
*
|
||||
* @see GenericObjectPool#getTestWhileIdle()
|
||||
* @see GenericKeyedObjectPool#getTestWhileIdle()
|
||||
*/
|
||||
public boolean getTestWhileIdle() {
|
||||
return testWhileIdle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value for the {@code testWhileIdle} configuration attribute for
|
||||
* pools created with this configuration instance.
|
||||
*
|
||||
* @param testWhileIdle The new setting of {@code testWhileIdle}
|
||||
* for this configuration instance
|
||||
*
|
||||
* @see GenericObjectPool#getTestWhileIdle()
|
||||
* @see GenericKeyedObjectPool#getTestWhileIdle()
|
||||
*/
|
||||
public void setTestWhileIdle(final boolean testWhileIdle) {
|
||||
this.testWhileIdle = testWhileIdle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value for the {@code timeBetweenEvictionRunsMillis} configuration
|
||||
* attribute for pools created with this configuration instance.
|
||||
*
|
||||
* @return The current setting of {@code timeBetweenEvictionRunsMillis} for
|
||||
* this configuration instance
|
||||
*
|
||||
* @see GenericObjectPool#getTimeBetweenEvictionRunsMillis()
|
||||
* @see GenericKeyedObjectPool#getTimeBetweenEvictionRunsMillis()
|
||||
*/
|
||||
public long getTimeBetweenEvictionRunsMillis() {
|
||||
return timeBetweenEvictionRunsMillis;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value for the {@code timeBetweenEvictionRunsMillis} configuration
|
||||
* attribute for pools created with this configuration instance.
|
||||
*
|
||||
* @param timeBetweenEvictionRunsMillis The new setting of
|
||||
* {@code timeBetweenEvictionRunsMillis} for this configuration
|
||||
* instance
|
||||
*
|
||||
* @see GenericObjectPool#getTimeBetweenEvictionRunsMillis()
|
||||
* @see GenericKeyedObjectPool#getTimeBetweenEvictionRunsMillis()
|
||||
*/
|
||||
public void setTimeBetweenEvictionRunsMillis(
|
||||
final long timeBetweenEvictionRunsMillis) {
|
||||
this.timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value for the {@code evictionPolicyClass} configuration
|
||||
* attribute for pools created with this configuration instance.
|
||||
*
|
||||
* @return The current setting of {@code evictionPolicyClass} for this
|
||||
* configuration instance
|
||||
*
|
||||
* @see GenericObjectPool#getEvictionPolicy()
|
||||
* @see GenericKeyedObjectPool#getEvictionPolicy()
|
||||
* @since 2.6.0
|
||||
*/
|
||||
public EvictionPolicy<T> getEvictionPolicy() {
|
||||
return evictionPolicy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value for the {@code evictionPolicyClassName} configuration
|
||||
* attribute for pools created with this configuration instance.
|
||||
*
|
||||
* @return The current setting of {@code evictionPolicyClassName} for this
|
||||
* configuration instance
|
||||
*
|
||||
* @see GenericObjectPool#getEvictionPolicyClassName()
|
||||
* @see GenericKeyedObjectPool#getEvictionPolicyClassName()
|
||||
*/
|
||||
public String getEvictionPolicyClassName() {
|
||||
return evictionPolicyClassName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value for the {@code evictionPolicyClass} configuration
|
||||
* attribute for pools created with this configuration instance.
|
||||
*
|
||||
* @param evictionPolicy The new setting of
|
||||
* {@code evictionPolicyClass} for this configuration instance
|
||||
*
|
||||
* @see GenericObjectPool#getEvictionPolicy()
|
||||
* @see GenericKeyedObjectPool#getEvictionPolicy()
|
||||
* @since 2.6.0
|
||||
*/
|
||||
public void setEvictionPolicy(final EvictionPolicy<T> evictionPolicy) {
|
||||
this.evictionPolicy = evictionPolicy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value for the {@code evictionPolicyClassName} configuration
|
||||
* attribute for pools created with this configuration instance.
|
||||
*
|
||||
* @param evictionPolicyClassName The new setting of
|
||||
* {@code evictionPolicyClassName} for this configuration instance
|
||||
*
|
||||
* @see GenericObjectPool#getEvictionPolicyClassName()
|
||||
* @see GenericKeyedObjectPool#getEvictionPolicyClassName()
|
||||
*/
|
||||
public void setEvictionPolicyClassName(final String evictionPolicyClassName) {
|
||||
this.evictionPolicyClassName = evictionPolicyClassName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value for the {@code blockWhenExhausted} configuration attribute
|
||||
* for pools created with this configuration instance.
|
||||
*
|
||||
* @return The current setting of {@code blockWhenExhausted} for this
|
||||
* configuration instance
|
||||
*
|
||||
* @see GenericObjectPool#getBlockWhenExhausted()
|
||||
* @see GenericKeyedObjectPool#getBlockWhenExhausted()
|
||||
*/
|
||||
public boolean getBlockWhenExhausted() {
|
||||
return blockWhenExhausted;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value for the {@code blockWhenExhausted} configuration attribute
|
||||
* for pools created with this configuration instance.
|
||||
*
|
||||
* @param blockWhenExhausted The new setting of {@code blockWhenExhausted}
|
||||
* for this configuration instance
|
||||
*
|
||||
* @see GenericObjectPool#getBlockWhenExhausted()
|
||||
* @see GenericKeyedObjectPool#getBlockWhenExhausted()
|
||||
*/
|
||||
public void setBlockWhenExhausted(final boolean blockWhenExhausted) {
|
||||
this.blockWhenExhausted = blockWhenExhausted;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the flag that determines if JMX will be enabled for
|
||||
* pools created with this configuration instance.
|
||||
*
|
||||
* @return The current setting of {@code jmxEnabled} for this configuration
|
||||
* instance
|
||||
*/
|
||||
public boolean getJmxEnabled() {
|
||||
return jmxEnabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the flag that determines if JMX will be enabled for
|
||||
* pools created with this configuration instance.
|
||||
*
|
||||
* @param jmxEnabled The new setting of {@code jmxEnabled}
|
||||
* for this configuration instance
|
||||
*/
|
||||
public void setJmxEnabled(final boolean jmxEnabled) {
|
||||
this.jmxEnabled = jmxEnabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the JMX name base that will be used as part of the
|
||||
* name assigned to JMX enabled pools created with this configuration
|
||||
* instance. A value of <code>null</code> means that the pool will define
|
||||
* the JMX name base.
|
||||
*
|
||||
* @return The current setting of {@code jmxNameBase} for this
|
||||
* configuration instance
|
||||
*/
|
||||
public String getJmxNameBase() {
|
||||
return jmxNameBase;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the JMX name base that will be used as part of the
|
||||
* name assigned to JMX enabled pools created with this configuration
|
||||
* instance. A value of <code>null</code> means that the pool will define
|
||||
* the JMX name base.
|
||||
*
|
||||
* @param jmxNameBase The new setting of {@code jmxNameBase}
|
||||
* for this configuration instance
|
||||
*/
|
||||
public void setJmxNameBase(final String jmxNameBase) {
|
||||
this.jmxNameBase = jmxNameBase;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the JMX name prefix that will be used as part of the
|
||||
* name assigned to JMX enabled pools created with this configuration
|
||||
* instance.
|
||||
*
|
||||
* @return The current setting of {@code jmxNamePrefix} for this
|
||||
* configuration instance
|
||||
*/
|
||||
public String getJmxNamePrefix() {
|
||||
return jmxNamePrefix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the JMX name prefix that will be used as part of the
|
||||
* name assigned to JMX enabled pools created with this configuration
|
||||
* instance.
|
||||
*
|
||||
* @param jmxNamePrefix The new setting of {@code jmxNamePrefix}
|
||||
* for this configuration instance
|
||||
*/
|
||||
public void setJmxNamePrefix(final String jmxNamePrefix) {
|
||||
this.jmxNamePrefix = jmxNamePrefix;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void toStringAppendFields(final StringBuilder builder) {
|
||||
builder.append("lifo=");
|
||||
builder.append(lifo);
|
||||
builder.append(", fairness=");
|
||||
builder.append(fairness);
|
||||
builder.append(", maxWaitMillis=");
|
||||
builder.append(maxWaitMillis);
|
||||
builder.append(", minEvictableIdleTimeMillis=");
|
||||
builder.append(minEvictableIdleTimeMillis);
|
||||
builder.append(", softMinEvictableIdleTimeMillis=");
|
||||
builder.append(softMinEvictableIdleTimeMillis);
|
||||
builder.append(", numTestsPerEvictionRun=");
|
||||
builder.append(numTestsPerEvictionRun);
|
||||
builder.append(", evictionPolicyClassName=");
|
||||
builder.append(evictionPolicyClassName);
|
||||
builder.append(", testOnCreate=");
|
||||
builder.append(testOnCreate);
|
||||
builder.append(", testOnBorrow=");
|
||||
builder.append(testOnBorrow);
|
||||
builder.append(", testOnReturn=");
|
||||
builder.append(testOnReturn);
|
||||
builder.append(", testWhileIdle=");
|
||||
builder.append(testWhileIdle);
|
||||
builder.append(", timeBetweenEvictionRunsMillis=");
|
||||
builder.append(timeBetweenEvictionRunsMillis);
|
||||
builder.append(", blockWhenExhausted=");
|
||||
builder.append(blockWhenExhausted);
|
||||
builder.append(", jmxEnabled=");
|
||||
builder.append(jmxEnabled);
|
||||
builder.append(", jmxNamePrefix=");
|
||||
builder.append(jmxNamePrefix);
|
||||
builder.append(", jmxNameBase=");
|
||||
builder.append(jmxNameBase);
|
||||
}
|
||||
}
|
||||
52
java/org/apache/tomcat/dbcp/pool2/impl/CallStack.java
Normal file
52
java/org/apache/tomcat/dbcp/pool2/impl/CallStack.java
Normal file
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* 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.impl;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
|
||||
/**
|
||||
* Strategy for obtaining and printing the current call stack. This is primarily useful for
|
||||
* {@link org.apache.tomcat.dbcp.pool2.UsageTracking usage tracking} so
|
||||
* that different JVMs and configurations can use more efficient strategies
|
||||
* for obtaining the current call stack depending on metadata needs.
|
||||
*
|
||||
* @see CallStackUtils
|
||||
* @since 2.4.3
|
||||
*/
|
||||
public interface CallStack {
|
||||
|
||||
/**
|
||||
* Prints the current stack trace if available to a PrintWriter. The format is undefined and is primarily useful
|
||||
* for debugging issues with {@link org.apache.tomcat.dbcp.pool2.PooledObject} usage in user code.
|
||||
*
|
||||
* @param writer a PrintWriter to write the current stack trace to if available
|
||||
* @return true if a stack trace was available to print or false if nothing was printed
|
||||
*/
|
||||
boolean printStackTrace(final PrintWriter writer);
|
||||
|
||||
/**
|
||||
* Takes a snapshot of the current call stack. Subsequent calls to {@link #printStackTrace(PrintWriter)} will print
|
||||
* out that stack trace until it is {@linkplain #clear() cleared}.
|
||||
*/
|
||||
void fillInStackTrace();
|
||||
|
||||
/**
|
||||
* Clears the current stack trace snapshot. Subsequent calls to {@link #printStackTrace(PrintWriter)} will be
|
||||
* no-ops until another call to {@link #fillInStackTrace()}.
|
||||
*/
|
||||
void clear();
|
||||
}
|
||||
85
java/org/apache/tomcat/dbcp/pool2/impl/CallStackUtils.java
Normal file
85
java/org/apache/tomcat/dbcp/pool2/impl/CallStackUtils.java
Normal file
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* 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.impl;
|
||||
|
||||
import java.security.AccessControlException;
|
||||
|
||||
/**
|
||||
* Utility methods for {@link CallStack}.
|
||||
*
|
||||
* @since 2.4.3
|
||||
*/
|
||||
public final class CallStackUtils {
|
||||
|
||||
/**
|
||||
* Returns whether the caller can create a security manager in the current environment.
|
||||
*
|
||||
* @return {@code true} if it is able to create a security manager in the current environment, {@code false}
|
||||
* otherwise.
|
||||
*/
|
||||
private static boolean canCreateSecurityManager() {
|
||||
final SecurityManager manager = System.getSecurityManager();
|
||||
if (manager == null) {
|
||||
return true;
|
||||
}
|
||||
try {
|
||||
manager.checkPermission(new RuntimePermission("createSecurityManager"));
|
||||
return true;
|
||||
} catch (final AccessControlException ignored) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@link CallStack} using the fastest allowed strategy.
|
||||
*
|
||||
* @param messageFormat message (or format) to print first in stack traces
|
||||
* @param useTimestamp if true, interpret message as a SimpleDateFormat and print the created timestamp; otherwise,
|
||||
* print message format literally
|
||||
* @return a new CallStack
|
||||
* @deprecated use {@link #newCallStack(String, boolean, boolean)}
|
||||
*/
|
||||
@Deprecated
|
||||
public static CallStack newCallStack(final String messageFormat, final boolean useTimestamp) {
|
||||
return newCallStack(messageFormat, useTimestamp, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@link CallStack} using the fasted allowed strategy.
|
||||
*
|
||||
* @param messageFormat message (or format) to print first in stack traces
|
||||
* @param useTimestamp if true, interpret message as a SimpleDateFormat and print the created timestamp;
|
||||
* otherwise, print message format literally
|
||||
* @param requireFullStackTrace if true, forces the use of a stack walking mechanism that includes full stack trace
|
||||
* information; otherwise, uses a faster implementation if possible
|
||||
* @return a new CallStack
|
||||
* @since 2.5
|
||||
*/
|
||||
public static CallStack newCallStack(final String messageFormat,
|
||||
final boolean useTimestamp,
|
||||
final boolean requireFullStackTrace) {
|
||||
return canCreateSecurityManager() && !requireFullStackTrace
|
||||
? new SecurityManagerCallStack(messageFormat, useTimestamp)
|
||||
: new ThrowableCallStack(messageFormat, useTimestamp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Hidden constructor.
|
||||
*/
|
||||
private CallStackUtils() {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* 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.impl;
|
||||
|
||||
import org.apache.tomcat.dbcp.pool2.PooledObject;
|
||||
|
||||
/**
|
||||
* Provides the default implementation of {@link EvictionPolicy} used by the
|
||||
* pools. Objects will be evicted if the following conditions are met:
|
||||
* <ul>
|
||||
* <li>the object has been idle longer than
|
||||
* {@link GenericObjectPool#getMinEvictableIdleTimeMillis()} /
|
||||
* {@link GenericKeyedObjectPool#getMinEvictableIdleTimeMillis()}</li>
|
||||
* <li>there are more than {@link GenericObjectPool#getMinIdle()} /
|
||||
* {@link GenericKeyedObjectPoolConfig#getMinIdlePerKey()} idle objects in
|
||||
* the pool and the object has been idle for longer than
|
||||
* {@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
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public class DefaultEvictionPolicy<T> implements EvictionPolicy<T> {
|
||||
|
||||
@Override
|
||||
public boolean evict(final EvictionConfig config, final PooledObject<T> underTest,
|
||||
final int idleCount) {
|
||||
|
||||
if ((config.getIdleSoftEvictTime() < underTest.getIdleTimeMillis() &&
|
||||
config.getMinIdle() < idleCount) ||
|
||||
config.getIdleEvictTime() < underTest.getIdleTimeMillis()) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
298
java/org/apache/tomcat/dbcp/pool2/impl/DefaultPooledObject.java
Normal file
298
java/org/apache/tomcat/dbcp/pool2/impl/DefaultPooledObject.java
Normal file
@@ -0,0 +1,298 @@
|
||||
/*
|
||||
* 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.impl;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.util.Deque;
|
||||
|
||||
import org.apache.tomcat.dbcp.pool2.PooledObject;
|
||||
import org.apache.tomcat.dbcp.pool2.PooledObjectState;
|
||||
import org.apache.tomcat.dbcp.pool2.TrackedUse;
|
||||
|
||||
/**
|
||||
* This wrapper is used to track the additional information, such as state, for
|
||||
* the pooled objects.
|
||||
* <p>
|
||||
* This class is intended to be thread-safe.
|
||||
* </p>
|
||||
*
|
||||
* @param <T> the type of object in the pool
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public class DefaultPooledObject<T> implements PooledObject<T> {
|
||||
|
||||
private final T object;
|
||||
private PooledObjectState state = PooledObjectState.IDLE; // @GuardedBy("this") to ensure transitions are valid
|
||||
private final long createTime = System.currentTimeMillis();
|
||||
private volatile long lastBorrowTime = createTime;
|
||||
private volatile long lastUseTime = createTime;
|
||||
private volatile long lastReturnTime = createTime;
|
||||
private volatile boolean logAbandoned = false;
|
||||
private volatile CallStack borrowedBy = NoOpCallStack.INSTANCE;
|
||||
private volatile CallStack usedBy = NoOpCallStack.INSTANCE;
|
||||
private volatile long borrowedCount = 0;
|
||||
|
||||
/**
|
||||
* Creates a new instance that wraps the provided object so that the pool can
|
||||
* track the state of the pooled object.
|
||||
*
|
||||
* @param object The object to wrap
|
||||
*/
|
||||
public DefaultPooledObject(final T object) {
|
||||
this.object = object;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T getObject() {
|
||||
return object;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getCreateTime() {
|
||||
return createTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getActiveTimeMillis() {
|
||||
// Take copies to avoid threading issues
|
||||
final long rTime = lastReturnTime;
|
||||
final long bTime = lastBorrowTime;
|
||||
|
||||
if (rTime > bTime) {
|
||||
return rTime - bTime;
|
||||
}
|
||||
return System.currentTimeMillis() - bTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getIdleTimeMillis() {
|
||||
final long elapsed = System.currentTimeMillis() - lastReturnTime;
|
||||
// elapsed may be negative if:
|
||||
// - another thread updates lastReturnTime during the calculation window
|
||||
// - System.currentTimeMillis() is not monotonic (e.g. system time is set back)
|
||||
return elapsed >= 0 ? elapsed : 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getLastBorrowTime() {
|
||||
return lastBorrowTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getLastReturnTime() {
|
||||
return lastReturnTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the number of times this object has been borrowed.
|
||||
* @return The number of times this object has been borrowed.
|
||||
* @since 2.1
|
||||
*/
|
||||
@Override
|
||||
public long getBorrowedCount() {
|
||||
return borrowedCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an estimate of the last time this object was used. If the class
|
||||
* of the pooled object implements {@link TrackedUse}, what is returned is
|
||||
* the maximum of {@link TrackedUse#getLastUsed()} and
|
||||
* {@link #getLastBorrowTime()}; otherwise this method gives the same
|
||||
* value as {@link #getLastBorrowTime()}.
|
||||
*
|
||||
* @return the last time this object was used
|
||||
*/
|
||||
@Override
|
||||
public long getLastUsedTime() {
|
||||
if (object instanceof TrackedUse) {
|
||||
return Math.max(((TrackedUse) object).getLastUsed(), lastUseTime);
|
||||
}
|
||||
return lastUseTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(final PooledObject<T> other) {
|
||||
final long lastActiveDiff = this.getLastReturnTime() - other.getLastReturnTime();
|
||||
if (lastActiveDiff == 0) {
|
||||
// Make sure the natural ordering is broadly consistent with equals
|
||||
// although this will break down if distinct objects have the same
|
||||
// identity hash code.
|
||||
// see java.lang.Comparable Javadocs
|
||||
return System.identityHashCode(this) - System.identityHashCode(other);
|
||||
}
|
||||
// handle int overflow
|
||||
return (int)Math.min(Math.max(lastActiveDiff, Integer.MIN_VALUE), Integer.MAX_VALUE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
final StringBuilder result = new StringBuilder();
|
||||
result.append("Object: ");
|
||||
result.append(object.toString());
|
||||
result.append(", State: ");
|
||||
synchronized (this) {
|
||||
result.append(state.toString());
|
||||
}
|
||||
return result.toString();
|
||||
// TODO add other attributes
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean startEvictionTest() {
|
||||
if (state == PooledObjectState.IDLE) {
|
||||
state = PooledObjectState.EVICTION;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean endEvictionTest(
|
||||
final Deque<PooledObject<T>> idleQueue) {
|
||||
if (state == PooledObjectState.EVICTION) {
|
||||
state = PooledObjectState.IDLE;
|
||||
return true;
|
||||
} else if (state == PooledObjectState.EVICTION_RETURN_TO_HEAD) {
|
||||
state = PooledObjectState.IDLE;
|
||||
if (!idleQueue.offerFirst(this)) {
|
||||
// TODO - Should never happen
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocates the object.
|
||||
*
|
||||
* @return {@code true} if the original state was {@link PooledObjectState#IDLE IDLE}
|
||||
*/
|
||||
@Override
|
||||
public synchronized boolean allocate() {
|
||||
if (state == PooledObjectState.IDLE) {
|
||||
state = PooledObjectState.ALLOCATED;
|
||||
lastBorrowTime = System.currentTimeMillis();
|
||||
lastUseTime = lastBorrowTime;
|
||||
borrowedCount++;
|
||||
if (logAbandoned) {
|
||||
borrowedBy.fillInStackTrace();
|
||||
}
|
||||
return true;
|
||||
} else if (state == PooledObjectState.EVICTION) {
|
||||
// TODO Allocate anyway and ignore eviction test
|
||||
state = PooledObjectState.EVICTION_RETURN_TO_HEAD;
|
||||
return false;
|
||||
}
|
||||
// TODO if validating and testOnBorrow == true then pre-allocate for
|
||||
// performance
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deallocates the object and sets it {@link PooledObjectState#IDLE IDLE}
|
||||
* if it is currently {@link PooledObjectState#ALLOCATED ALLOCATED}.
|
||||
*
|
||||
* @return {@code true} if the state was {@link PooledObjectState#ALLOCATED ALLOCATED}
|
||||
*/
|
||||
@Override
|
||||
public synchronized boolean deallocate() {
|
||||
if (state == PooledObjectState.ALLOCATED ||
|
||||
state == PooledObjectState.RETURNING) {
|
||||
state = PooledObjectState.IDLE;
|
||||
lastReturnTime = System.currentTimeMillis();
|
||||
borrowedBy.clear();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the state to {@link PooledObjectState#INVALID INVALID}
|
||||
*/
|
||||
@Override
|
||||
public synchronized void invalidate() {
|
||||
state = PooledObjectState.INVALID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void use() {
|
||||
lastUseTime = System.currentTimeMillis();
|
||||
usedBy.fillInStackTrace();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void printStackTrace(final PrintWriter writer) {
|
||||
boolean written = borrowedBy.printStackTrace(writer);
|
||||
written |= usedBy.printStackTrace(writer);
|
||||
if (written) {
|
||||
writer.flush();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the state of this object.
|
||||
* @return state
|
||||
*/
|
||||
@Override
|
||||
public synchronized PooledObjectState getState() {
|
||||
return state;
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks the pooled object as abandoned.
|
||||
*/
|
||||
@Override
|
||||
public synchronized void markAbandoned() {
|
||||
state = PooledObjectState.ABANDONED;
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks the object as returning to the pool.
|
||||
*/
|
||||
@Override
|
||||
public synchronized void markReturning() {
|
||||
state = PooledObjectState.RETURNING;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLogAbandoned(final boolean logAbandoned) {
|
||||
this.logAbandoned = logAbandoned;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures the stack trace generation strategy based on whether or not fully
|
||||
* detailed stack traces are required. When set to false, abandoned logs may
|
||||
* only include caller class information rather than method names, line numbers,
|
||||
* and other normal metadata available in a full stack trace.
|
||||
*
|
||||
* @param requireFullStackTrace the new configuration setting for abandoned object
|
||||
* logging
|
||||
* @since 2.5
|
||||
*/
|
||||
@Override
|
||||
public void setRequireFullStackTrace(final boolean requireFullStackTrace) {
|
||||
borrowedBy = CallStackUtils.newCallStack("'Pooled object created' " +
|
||||
"yyyy-MM-dd HH:mm:ss Z 'by the following code has not been returned to the pool:'",
|
||||
true, requireFullStackTrace);
|
||||
usedBy = CallStackUtils.newCallStack("The last code to use this object was:",
|
||||
false, requireFullStackTrace);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* 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.impl;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.text.SimpleDateFormat;
|
||||
|
||||
import org.apache.tomcat.dbcp.pool2.PooledObject;
|
||||
|
||||
/**
|
||||
* Implementation of object that is used to provide information on pooled
|
||||
* objects via JMX.
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public class DefaultPooledObjectInfo implements DefaultPooledObjectInfoMBean {
|
||||
|
||||
private final PooledObject<?> pooledObject;
|
||||
|
||||
/**
|
||||
* Create a new instance for the given pooled object.
|
||||
*
|
||||
* @param pooledObject The pooled object that this instance will represent
|
||||
*/
|
||||
public DefaultPooledObjectInfo(final PooledObject<?> pooledObject) {
|
||||
this.pooledObject = pooledObject;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getCreateTime() {
|
||||
return pooledObject.getCreateTime();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCreateTimeFormatted() {
|
||||
final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z");
|
||||
return sdf.format(Long.valueOf(pooledObject.getCreateTime()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getLastBorrowTime() {
|
||||
return pooledObject.getLastBorrowTime();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLastBorrowTimeFormatted() {
|
||||
final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z");
|
||||
return sdf.format(Long.valueOf(pooledObject.getLastBorrowTime()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLastBorrowTrace() {
|
||||
final StringWriter sw = new StringWriter();
|
||||
pooledObject.printStackTrace(new PrintWriter(sw));
|
||||
return sw.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getLastReturnTime() {
|
||||
return pooledObject.getLastReturnTime();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLastReturnTimeFormatted() {
|
||||
final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z");
|
||||
return sdf.format(Long.valueOf(pooledObject.getLastReturnTime()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPooledObjectType() {
|
||||
return pooledObject.getObject().getClass().getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPooledObjectToString() {
|
||||
return pooledObject.getObject().toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getBorrowedCount() {
|
||||
return pooledObject.getBorrowedCount();
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.4.3
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
final StringBuilder builder = new StringBuilder();
|
||||
builder.append("DefaultPooledObjectInfo [pooledObject=");
|
||||
builder.append(pooledObject);
|
||||
builder.append("]");
|
||||
return builder.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
* 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.impl;
|
||||
|
||||
/**
|
||||
* The interface that defines the information about pooled objects that will be
|
||||
* exposed via JMX.
|
||||
*
|
||||
* NOTE: This interface exists only to define those attributes and methods that
|
||||
* will be made available via JMX. It must not be implemented by clients
|
||||
* as it is subject to change between major, minor and patch version
|
||||
* releases of commons pool. Clients that implement this interface may
|
||||
* not, therefore, be able to upgrade to a new minor or patch release
|
||||
* without requiring code changes.
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public interface DefaultPooledObjectInfoMBean {
|
||||
/**
|
||||
* Obtain the time (using the same basis as
|
||||
* {@link System#currentTimeMillis()}) that pooled object was created.
|
||||
*
|
||||
* @return The creation time for the pooled object
|
||||
*/
|
||||
long getCreateTime();
|
||||
|
||||
/**
|
||||
* Obtain the time that pooled object was created.
|
||||
*
|
||||
* @return The creation time for the pooled object formatted as
|
||||
* <code>yyyy-MM-dd HH:mm:ss Z</code>
|
||||
*/
|
||||
String getCreateTimeFormatted();
|
||||
|
||||
/**
|
||||
* Obtain the time (using the same basis as
|
||||
* {@link System#currentTimeMillis()}) the polled object was last borrowed.
|
||||
*
|
||||
* @return The time the pooled object was last borrowed
|
||||
*/
|
||||
long getLastBorrowTime();
|
||||
|
||||
/**
|
||||
* Obtain the time that pooled object was last borrowed.
|
||||
*
|
||||
* @return The last borrowed time for the pooled object formated as
|
||||
* <code>yyyy-MM-dd HH:mm:ss Z</code>
|
||||
*/
|
||||
String getLastBorrowTimeFormatted();
|
||||
|
||||
/**
|
||||
* Obtain the stack trace recorded when the pooled object was last borrowed.
|
||||
*
|
||||
* @return The stack trace showing which code last borrowed the pooled
|
||||
* object
|
||||
*/
|
||||
String getLastBorrowTrace();
|
||||
|
||||
|
||||
/**
|
||||
* Obtain the time (using the same basis as
|
||||
* {@link System#currentTimeMillis()})the wrapped object was last returned.
|
||||
*
|
||||
* @return The time the object was last returned
|
||||
*/
|
||||
long getLastReturnTime();
|
||||
|
||||
/**
|
||||
* Obtain the time that pooled object was last returned.
|
||||
*
|
||||
* @return The last returned time for the pooled object formated as
|
||||
* <code>yyyy-MM-dd HH:mm:ss Z</code>
|
||||
*/
|
||||
String getLastReturnTimeFormatted();
|
||||
|
||||
/**
|
||||
* Obtain the name of the class of the pooled object.
|
||||
*
|
||||
* @return The pooled object's class name
|
||||
*
|
||||
* @see Class#getName()
|
||||
*/
|
||||
String getPooledObjectType();
|
||||
|
||||
/**
|
||||
* Provides a String form of the wrapper for debug purposes. The format is
|
||||
* not fixed and may change at any time.
|
||||
*
|
||||
* @return A string representation of the pooled object
|
||||
*
|
||||
* @see Object#toString()
|
||||
*/
|
||||
String getPooledObjectToString();
|
||||
|
||||
/**
|
||||
* Get the number of times this object has been borrowed.
|
||||
* @return The number of times this object has been borrowed.
|
||||
* @since 2.1
|
||||
*/
|
||||
long getBorrowedCount();
|
||||
}
|
||||
115
java/org/apache/tomcat/dbcp/pool2/impl/EvictionConfig.java
Normal file
115
java/org/apache/tomcat/dbcp/pool2/impl/EvictionConfig.java
Normal file
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
* 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.impl;
|
||||
|
||||
/**
|
||||
* This class is used by pool implementations to pass configuration information
|
||||
* to {@link EvictionPolicy} instances. The {@link EvictionPolicy} may also have
|
||||
* its own specific configuration attributes.
|
||||
* <p>
|
||||
* This class is immutable and thread-safe.
|
||||
* </p>
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public class EvictionConfig {
|
||||
|
||||
private final long idleEvictTime;
|
||||
private final long idleSoftEvictTime;
|
||||
private final int minIdle;
|
||||
|
||||
/**
|
||||
* Create a new eviction configuration with the specified parameters.
|
||||
* Instances are immutable.
|
||||
*
|
||||
* @param poolIdleEvictTime Expected to be provided by
|
||||
* {@link BaseGenericObjectPool#getMinEvictableIdleTimeMillis()}
|
||||
* @param poolIdleSoftEvictTime Expected to be provided by
|
||||
* {@link BaseGenericObjectPool#getSoftMinEvictableIdleTimeMillis()}
|
||||
* @param minIdle Expected to be provided by
|
||||
* {@link GenericObjectPool#getMinIdle()} or
|
||||
* {@link GenericKeyedObjectPool#getMinIdlePerKey()}
|
||||
*/
|
||||
public EvictionConfig(final long poolIdleEvictTime, final long poolIdleSoftEvictTime,
|
||||
final int minIdle) {
|
||||
if (poolIdleEvictTime > 0) {
|
||||
idleEvictTime = poolIdleEvictTime;
|
||||
} else {
|
||||
idleEvictTime = Long.MAX_VALUE;
|
||||
}
|
||||
if (poolIdleSoftEvictTime > 0) {
|
||||
idleSoftEvictTime = poolIdleSoftEvictTime;
|
||||
} else {
|
||||
idleSoftEvictTime = Long.MAX_VALUE;
|
||||
}
|
||||
this.minIdle = minIdle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtain the {@code idleEvictTime} for this eviction configuration
|
||||
* instance.
|
||||
* <p>
|
||||
* How the evictor behaves based on this value will be determined by the
|
||||
* configured {@link EvictionPolicy}.
|
||||
*
|
||||
* @return The {@code idleEvictTime} in milliseconds
|
||||
*/
|
||||
public long getIdleEvictTime() {
|
||||
return idleEvictTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtain the {@code idleSoftEvictTime} for this eviction configuration
|
||||
* instance.
|
||||
* <p>
|
||||
* How the evictor behaves based on this value will be determined by the
|
||||
* configured {@link EvictionPolicy}.
|
||||
*
|
||||
* @return The (@code idleSoftEvictTime} in milliseconds
|
||||
*/
|
||||
public long getIdleSoftEvictTime() {
|
||||
return idleSoftEvictTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtain the {@code minIdle} for this eviction configuration instance.
|
||||
* <p>
|
||||
* How the evictor behaves based on this value will be determined by the
|
||||
* configured {@link EvictionPolicy}.
|
||||
*
|
||||
* @return The {@code minIdle}
|
||||
*/
|
||||
public int getMinIdle() {
|
||||
return minIdle;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.4
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
final StringBuilder builder = new StringBuilder();
|
||||
builder.append("EvictionConfig [idleEvictTime=");
|
||||
builder.append(idleEvictTime);
|
||||
builder.append(", idleSoftEvictTime=");
|
||||
builder.append(idleSoftEvictTime);
|
||||
builder.append(", minIdle=");
|
||||
builder.append(minIdle);
|
||||
builder.append("]");
|
||||
return builder.toString();
|
||||
}
|
||||
}
|
||||
44
java/org/apache/tomcat/dbcp/pool2/impl/EvictionPolicy.java
Normal file
44
java/org/apache/tomcat/dbcp/pool2/impl/EvictionPolicy.java
Normal file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* 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.impl;
|
||||
|
||||
import org.apache.tomcat.dbcp.pool2.PooledObject;
|
||||
|
||||
/**
|
||||
* To provide a custom eviction policy (i.e. something other than {@link
|
||||
* DefaultEvictionPolicy} for a pool, users must provide an implementation of
|
||||
* this interface that provides the required eviction policy.
|
||||
*
|
||||
* @param <T> the type of objects in the pool
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public interface EvictionPolicy<T> {
|
||||
|
||||
/**
|
||||
* This method is called to test if an idle object in the pool should be
|
||||
* evicted or not.
|
||||
*
|
||||
* @param config The pool configuration settings related to eviction
|
||||
* @param underTest The pooled object being tested for eviction
|
||||
* @param idleCount The current number of idle objects in the pool including
|
||||
* the object under test
|
||||
* @return <code>true</code> if the object should be evicted, otherwise
|
||||
* <code>false</code>
|
||||
*/
|
||||
boolean evict(EvictionConfig config, PooledObject<T> underTest, int idleCount);
|
||||
}
|
||||
134
java/org/apache/tomcat/dbcp/pool2/impl/EvictionTimer.java
Normal file
134
java/org/apache/tomcat/dbcp/pool2/impl/EvictionTimer.java
Normal file
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
* 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.impl;
|
||||
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.ScheduledThreadPoolExecutor;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* Provides a shared idle object eviction timer for all pools.
|
||||
* <p>
|
||||
* This class is currently implemented using {@link ScheduledThreadPoolExecutor}. This implementation may change in any
|
||||
* future release. This class keeps track of how many pools are using it. If no pools are using the timer, it is
|
||||
* cancelled. This prevents a thread being left running which, in application server environments, can lead to memory
|
||||
* leads and/or prevent applications from shutting down or reloading cleanly.
|
||||
* </p>
|
||||
* <p>
|
||||
* This class has package scope to prevent its inclusion in the pool public API. The class declaration below should
|
||||
* *not* be changed to public.
|
||||
* </p>
|
||||
* <p>
|
||||
* This class is intended to be thread-safe.
|
||||
* </p>
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
class EvictionTimer {
|
||||
|
||||
/** Executor instance */
|
||||
private static ScheduledThreadPoolExecutor executor; //@GuardedBy("EvictionTimer.class")
|
||||
|
||||
/** Prevents instantiation */
|
||||
private EvictionTimer() {
|
||||
// Hide the default constructor
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @since 2.4.3
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
final StringBuilder builder = new StringBuilder();
|
||||
builder.append("EvictionTimer []");
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Adds the specified eviction task to the timer. Tasks that are added with a
|
||||
* call to this method *must* call {@link #cancel(BaseGenericObjectPool.Evictor,long,TimeUnit)}
|
||||
* to cancel the task to prevent memory and/or thread leaks in application
|
||||
* server environments.
|
||||
*
|
||||
* @param task Task to be scheduled.
|
||||
* @param delay Delay in milliseconds before task is executed.
|
||||
* @param period Time in milliseconds between executions.
|
||||
*/
|
||||
static synchronized void schedule(
|
||||
final BaseGenericObjectPool<?>.Evictor task, final long delay, final long period) {
|
||||
if (null == executor) {
|
||||
executor = new ScheduledThreadPoolExecutor(1, new EvictorThreadFactory());
|
||||
executor.setRemoveOnCancelPolicy(true);
|
||||
}
|
||||
final ScheduledFuture<?> scheduledFuture =
|
||||
executor.scheduleWithFixedDelay(task, delay, period, TimeUnit.MILLISECONDS);
|
||||
task.setScheduledFuture(scheduledFuture);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the specified eviction task from the timer.
|
||||
*
|
||||
* @param evictor Task to be cancelled.
|
||||
* @param timeout If the associated executor is no longer required, how
|
||||
* long should this thread wait for the executor to
|
||||
* terminate?
|
||||
* @param unit The units for the specified timeout.
|
||||
*/
|
||||
static synchronized void cancel(
|
||||
final BaseGenericObjectPool<?>.Evictor evictor, final long timeout, final TimeUnit unit) {
|
||||
if (evictor != null) {
|
||||
evictor.cancel();
|
||||
}
|
||||
if (executor != null && executor.getQueue().isEmpty()) {
|
||||
executor.shutdown();
|
||||
try {
|
||||
executor.awaitTermination(timeout, unit);
|
||||
} catch (final InterruptedException e) {
|
||||
// Swallow
|
||||
// Significant API changes would be required to propagate this
|
||||
}
|
||||
executor.setCorePoolSize(0);
|
||||
executor = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Thread factory that creates a daemon thread, with the context class loader from this class.
|
||||
*/
|
||||
private static class EvictorThreadFactory implements ThreadFactory {
|
||||
|
||||
@Override
|
||||
public Thread newThread(final Runnable runnable) {
|
||||
final Thread thread = new Thread(null, runnable, "commons-pool-evictor-thread");
|
||||
thread.setDaemon(true); // POOL-363 - Required for applications using Runtime.addShutdownHook().
|
||||
AccessController.doPrivileged(new PrivilegedAction<Void>() {
|
||||
@Override
|
||||
public Void run() {
|
||||
thread.setContextClassLoader(EvictorThreadFactory.class.getClassLoader());
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
return thread;
|
||||
}
|
||||
}
|
||||
}
|
||||
1680
java/org/apache/tomcat/dbcp/pool2/impl/GenericKeyedObjectPool.java
Normal file
1680
java/org/apache/tomcat/dbcp/pool2/impl/GenericKeyedObjectPool.java
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,198 @@
|
||||
/*
|
||||
* 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.impl;
|
||||
|
||||
/**
|
||||
* A simple "struct" encapsulating the configuration for a
|
||||
* {@link GenericKeyedObjectPool}.
|
||||
*
|
||||
* <p>
|
||||
* This class is not thread-safe; it is only intended to be used to provide
|
||||
* attributes used when creating a pool.
|
||||
* </p>
|
||||
*
|
||||
* @param <T> Type of element pooled.
|
||||
* @since 2.0
|
||||
*/
|
||||
public class GenericKeyedObjectPoolConfig<T> extends BaseObjectPoolConfig<T> {
|
||||
|
||||
/**
|
||||
* The default value for the {@code maxTotalPerKey} configuration attribute.
|
||||
* @see GenericKeyedObjectPool#getMaxTotalPerKey()
|
||||
*/
|
||||
public static final int DEFAULT_MAX_TOTAL_PER_KEY = 8;
|
||||
|
||||
/**
|
||||
* The default value for the {@code maxTotal} configuration attribute.
|
||||
* @see GenericKeyedObjectPool#getMaxTotal()
|
||||
*/
|
||||
public static final int DEFAULT_MAX_TOTAL = -1;
|
||||
|
||||
/**
|
||||
* The default value for the {@code minIdlePerKey} configuration attribute.
|
||||
* @see GenericKeyedObjectPool#getMinIdlePerKey()
|
||||
*/
|
||||
public static final int DEFAULT_MIN_IDLE_PER_KEY = 0;
|
||||
|
||||
/**
|
||||
* The default value for the {@code maxIdlePerKey} configuration attribute.
|
||||
* @see GenericKeyedObjectPool#getMaxIdlePerKey()
|
||||
*/
|
||||
public static final int DEFAULT_MAX_IDLE_PER_KEY = 8;
|
||||
|
||||
|
||||
private int minIdlePerKey = DEFAULT_MIN_IDLE_PER_KEY;
|
||||
|
||||
private int maxIdlePerKey = DEFAULT_MAX_IDLE_PER_KEY;
|
||||
|
||||
private int maxTotalPerKey = DEFAULT_MAX_TOTAL_PER_KEY;
|
||||
|
||||
private int maxTotal = DEFAULT_MAX_TOTAL;
|
||||
|
||||
/**
|
||||
* Create a new configuration with default settings.
|
||||
*/
|
||||
public GenericKeyedObjectPoolConfig() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value for the {@code maxTotal} configuration attribute
|
||||
* for pools created with this configuration instance.
|
||||
*
|
||||
* @return The current setting of {@code maxTotal} for this
|
||||
* configuration instance
|
||||
*
|
||||
* @see GenericKeyedObjectPool#getMaxTotal()
|
||||
*/
|
||||
public int getMaxTotal() {
|
||||
return maxTotal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value for the {@code maxTotal} configuration attribute for
|
||||
* pools created with this configuration instance.
|
||||
*
|
||||
* @param maxTotal The new setting of {@code maxTotal}
|
||||
* for this configuration instance
|
||||
*
|
||||
* @see GenericKeyedObjectPool#setMaxTotal(int)
|
||||
*/
|
||||
public void setMaxTotal(final int maxTotal) {
|
||||
this.maxTotal = maxTotal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value for the {@code maxTotalPerKey} configuration attribute
|
||||
* for pools created with this configuration instance.
|
||||
*
|
||||
* @return The current setting of {@code maxTotalPerKey} for this
|
||||
* configuration instance
|
||||
*
|
||||
* @see GenericKeyedObjectPool#getMaxTotalPerKey()
|
||||
*/
|
||||
public int getMaxTotalPerKey() {
|
||||
return maxTotalPerKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value for the {@code maxTotalPerKey} configuration attribute for
|
||||
* pools created with this configuration instance.
|
||||
*
|
||||
* @param maxTotalPerKey The new setting of {@code maxTotalPerKey}
|
||||
* for this configuration instance
|
||||
*
|
||||
* @see GenericKeyedObjectPool#setMaxTotalPerKey(int)
|
||||
*/
|
||||
public void setMaxTotalPerKey(final int maxTotalPerKey) {
|
||||
this.maxTotalPerKey = maxTotalPerKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value for the {@code minIdlePerKey} configuration attribute
|
||||
* for pools created with this configuration instance.
|
||||
*
|
||||
* @return The current setting of {@code minIdlePerKey} for this
|
||||
* configuration instance
|
||||
*
|
||||
* @see GenericKeyedObjectPool#getMinIdlePerKey()
|
||||
*/
|
||||
public int getMinIdlePerKey() {
|
||||
return minIdlePerKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value for the {@code minIdlePerKey} configuration attribute for
|
||||
* pools created with this configuration instance.
|
||||
*
|
||||
* @param minIdlePerKey The new setting of {@code minIdlePerKey}
|
||||
* for this configuration instance
|
||||
*
|
||||
* @see GenericKeyedObjectPool#setMinIdlePerKey(int)
|
||||
*/
|
||||
public void setMinIdlePerKey(final int minIdlePerKey) {
|
||||
this.minIdlePerKey = minIdlePerKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value for the {@code maxIdlePerKey} configuration attribute
|
||||
* for pools created with this configuration instance.
|
||||
*
|
||||
* @return The current setting of {@code maxIdlePerKey} for this
|
||||
* configuration instance
|
||||
*
|
||||
* @see GenericKeyedObjectPool#getMaxIdlePerKey()
|
||||
*/
|
||||
public int getMaxIdlePerKey() {
|
||||
return maxIdlePerKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value for the {@code maxIdlePerKey} configuration attribute for
|
||||
* pools created with this configuration instance.
|
||||
*
|
||||
* @param maxIdlePerKey The new setting of {@code maxIdlePerKey}
|
||||
* for this configuration instance
|
||||
*
|
||||
* @see GenericKeyedObjectPool#setMaxIdlePerKey(int)
|
||||
*/
|
||||
public void setMaxIdlePerKey(final int maxIdlePerKey) {
|
||||
this.maxIdlePerKey = maxIdlePerKey;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public GenericKeyedObjectPoolConfig<T> clone() {
|
||||
try {
|
||||
return (GenericKeyedObjectPoolConfig<T>) super.clone();
|
||||
} catch (final CloneNotSupportedException e) {
|
||||
throw new AssertionError(); // Can't happen
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void toStringAppendFields(final StringBuilder builder) {
|
||||
super.toStringAppendFields(builder);
|
||||
builder.append(", minIdlePerKey=");
|
||||
builder.append(minIdlePerKey);
|
||||
builder.append(", maxIdlePerKey=");
|
||||
builder.append(maxIdlePerKey);
|
||||
builder.append(", maxTotalPerKey=");
|
||||
builder.append(maxTotalPerKey);
|
||||
builder.append(", maxTotal=");
|
||||
builder.append(maxTotal);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,240 @@
|
||||
/*
|
||||
* 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.impl;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Defines the methods that will be made available via JMX.
|
||||
*
|
||||
* NOTE: This interface exists only to define those attributes and methods that
|
||||
* will be made available via JMX. It must not be implemented by clients
|
||||
* as it is subject to change between major, minor and patch version
|
||||
* releases of commons pool. Clients that implement this interface may
|
||||
* not, therefore, be able to upgrade to a new minor or patch release
|
||||
* without requiring code changes.
|
||||
*
|
||||
* @param <K> The type of keys maintained by the pool.
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public interface GenericKeyedObjectPoolMXBean<K> {
|
||||
|
||||
// Expose getters for configuration settings
|
||||
|
||||
/**
|
||||
* See {@link GenericKeyedObjectPool#getBlockWhenExhausted()}
|
||||
* @return See {@link GenericKeyedObjectPool#getBlockWhenExhausted()}
|
||||
*/
|
||||
boolean getBlockWhenExhausted();
|
||||
|
||||
/**
|
||||
* See {@link GenericKeyedObjectPool#getFairness()}
|
||||
* @return See {@link GenericKeyedObjectPool#getFairness()}
|
||||
*/
|
||||
boolean getFairness();
|
||||
|
||||
/**
|
||||
* See {@link GenericKeyedObjectPool#getLifo()}
|
||||
* @return See {@link GenericKeyedObjectPool#getLifo()}
|
||||
*/
|
||||
boolean getLifo();
|
||||
|
||||
/**
|
||||
* See {@link GenericKeyedObjectPool#getMaxIdlePerKey()}
|
||||
* @return See {@link GenericKeyedObjectPool#getMaxIdlePerKey()}
|
||||
*/
|
||||
int getMaxIdlePerKey();
|
||||
|
||||
/**
|
||||
* See {@link GenericKeyedObjectPool#getMaxTotal()}
|
||||
* @return See {@link GenericKeyedObjectPool#getMaxTotal()}
|
||||
*/
|
||||
int getMaxTotal();
|
||||
|
||||
/**
|
||||
* See {@link GenericKeyedObjectPool#getMaxTotalPerKey()}
|
||||
* @return See {@link GenericKeyedObjectPool#getMaxTotalPerKey()}
|
||||
*/
|
||||
int getMaxTotalPerKey();
|
||||
|
||||
/**
|
||||
* See {@link GenericKeyedObjectPool#getMaxWaitMillis()}
|
||||
* @return See {@link GenericKeyedObjectPool#getMaxWaitMillis()}
|
||||
*/
|
||||
long getMaxWaitMillis();
|
||||
|
||||
/**
|
||||
* See {@link GenericKeyedObjectPool#getMinEvictableIdleTimeMillis()}
|
||||
* @return See {@link GenericKeyedObjectPool#getMinEvictableIdleTimeMillis()}
|
||||
*/
|
||||
long getMinEvictableIdleTimeMillis();
|
||||
|
||||
/**
|
||||
* See {@link GenericKeyedObjectPool#getMinIdlePerKey()}
|
||||
* @return See {@link GenericKeyedObjectPool#getMinIdlePerKey()}
|
||||
*/
|
||||
int getMinIdlePerKey();
|
||||
|
||||
/**
|
||||
* See {@link GenericKeyedObjectPool#getNumActive()}
|
||||
* @return See {@link GenericKeyedObjectPool#getNumActive()}
|
||||
*/
|
||||
int getNumActive();
|
||||
|
||||
/**
|
||||
* See {@link GenericKeyedObjectPool#getNumIdle()}
|
||||
* @return See {@link GenericKeyedObjectPool#getNumIdle()}
|
||||
*/
|
||||
int getNumIdle();
|
||||
|
||||
/**
|
||||
* See {@link GenericKeyedObjectPool#getNumTestsPerEvictionRun()}
|
||||
* @return See {@link GenericKeyedObjectPool#getNumTestsPerEvictionRun()}
|
||||
*/
|
||||
int getNumTestsPerEvictionRun();
|
||||
|
||||
/**
|
||||
* See {@link GenericKeyedObjectPool#getTestOnCreate()}
|
||||
* @return See {@link GenericKeyedObjectPool#getTestOnCreate()}
|
||||
* @since 2.2
|
||||
*/
|
||||
boolean getTestOnCreate();
|
||||
|
||||
/**
|
||||
* See {@link GenericKeyedObjectPool#getTestOnBorrow()}
|
||||
* @return See {@link GenericKeyedObjectPool#getTestOnBorrow()}
|
||||
*/
|
||||
boolean getTestOnBorrow();
|
||||
|
||||
/**
|
||||
* See {@link GenericKeyedObjectPool#getTestOnReturn()}
|
||||
* @return See {@link GenericKeyedObjectPool#getTestOnReturn()}
|
||||
*/
|
||||
boolean getTestOnReturn();
|
||||
|
||||
/**
|
||||
* See {@link GenericKeyedObjectPool#getTestWhileIdle()}
|
||||
* @return See {@link GenericKeyedObjectPool#getTestWhileIdle()}
|
||||
*/
|
||||
boolean getTestWhileIdle();
|
||||
|
||||
/**
|
||||
* See {@link GenericKeyedObjectPool#getTimeBetweenEvictionRunsMillis()}
|
||||
* @return See {@link GenericKeyedObjectPool#getTimeBetweenEvictionRunsMillis()}
|
||||
*/
|
||||
long getTimeBetweenEvictionRunsMillis();
|
||||
|
||||
/**
|
||||
* See {@link GenericKeyedObjectPool#isClosed()}
|
||||
* @return See {@link GenericKeyedObjectPool#isClosed()}
|
||||
*/
|
||||
boolean isClosed();
|
||||
|
||||
// Expose getters for monitoring attributes
|
||||
|
||||
/**
|
||||
* See {@link GenericKeyedObjectPool#getNumActivePerKey()}
|
||||
* @return See {@link GenericKeyedObjectPool#getNumActivePerKey()}
|
||||
*/
|
||||
Map<String,Integer> getNumActivePerKey();
|
||||
|
||||
/**
|
||||
* See {@link GenericKeyedObjectPool#getBorrowedCount()}
|
||||
* @return See {@link GenericKeyedObjectPool#getBorrowedCount()}
|
||||
*/
|
||||
long getBorrowedCount();
|
||||
|
||||
/**
|
||||
* See {@link GenericKeyedObjectPool#getReturnedCount()}
|
||||
* @return See {@link GenericKeyedObjectPool#getReturnedCount()}
|
||||
*/
|
||||
long getReturnedCount();
|
||||
|
||||
/**
|
||||
* See {@link GenericKeyedObjectPool#getCreatedCount()}
|
||||
* @return See {@link GenericKeyedObjectPool#getCreatedCount()}
|
||||
*/
|
||||
long getCreatedCount();
|
||||
|
||||
/**
|
||||
* See {@link GenericKeyedObjectPool#getDestroyedCount()}
|
||||
* @return See {@link GenericKeyedObjectPool#getDestroyedCount()}
|
||||
*/
|
||||
long getDestroyedCount();
|
||||
|
||||
/**
|
||||
* See {@link GenericKeyedObjectPool#getDestroyedByEvictorCount()}
|
||||
* @return See {@link GenericKeyedObjectPool#getDestroyedByEvictorCount()}
|
||||
*/
|
||||
long getDestroyedByEvictorCount();
|
||||
|
||||
/**
|
||||
* See {@link GenericKeyedObjectPool#getDestroyedByBorrowValidationCount()}
|
||||
* @return See {@link GenericKeyedObjectPool#getDestroyedByBorrowValidationCount()}
|
||||
*/
|
||||
long getDestroyedByBorrowValidationCount();
|
||||
|
||||
/**
|
||||
* See {@link GenericKeyedObjectPool#getMeanActiveTimeMillis()}
|
||||
* @return See {@link GenericKeyedObjectPool#getMeanActiveTimeMillis()}
|
||||
*/
|
||||
long getMeanActiveTimeMillis();
|
||||
|
||||
/**
|
||||
* See {@link GenericKeyedObjectPool#getMeanIdleTimeMillis()}
|
||||
* @return See {@link GenericKeyedObjectPool#getMeanIdleTimeMillis()}
|
||||
*/
|
||||
long getMeanIdleTimeMillis();
|
||||
|
||||
/**
|
||||
* See {@link GenericKeyedObjectPool#getMaxBorrowWaitTimeMillis()}
|
||||
* @return See {@link GenericKeyedObjectPool#getMaxBorrowWaitTimeMillis()}
|
||||
*/
|
||||
long getMeanBorrowWaitTimeMillis();
|
||||
|
||||
/**
|
||||
* See {@link GenericKeyedObjectPool#getMaxBorrowWaitTimeMillis()}
|
||||
* @return See {@link GenericKeyedObjectPool#getMaxBorrowWaitTimeMillis()}
|
||||
*/
|
||||
long getMaxBorrowWaitTimeMillis();
|
||||
|
||||
/**
|
||||
* See {@link GenericKeyedObjectPool#getCreationStackTrace()}
|
||||
* @return See {@link GenericKeyedObjectPool#getCreationStackTrace()}
|
||||
*/
|
||||
String getCreationStackTrace();
|
||||
|
||||
/**
|
||||
* See {@link GenericKeyedObjectPool#getNumWaiters()}
|
||||
* @return See {@link GenericKeyedObjectPool#getNumWaiters()}
|
||||
*/
|
||||
int getNumWaiters();
|
||||
|
||||
/**
|
||||
* See {@link GenericKeyedObjectPool#getNumWaitersByKey()}
|
||||
* @return See {@link GenericKeyedObjectPool#getNumWaitersByKey()}
|
||||
*/
|
||||
Map<String,Integer> getNumWaitersByKey();
|
||||
|
||||
/**
|
||||
* See {@link GenericKeyedObjectPool#listAllObjects()}
|
||||
* @return See {@link GenericKeyedObjectPool#listAllObjects()}
|
||||
*/
|
||||
Map<String,List<DefaultPooledObjectInfo>> listAllObjects();
|
||||
}
|
||||
1234
java/org/apache/tomcat/dbcp/pool2/impl/GenericObjectPool.java
Normal file
1234
java/org/apache/tomcat/dbcp/pool2/impl/GenericObjectPool.java
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,158 @@
|
||||
/*
|
||||
* 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.impl;
|
||||
|
||||
/**
|
||||
* A simple "struct" encapsulating the configuration for a
|
||||
* {@link GenericObjectPool}.
|
||||
*
|
||||
* <p>
|
||||
* This class is not thread-safe; it is only intended to be used to provide
|
||||
* attributes used when creating a pool.
|
||||
* </p>
|
||||
*
|
||||
* @param <T> Type of element pooled.
|
||||
* @since 2.0
|
||||
*/
|
||||
public class GenericObjectPoolConfig<T> extends BaseObjectPoolConfig<T> {
|
||||
|
||||
/**
|
||||
* The default value for the {@code maxTotal} configuration attribute.
|
||||
* @see GenericObjectPool#getMaxTotal()
|
||||
*/
|
||||
public static final int DEFAULT_MAX_TOTAL = 8;
|
||||
|
||||
/**
|
||||
* The default value for the {@code maxIdle} configuration attribute.
|
||||
* @see GenericObjectPool#getMaxIdle()
|
||||
*/
|
||||
public static final int DEFAULT_MAX_IDLE = 8;
|
||||
|
||||
/**
|
||||
* The default value for the {@code minIdle} configuration attribute.
|
||||
* @see GenericObjectPool#getMinIdle()
|
||||
*/
|
||||
public static final int DEFAULT_MIN_IDLE = 0;
|
||||
|
||||
|
||||
private int maxTotal = DEFAULT_MAX_TOTAL;
|
||||
|
||||
private int maxIdle = DEFAULT_MAX_IDLE;
|
||||
|
||||
private int minIdle = DEFAULT_MIN_IDLE;
|
||||
|
||||
/**
|
||||
* Get the value for the {@code maxTotal} configuration attribute
|
||||
* for pools created with this configuration instance.
|
||||
*
|
||||
* @return The current setting of {@code maxTotal} for this
|
||||
* configuration instance
|
||||
*
|
||||
* @see GenericObjectPool#getMaxTotal()
|
||||
*/
|
||||
public int getMaxTotal() {
|
||||
return maxTotal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value for the {@code maxTotal} configuration attribute for
|
||||
* pools created with this configuration instance.
|
||||
*
|
||||
* @param maxTotal The new setting of {@code maxTotal}
|
||||
* for this configuration instance
|
||||
*
|
||||
* @see GenericObjectPool#setMaxTotal(int)
|
||||
*/
|
||||
public void setMaxTotal(final int maxTotal) {
|
||||
this.maxTotal = maxTotal;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the value for the {@code maxIdle} configuration attribute
|
||||
* for pools created with this configuration instance.
|
||||
*
|
||||
* @return The current setting of {@code maxIdle} for this
|
||||
* configuration instance
|
||||
*
|
||||
* @see GenericObjectPool#getMaxIdle()
|
||||
*/
|
||||
public int getMaxIdle() {
|
||||
return maxIdle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value for the {@code maxIdle} configuration attribute for
|
||||
* pools created with this configuration instance.
|
||||
*
|
||||
* @param maxIdle The new setting of {@code maxIdle}
|
||||
* for this configuration instance
|
||||
*
|
||||
* @see GenericObjectPool#setMaxIdle(int)
|
||||
*/
|
||||
public void setMaxIdle(final int maxIdle) {
|
||||
this.maxIdle = maxIdle;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the value for the {@code minIdle} configuration attribute
|
||||
* for pools created with this configuration instance.
|
||||
*
|
||||
* @return The current setting of {@code minIdle} for this
|
||||
* configuration instance
|
||||
*
|
||||
* @see GenericObjectPool#getMinIdle()
|
||||
*/
|
||||
public int getMinIdle() {
|
||||
return minIdle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value for the {@code minIdle} configuration attribute for
|
||||
* pools created with this configuration instance.
|
||||
*
|
||||
* @param minIdle The new setting of {@code minIdle}
|
||||
* for this configuration instance
|
||||
*
|
||||
* @see GenericObjectPool#setMinIdle(int)
|
||||
*/
|
||||
public void setMinIdle(final int minIdle) {
|
||||
this.minIdle = minIdle;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public GenericObjectPoolConfig<T> clone() {
|
||||
try {
|
||||
return (GenericObjectPoolConfig<T>) super.clone();
|
||||
} catch (final CloneNotSupportedException e) {
|
||||
throw new AssertionError(); // Can't happen
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void toStringAppendFields(final StringBuilder builder) {
|
||||
super.toStringAppendFields(builder);
|
||||
builder.append(", maxTotal=");
|
||||
builder.append(maxTotal);
|
||||
builder.append(", maxIdle=");
|
||||
builder.append(maxIdle);
|
||||
builder.append(", minIdle=");
|
||||
builder.append(minIdle);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,257 @@
|
||||
/*
|
||||
* 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.impl;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Defines the methods that will be made available via JMX.
|
||||
*
|
||||
* NOTE: This interface exists only to define those attributes and methods that
|
||||
* will be made available via JMX. It must not be implemented by clients
|
||||
* as it is subject to change between major, minor and patch version
|
||||
* releases of commons pool. Clients that implement this interface may
|
||||
* not, therefore, be able to upgrade to a new minor or patch release
|
||||
* without requiring code changes.
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public interface GenericObjectPoolMXBean {
|
||||
|
||||
// Getters for basic configuration settings
|
||||
|
||||
/**
|
||||
* See {@link GenericObjectPool#getBlockWhenExhausted()}
|
||||
* @return See {@link GenericObjectPool#getBlockWhenExhausted()}
|
||||
*/
|
||||
boolean getBlockWhenExhausted();
|
||||
|
||||
/**
|
||||
* See {@link GenericObjectPool#getLifo()}
|
||||
* @return See {@link GenericObjectPool#getLifo()}
|
||||
*/
|
||||
boolean getFairness();
|
||||
|
||||
/**
|
||||
* See {@link GenericObjectPool#getFairness()}
|
||||
* @return See {@link GenericObjectPool#getFairness()}
|
||||
*/
|
||||
boolean getLifo();
|
||||
|
||||
/**
|
||||
* See {@link GenericObjectPool#getMaxIdle()}
|
||||
* @return See {@link GenericObjectPool#getMaxIdle()}
|
||||
*/
|
||||
int getMaxIdle();
|
||||
|
||||
/**
|
||||
* See {@link GenericObjectPool#getMaxTotal()}
|
||||
* @return See {@link GenericObjectPool#getMaxTotal()}
|
||||
*/
|
||||
int getMaxTotal();
|
||||
|
||||
/**
|
||||
* See {@link GenericObjectPool#getMaxWaitMillis()}
|
||||
* @return See {@link GenericObjectPool#getMaxWaitMillis()}
|
||||
*/
|
||||
long getMaxWaitMillis();
|
||||
|
||||
/**
|
||||
* See {@link GenericObjectPool#getMinEvictableIdleTimeMillis()}
|
||||
* @return See {@link GenericObjectPool#getMinEvictableIdleTimeMillis()}
|
||||
*/
|
||||
long getMinEvictableIdleTimeMillis();
|
||||
|
||||
/**
|
||||
* See {@link GenericObjectPool#getMinIdle()}
|
||||
* @return See {@link GenericObjectPool#getMinIdle()}
|
||||
*/
|
||||
int getMinIdle();
|
||||
|
||||
/**
|
||||
* See {@link GenericObjectPool#getNumActive()}
|
||||
* @return See {@link GenericObjectPool#getNumActive()}
|
||||
*/
|
||||
int getNumActive();
|
||||
|
||||
/**
|
||||
* See {@link GenericObjectPool#getNumIdle()}
|
||||
* @return See {@link GenericObjectPool#getNumIdle()}
|
||||
*/
|
||||
int getNumIdle();
|
||||
|
||||
/**
|
||||
* See {@link GenericObjectPool#getNumTestsPerEvictionRun()}
|
||||
* @return See {@link GenericObjectPool#getNumTestsPerEvictionRun()}
|
||||
*/
|
||||
int getNumTestsPerEvictionRun();
|
||||
|
||||
/**
|
||||
* See {@link GenericObjectPool#getTestOnCreate()}
|
||||
* @return See {@link GenericObjectPool#getTestOnCreate()}
|
||||
* @since 2.2
|
||||
*/
|
||||
boolean getTestOnCreate();
|
||||
|
||||
/**
|
||||
* See {@link GenericObjectPool#getTestOnBorrow()}
|
||||
* @return See {@link GenericObjectPool#getTestOnBorrow()}
|
||||
*/
|
||||
boolean getTestOnBorrow();
|
||||
|
||||
/**
|
||||
* See {@link GenericObjectPool#getTestOnReturn()}
|
||||
* @return See {@link GenericObjectPool#getTestOnReturn()}
|
||||
*/
|
||||
boolean getTestOnReturn();
|
||||
|
||||
/**
|
||||
* See {@link GenericObjectPool#getTestWhileIdle()}
|
||||
* @return See {@link GenericObjectPool#getTestWhileIdle()}
|
||||
*/
|
||||
boolean getTestWhileIdle();
|
||||
|
||||
/**
|
||||
* See {@link GenericObjectPool#getTimeBetweenEvictionRunsMillis()}
|
||||
* @return See {@link GenericObjectPool#getTimeBetweenEvictionRunsMillis()}
|
||||
*/
|
||||
long getTimeBetweenEvictionRunsMillis();
|
||||
|
||||
/**
|
||||
* See {@link GenericObjectPool#isClosed()}
|
||||
* @return See {@link GenericObjectPool#isClosed()}
|
||||
*/
|
||||
boolean isClosed();
|
||||
|
||||
// Getters for monitoring attributes
|
||||
|
||||
/**
|
||||
* See {@link GenericObjectPool#getBorrowedCount()}
|
||||
* @return See {@link GenericObjectPool#getBorrowedCount()}
|
||||
*/
|
||||
long getBorrowedCount();
|
||||
|
||||
/**
|
||||
* See {@link GenericObjectPool#getReturnedCount()}
|
||||
* @return See {@link GenericObjectPool#getReturnedCount()}
|
||||
*/
|
||||
long getReturnedCount();
|
||||
|
||||
/**
|
||||
* See {@link GenericObjectPool#getCreatedCount()}
|
||||
* @return See {@link GenericObjectPool#getCreatedCount()}
|
||||
*/
|
||||
long getCreatedCount();
|
||||
|
||||
/**
|
||||
* See {@link GenericObjectPool#getDestroyedCount()}
|
||||
* @return See {@link GenericObjectPool#getDestroyedCount()}
|
||||
*/
|
||||
long getDestroyedCount();
|
||||
|
||||
/**
|
||||
* See {@link GenericObjectPool#getDestroyedByEvictorCount()}
|
||||
* @return See {@link GenericObjectPool#getDestroyedByEvictorCount()}
|
||||
*/
|
||||
long getDestroyedByEvictorCount();
|
||||
|
||||
/**
|
||||
* See {@link GenericObjectPool#getDestroyedByBorrowValidationCount()}
|
||||
* @return See {@link GenericObjectPool#getDestroyedByBorrowValidationCount()}
|
||||
*/
|
||||
long getDestroyedByBorrowValidationCount();
|
||||
|
||||
/**
|
||||
* See {@link GenericObjectPool#getMeanActiveTimeMillis()}
|
||||
* @return See {@link GenericObjectPool#getMeanActiveTimeMillis()}
|
||||
*/
|
||||
long getMeanActiveTimeMillis();
|
||||
|
||||
/**
|
||||
* See {@link GenericObjectPool#getMeanIdleTimeMillis()}
|
||||
* @return See {@link GenericObjectPool#getMeanIdleTimeMillis()}
|
||||
*/
|
||||
long getMeanIdleTimeMillis();
|
||||
|
||||
/**
|
||||
* See {@link GenericObjectPool#getMeanBorrowWaitTimeMillis()}
|
||||
* @return See {@link GenericObjectPool#getMeanBorrowWaitTimeMillis()}
|
||||
*/
|
||||
long getMeanBorrowWaitTimeMillis();
|
||||
|
||||
/**
|
||||
* See {@link GenericObjectPool#getMaxBorrowWaitTimeMillis()}
|
||||
* @return See {@link GenericObjectPool#getMaxBorrowWaitTimeMillis()}
|
||||
*/
|
||||
long getMaxBorrowWaitTimeMillis();
|
||||
|
||||
/**
|
||||
* See {@link GenericObjectPool#getCreationStackTrace()}
|
||||
* @return See {@link GenericObjectPool#getCreationStackTrace()}
|
||||
*/
|
||||
String getCreationStackTrace();
|
||||
|
||||
/**
|
||||
* See {@link GenericObjectPool#getNumWaiters()}
|
||||
* @return See {@link GenericObjectPool#getNumWaiters()}
|
||||
*/
|
||||
int getNumWaiters();
|
||||
|
||||
// Getters for abandoned object removal configuration
|
||||
|
||||
/**
|
||||
* See {@link GenericObjectPool#isAbandonedConfig()}
|
||||
* @return See {@link GenericObjectPool#isAbandonedConfig()}
|
||||
*/
|
||||
boolean isAbandonedConfig();
|
||||
|
||||
/**
|
||||
* See {@link GenericObjectPool#getLogAbandoned()}
|
||||
* @return See {@link GenericObjectPool#getLogAbandoned()}
|
||||
*/
|
||||
boolean getLogAbandoned();
|
||||
|
||||
/**
|
||||
* See {@link GenericObjectPool#getRemoveAbandonedOnBorrow()}
|
||||
* @return See {@link GenericObjectPool#getRemoveAbandonedOnBorrow()}
|
||||
*/
|
||||
boolean getRemoveAbandonedOnBorrow();
|
||||
|
||||
/**
|
||||
* See {@link GenericObjectPool#getRemoveAbandonedOnMaintenance()}
|
||||
* @return See {@link GenericObjectPool#getRemoveAbandonedOnMaintenance()}
|
||||
*/
|
||||
boolean getRemoveAbandonedOnMaintenance();
|
||||
|
||||
/**
|
||||
* See {@link GenericObjectPool#getRemoveAbandonedTimeout()}
|
||||
* @return See {@link GenericObjectPool#getRemoveAbandonedTimeout()}
|
||||
*/
|
||||
int getRemoveAbandonedTimeout();
|
||||
|
||||
/**
|
||||
* See {@link GenericObjectPool#getFactoryType()}
|
||||
* @return See {@link GenericObjectPool#getFactoryType()}
|
||||
*/
|
||||
String getFactoryType();
|
||||
|
||||
/**
|
||||
* See {@link GenericObjectPool#listAllObjects()}
|
||||
* @return See {@link GenericObjectPool#listAllObjects()}
|
||||
*/
|
||||
Set<DefaultPooledObjectInfo> listAllObjects();
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* 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.impl;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.concurrent.locks.Condition;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
/**
|
||||
* This sub-class was created to expose the waiting threads so that they can be
|
||||
* interrupted when the pool using the queue that uses this lock is closed. The
|
||||
* class is intended for internal use only.
|
||||
* <p>
|
||||
* This class is intended to be thread-safe.
|
||||
* </p>
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
class InterruptibleReentrantLock extends ReentrantLock {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* Create a new InterruptibleReentrantLock with the given fairness policy.
|
||||
*
|
||||
* @param fairness true means threads should acquire contended locks as if
|
||||
* waiting in a FIFO queue
|
||||
*/
|
||||
public InterruptibleReentrantLock(final boolean fairness) {
|
||||
super(fairness);
|
||||
}
|
||||
|
||||
/**
|
||||
* Interrupt the threads that are waiting on a specific condition
|
||||
*
|
||||
* @param condition the condition on which the threads are waiting.
|
||||
*/
|
||||
public void interruptWaiters(final Condition condition) {
|
||||
final Collection<Thread> threads = getWaitingThreads(condition);
|
||||
for (final Thread thread : threads) {
|
||||
thread.interrupt();
|
||||
}
|
||||
}
|
||||
}
|
||||
1427
java/org/apache/tomcat/dbcp/pool2/impl/LinkedBlockingDeque.java
Normal file
1427
java/org/apache/tomcat/dbcp/pool2/impl/LinkedBlockingDeque.java
Normal file
File diff suppressed because it is too large
Load Diff
54
java/org/apache/tomcat/dbcp/pool2/impl/NoOpCallStack.java
Normal file
54
java/org/apache/tomcat/dbcp/pool2/impl/NoOpCallStack.java
Normal file
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* 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.impl;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
|
||||
/**
|
||||
* CallStack strategy using no-op implementations of all functionality. Can be used by default when abandoned object
|
||||
* logging is disabled.
|
||||
*
|
||||
* @since 2.5
|
||||
*/
|
||||
public class NoOpCallStack implements CallStack {
|
||||
|
||||
/**
|
||||
* Singleton instance.
|
||||
*/
|
||||
public static final CallStack INSTANCE = new NoOpCallStack();
|
||||
|
||||
/**
|
||||
* Constructs the singleton instance.
|
||||
*/
|
||||
private NoOpCallStack() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean printStackTrace(final PrintWriter writer) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fillInStackTrace() {
|
||||
// no-op
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
// no-op
|
||||
}
|
||||
}
|
||||
156
java/org/apache/tomcat/dbcp/pool2/impl/PoolImplUtils.java
Normal file
156
java/org/apache/tomcat/dbcp/pool2/impl/PoolImplUtils.java
Normal file
@@ -0,0 +1,156 @@
|
||||
/*
|
||||
* 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.impl;
|
||||
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
import java.lang.reflect.TypeVariable;
|
||||
|
||||
import org.apache.tomcat.dbcp.pool2.PooledObjectFactory;
|
||||
|
||||
/**
|
||||
* Implementation specific utilities.
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
class PoolImplUtils {
|
||||
|
||||
/**
|
||||
* Identifies the concrete type of object that an object factory creates.
|
||||
*
|
||||
* @param factoryClass
|
||||
* The factory to examine
|
||||
*
|
||||
* @return the type of object the factory creates
|
||||
*/
|
||||
@SuppressWarnings("rawtypes")
|
||||
static Class<?> getFactoryType(final Class<? extends PooledObjectFactory> factoryClass) {
|
||||
final Class<PooledObjectFactory> type = PooledObjectFactory.class;
|
||||
final Object genericType = getGenericType(type, factoryClass);
|
||||
if (genericType instanceof Integer) {
|
||||
// POOL-324 org.apache.commons.pool2.impl.GenericObjectPool.getFactoryType() throws
|
||||
// java.lang.ClassCastException
|
||||
//
|
||||
// A bit hackish, but we must handle cases when getGenericType() does not return a concrete types.
|
||||
final ParameterizedType pi = getParameterizedType(type, factoryClass);
|
||||
if (pi != null) {
|
||||
final Type[] bounds = ((TypeVariable) pi.getActualTypeArguments()[((Integer) genericType).intValue()]).getBounds();
|
||||
if (bounds != null && bounds.length > 0) {
|
||||
final Type bound0 = bounds[0];
|
||||
if (bound0 instanceof Class) {
|
||||
return (Class<?>) bound0;
|
||||
}
|
||||
}
|
||||
}
|
||||
// last resort: Always return a Class
|
||||
return Object.class;
|
||||
}
|
||||
return (Class<?>) genericType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtains the concrete type used by an implementation of an interface that uses a generic type.
|
||||
*
|
||||
* @param type
|
||||
* The interface that defines a generic type
|
||||
* @param clazz
|
||||
* The class that implements the interface with a concrete type
|
||||
* @param <T>
|
||||
* The interface type
|
||||
*
|
||||
* @return concrete type used by the implementation
|
||||
*/
|
||||
private static <T> Object getGenericType(final Class<T> type, final Class<? extends T> clazz) {
|
||||
if (type == null || clazz == null) {
|
||||
// Error will be logged further up the call stack
|
||||
return null;
|
||||
}
|
||||
|
||||
// Look to see if this class implements the generic interface
|
||||
final ParameterizedType pi = getParameterizedType(type, clazz);
|
||||
if (pi != null) {
|
||||
return getTypeParameter(clazz, pi.getActualTypeArguments()[0]);
|
||||
}
|
||||
|
||||
// Interface not found on this class. Look at the superclass.
|
||||
@SuppressWarnings("unchecked")
|
||||
final Class<? extends T> superClass = (Class<? extends T>) clazz.getSuperclass();
|
||||
|
||||
final Object result = getGenericType(type, superClass);
|
||||
if (result instanceof Class<?>) {
|
||||
// Superclass implements interface and defines explicit type for generic
|
||||
return result;
|
||||
} else if (result instanceof Integer) {
|
||||
// Superclass implements interface and defines unknown type for generic
|
||||
// Map that unknown type to the generic types defined in this class
|
||||
final ParameterizedType superClassType = (ParameterizedType) clazz.getGenericSuperclass();
|
||||
return getTypeParameter(clazz, superClassType.getActualTypeArguments()[((Integer) result).intValue()]);
|
||||
} else {
|
||||
// Error will be logged further up the call stack
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the matching parameterized type or null.
|
||||
* @param type
|
||||
* The interface that defines a generic type.
|
||||
* @param clazz
|
||||
* The class that implements the interface with a concrete type.
|
||||
* @param <T>
|
||||
* The interface type.
|
||||
* @return the matching parameterized type or null.
|
||||
*/
|
||||
private static <T> ParameterizedType getParameterizedType(final Class<T> type, final Class<? extends T> clazz) {
|
||||
for (final Type iface : clazz.getGenericInterfaces()) {
|
||||
// Only need to check interfaces that use generics
|
||||
if (iface instanceof ParameterizedType) {
|
||||
final ParameterizedType pi = (ParameterizedType) iface;
|
||||
// Look for the generic interface
|
||||
if (pi.getRawType() instanceof Class && type.isAssignableFrom((Class<?>) pi.getRawType())) {
|
||||
return pi;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* For a generic parameter, return either the Class used or if the type is unknown, the index for the type in
|
||||
* definition of the class
|
||||
*
|
||||
* @param clazz
|
||||
* defining class
|
||||
* @param argType
|
||||
* the type argument of interest
|
||||
*
|
||||
* @return An instance of {@link Class} representing the type used by the type parameter or an instance of
|
||||
* {@link Integer} representing the index for the type in the definition of the defining class
|
||||
*/
|
||||
private static Object getTypeParameter(final Class<?> clazz, final Type argType) {
|
||||
if (argType instanceof Class<?>) {
|
||||
return argType;
|
||||
}
|
||||
final TypeVariable<?>[] tvs = clazz.getTypeParameters();
|
||||
for (int i = 0; i < tvs.length; i++) {
|
||||
if (tvs[i].equals(argType)) {
|
||||
return Integer.valueOf(i);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* 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.impl;
|
||||
|
||||
import java.lang.ref.SoftReference;
|
||||
|
||||
/**
|
||||
* Extension of {@link DefaultPooledObject} to wrap pooled soft references.
|
||||
*
|
||||
* <p>This class is intended to be thread-safe.</p>
|
||||
*
|
||||
* @param <T> the type of the underlying object that the wrapped SoftReference
|
||||
* refers to.
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public class PooledSoftReference<T> extends DefaultPooledObject<T> {
|
||||
|
||||
/** SoftReference wrapped by this object */
|
||||
private volatile SoftReference<T> reference;
|
||||
|
||||
/**
|
||||
* Creates a new PooledSoftReference wrapping the provided reference.
|
||||
*
|
||||
* @param reference SoftReference to be managed by the pool
|
||||
*/
|
||||
public PooledSoftReference(final SoftReference<T> reference) {
|
||||
super(null); // Null the hard reference in the parent
|
||||
this.reference = reference;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the object that the wrapped SoftReference refers to.
|
||||
* <p>
|
||||
* Note that if the reference has been cleared, this method will return
|
||||
* null.
|
||||
*
|
||||
* @return Object referred to by the SoftReference
|
||||
*/
|
||||
@Override
|
||||
public T getObject() {
|
||||
return reference.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
final StringBuilder result = new StringBuilder();
|
||||
result.append("Referenced Object: ");
|
||||
result.append(getObject().toString());
|
||||
result.append(", State: ");
|
||||
synchronized (this) {
|
||||
result.append(getState().toString());
|
||||
}
|
||||
return result.toString();
|
||||
// TODO add other attributes
|
||||
// TODO encapsulate state and other attribute display in parent
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the SoftReference wrapped by this object.
|
||||
*
|
||||
* @return underlying SoftReference
|
||||
*/
|
||||
public synchronized SoftReference<T> getReference() {
|
||||
return reference;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the wrapped reference.
|
||||
*
|
||||
* <p>This method exists to allow a new, non-registered reference to be
|
||||
* held by the pool to track objects that have been checked out of the pool.
|
||||
* The actual parameter <strong>should</strong> be a reference to the same
|
||||
* object that {@link #getObject()} returns before calling this method.</p>
|
||||
*
|
||||
* @param reference new reference
|
||||
*/
|
||||
public synchronized void setReference(final SoftReference<T> reference) {
|
||||
this.reference = reference;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
* 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.impl;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* CallStack strategy using a {@link SecurityManager}. Obtaining the current call stack is much faster via a
|
||||
* SecurityManger, but access to the underlying method may be restricted by the current SecurityManager. In environments
|
||||
* where a SecurityManager cannot be created, {@link ThrowableCallStack} should be used instead.
|
||||
*
|
||||
* @see RuntimePermission
|
||||
* @see SecurityManager#getClassContext()
|
||||
* @since 2.4.3
|
||||
*/
|
||||
public class SecurityManagerCallStack implements CallStack {
|
||||
|
||||
private final String messageFormat;
|
||||
//@GuardedBy("dateFormat")
|
||||
private final DateFormat dateFormat;
|
||||
private final PrivateSecurityManager securityManager;
|
||||
|
||||
private volatile Snapshot snapshot;
|
||||
|
||||
/**
|
||||
* Create a new instance.
|
||||
*
|
||||
* @param messageFormat message format
|
||||
* @param useTimestamp whether to format the dates in the output message or not
|
||||
*/
|
||||
public SecurityManagerCallStack(final String messageFormat, final boolean useTimestamp) {
|
||||
this.messageFormat = messageFormat;
|
||||
this.dateFormat = useTimestamp ? new SimpleDateFormat(messageFormat) : null;
|
||||
this.securityManager = AccessController.doPrivileged(new PrivilegedAction<PrivateSecurityManager>() {
|
||||
@Override
|
||||
public PrivateSecurityManager run() {
|
||||
return new PrivateSecurityManager();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean printStackTrace(final PrintWriter writer) {
|
||||
final Snapshot snapshotRef = this.snapshot;
|
||||
if (snapshotRef == null) {
|
||||
return false;
|
||||
}
|
||||
final String message;
|
||||
if (dateFormat == null) {
|
||||
message = messageFormat;
|
||||
} else {
|
||||
synchronized (dateFormat) {
|
||||
message = dateFormat.format(Long.valueOf(snapshotRef.timestamp));
|
||||
}
|
||||
}
|
||||
writer.println(message);
|
||||
for (final WeakReference<Class<?>> reference : snapshotRef.stack) {
|
||||
writer.println(reference.get());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fillInStackTrace() {
|
||||
snapshot = new Snapshot(securityManager.getCallStack());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
snapshot = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* A custom security manager.
|
||||
*/
|
||||
private static class PrivateSecurityManager extends SecurityManager {
|
||||
/**
|
||||
* Get the class stack.
|
||||
*
|
||||
* @return class stack
|
||||
*/
|
||||
private List<WeakReference<Class<?>>> getCallStack() {
|
||||
final Class<?>[] classes = getClassContext();
|
||||
final List<WeakReference<Class<?>>> stack = new ArrayList<>(classes.length);
|
||||
for (final Class<?> klass : classes) {
|
||||
stack.add(new WeakReference<Class<?>>(klass));
|
||||
}
|
||||
return stack;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A snapshot of a class stack.
|
||||
*/
|
||||
private static class Snapshot {
|
||||
private final long timestamp = System.currentTimeMillis();
|
||||
private final List<WeakReference<Class<?>>> stack;
|
||||
|
||||
/**
|
||||
* Create a new snapshot with a class stack.
|
||||
*
|
||||
* @param stack class stack
|
||||
*/
|
||||
private Snapshot(final List<WeakReference<Class<?>>> stack) {
|
||||
this.stack = stack;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,456 @@
|
||||
/*
|
||||
* 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.impl;
|
||||
|
||||
import java.lang.ref.Reference;
|
||||
import java.lang.ref.ReferenceQueue;
|
||||
import java.lang.ref.SoftReference;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
import org.apache.tomcat.dbcp.pool2.BaseObjectPool;
|
||||
import org.apache.tomcat.dbcp.pool2.PoolUtils;
|
||||
import org.apache.tomcat.dbcp.pool2.PooledObjectFactory;
|
||||
|
||||
/**
|
||||
* A {@link java.lang.ref.SoftReference SoftReference} based
|
||||
* {@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.
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public class SoftReferenceObjectPool<T> extends BaseObjectPool<T> {
|
||||
|
||||
/** Factory to source pooled objects */
|
||||
private final PooledObjectFactory<T> factory;
|
||||
|
||||
/**
|
||||
* Queue of broken references that might be able to be removed from
|
||||
* <code>_pool</code>. This is used to help {@link #getNumIdle()} be more
|
||||
* accurate with minimal performance overhead.
|
||||
*/
|
||||
private final ReferenceQueue<T> refQueue = new ReferenceQueue<>();
|
||||
|
||||
/** Count of instances that have been checkout out to pool clients */
|
||||
private int numActive = 0; // @GuardedBy("this")
|
||||
|
||||
/** Total number of instances that have been destroyed */
|
||||
private long destroyCount = 0; // @GuardedBy("this")
|
||||
|
||||
|
||||
/** Total number of instances that have been created */
|
||||
private long createCount = 0; // @GuardedBy("this")
|
||||
|
||||
/** Idle references - waiting to be borrowed */
|
||||
private final LinkedBlockingDeque<PooledSoftReference<T>> idleReferences =
|
||||
new LinkedBlockingDeque<>();
|
||||
|
||||
/** All references - checked out or waiting to be borrowed. */
|
||||
private final ArrayList<PooledSoftReference<T>> allReferences =
|
||||
new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Create a <code>SoftReferenceObjectPool</code> with the specified factory.
|
||||
*
|
||||
* @param factory object factory to use.
|
||||
*/
|
||||
public SoftReferenceObjectPool(final PooledObjectFactory<T> factory) {
|
||||
this.factory = factory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Borrows an object from the pool. If there are no idle instances available
|
||||
* in the pool, the configured factory's
|
||||
* {@link PooledObjectFactory#makeObject()} method is invoked to create a
|
||||
* new instance.
|
||||
* <p>
|
||||
* All instances are {@link PooledObjectFactory#activateObject(
|
||||
* org.apache.tomcat.dbcp.pool2.PooledObject) activated}
|
||||
* and {@link PooledObjectFactory#validateObject(
|
||||
* org.apache.tomcat.dbcp.pool2.PooledObject)
|
||||
* validated} before being returned by this method. If validation fails or
|
||||
* an exception occurs activating or validating an idle instance, the
|
||||
* failing instance is {@link PooledObjectFactory#destroyObject(
|
||||
* org.apache.tomcat.dbcp.pool2.PooledObject)
|
||||
* destroyed} and another instance is retrieved from the pool, validated and
|
||||
* activated. This process continues until either the pool is empty or an
|
||||
* instance passes validation. If the pool is empty on activation or it does
|
||||
* not contain any valid instances, the factory's <code>makeObject</code>
|
||||
* method is used to create a new instance. If the created instance either
|
||||
* raises an exception on activation or fails validation,
|
||||
* <code>NoSuchElementException</code> is thrown. Exceptions thrown by
|
||||
* <code>MakeObject</code> are propagated to the caller; but other than
|
||||
* <code>ThreadDeath</code> or <code>VirtualMachineError</code>, exceptions
|
||||
* generated by activation, validation or destroy methods are swallowed
|
||||
* silently.
|
||||
*
|
||||
* @throws NoSuchElementException
|
||||
* if a valid object cannot be provided
|
||||
* @throws IllegalStateException
|
||||
* if invoked on a {@link #close() closed} pool
|
||||
* @throws Exception
|
||||
* if an exception occurs creating a new instance
|
||||
* @return a valid, activated object instance
|
||||
*/
|
||||
@SuppressWarnings("null") // ref cannot be null
|
||||
@Override
|
||||
public synchronized T borrowObject() throws Exception {
|
||||
assertOpen();
|
||||
T obj = null;
|
||||
boolean newlyCreated = false;
|
||||
PooledSoftReference<T> ref = null;
|
||||
while (null == obj) {
|
||||
if (idleReferences.isEmpty()) {
|
||||
if (null == factory) {
|
||||
throw new NoSuchElementException();
|
||||
}
|
||||
newlyCreated = true;
|
||||
obj = factory.makeObject().getObject();
|
||||
createCount++;
|
||||
// Do not register with the queue
|
||||
ref = new PooledSoftReference<>(new SoftReference<>(obj));
|
||||
allReferences.add(ref);
|
||||
} else {
|
||||
ref = idleReferences.pollFirst();
|
||||
obj = ref.getObject();
|
||||
// Clear the reference so it will not be queued, but replace with a
|
||||
// a new, non-registered reference so we can still track this object
|
||||
// in allReferences
|
||||
ref.getReference().clear();
|
||||
ref.setReference(new SoftReference<>(obj));
|
||||
}
|
||||
if (null != factory && null != obj) {
|
||||
try {
|
||||
factory.activateObject(ref);
|
||||
if (!factory.validateObject(ref)) {
|
||||
throw new Exception("ValidateObject failed");
|
||||
}
|
||||
} catch (final Throwable t) {
|
||||
PoolUtils.checkRethrow(t);
|
||||
try {
|
||||
destroy(ref);
|
||||
} catch (final Throwable t2) {
|
||||
PoolUtils.checkRethrow(t2);
|
||||
// Swallowed
|
||||
} finally {
|
||||
obj = null;
|
||||
}
|
||||
if (newlyCreated) {
|
||||
throw new NoSuchElementException(
|
||||
"Could not create a validated object, cause: " +
|
||||
t.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
numActive++;
|
||||
ref.allocate();
|
||||
return obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an instance to the pool after successful validation and
|
||||
* passivation. The returning instance is destroyed if any of the following
|
||||
* are true:
|
||||
* <ul>
|
||||
* <li>the pool is closed</li>
|
||||
* <li>{@link PooledObjectFactory#validateObject(
|
||||
* org.apache.tomcat.dbcp.pool2.PooledObject) validation} fails
|
||||
* </li>
|
||||
* <li>{@link PooledObjectFactory#passivateObject(
|
||||
* org.apache.tomcat.dbcp.pool2.PooledObject) passivation}
|
||||
* throws an exception</li>
|
||||
* </ul>
|
||||
* Exceptions passivating or destroying instances are silently swallowed.
|
||||
* Exceptions validating instances are propagated to the client.
|
||||
*
|
||||
* @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 {
|
||||
boolean success = !isClosed();
|
||||
final PooledSoftReference<T> ref = findReference(obj);
|
||||
if (ref == null) {
|
||||
throw new IllegalStateException(
|
||||
"Returned object not currently part of this pool");
|
||||
}
|
||||
if (factory != null) {
|
||||
if (!factory.validateObject(ref)) {
|
||||
success = false;
|
||||
} else {
|
||||
try {
|
||||
factory.passivateObject(ref);
|
||||
} catch (final Exception e) {
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final boolean shouldDestroy = !success;
|
||||
numActive--;
|
||||
if (success) {
|
||||
|
||||
// Deallocate and add to the idle instance pool
|
||||
ref.deallocate();
|
||||
idleReferences.add(ref);
|
||||
}
|
||||
notifyAll(); // numActive has changed
|
||||
|
||||
if (shouldDestroy && factory != null) {
|
||||
try {
|
||||
destroy(ref);
|
||||
} catch (final Exception e) {
|
||||
// ignored
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public synchronized void invalidateObject(final T obj) throws Exception {
|
||||
final PooledSoftReference<T> ref = findReference(obj);
|
||||
if (ref == null) {
|
||||
throw new IllegalStateException(
|
||||
"Object to invalidate is not currently part of this pool");
|
||||
}
|
||||
if (factory != null) {
|
||||
destroy(ref);
|
||||
}
|
||||
numActive--;
|
||||
notifyAll(); // numActive has changed
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an object, and places it into the pool. addObject() is useful for
|
||||
* "pre-loading" a pool with idle objects.
|
||||
* <p>
|
||||
* Before being added to the pool, the newly created instance is
|
||||
* {@link PooledObjectFactory#validateObject(
|
||||
* org.apache.tomcat.dbcp.pool2.PooledObject) validated} and
|
||||
* {@link PooledObjectFactory#passivateObject(
|
||||
* org.apache.tomcat.dbcp.pool2.PooledObject) passivated}. If
|
||||
* validation fails, the new instance is
|
||||
* {@link PooledObjectFactory#destroyObject(
|
||||
* org.apache.tomcat.dbcp.pool2.PooledObject) destroyed}. Exceptions
|
||||
* generated by the factory <code>makeObject</code> or
|
||||
* <code>passivate</code> are propagated to the caller. Exceptions
|
||||
* destroying instances are silently swallowed.
|
||||
*
|
||||
* @throws IllegalStateException
|
||||
* if invoked on a {@link #close() closed} pool
|
||||
* @throws Exception
|
||||
* when the {@link #getFactory() factory} has a problem creating
|
||||
* or passivating an object.
|
||||
*/
|
||||
@Override
|
||||
public synchronized void addObject() throws Exception {
|
||||
assertOpen();
|
||||
if (factory == null) {
|
||||
throw new IllegalStateException(
|
||||
"Cannot add objects without a factory.");
|
||||
}
|
||||
final T obj = factory.makeObject().getObject();
|
||||
createCount++;
|
||||
// Create and register with the queue
|
||||
final PooledSoftReference<T> ref = new PooledSoftReference<>(
|
||||
new SoftReference<>(obj, refQueue));
|
||||
allReferences.add(ref);
|
||||
|
||||
boolean success = true;
|
||||
if (!factory.validateObject(ref)) {
|
||||
success = false;
|
||||
} else {
|
||||
factory.passivateObject(ref);
|
||||
}
|
||||
|
||||
final boolean shouldDestroy = !success;
|
||||
if (success) {
|
||||
idleReferences.add(ref);
|
||||
notifyAll(); // numActive has changed
|
||||
}
|
||||
|
||||
if (shouldDestroy) {
|
||||
try {
|
||||
destroy(ref);
|
||||
} catch (final Exception e) {
|
||||
// ignored
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an approximation not less than the of the number of idle
|
||||
* instances in the pool.
|
||||
*
|
||||
* @return estimated number of idle instances in the pool
|
||||
*/
|
||||
@Override
|
||||
public synchronized int getNumIdle() {
|
||||
pruneClearedReferences();
|
||||
return idleReferences.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of instances currently borrowed from this pool.
|
||||
*
|
||||
* @return the number of instances currently borrowed from this pool
|
||||
*/
|
||||
@Override
|
||||
public synchronized int getNumActive() {
|
||||
return numActive;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears any objects sitting idle in the pool.
|
||||
*/
|
||||
@Override
|
||||
public synchronized void clear() {
|
||||
if (null != factory) {
|
||||
final Iterator<PooledSoftReference<T>> iter = idleReferences.iterator();
|
||||
while (iter.hasNext()) {
|
||||
try {
|
||||
final PooledSoftReference<T> ref = iter.next();
|
||||
if (null != ref.getObject()) {
|
||||
factory.destroyObject(ref);
|
||||
}
|
||||
} catch (final Exception e) {
|
||||
// ignore error, keep destroying the rest
|
||||
}
|
||||
}
|
||||
}
|
||||
idleReferences.clear();
|
||||
pruneClearedReferences();
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes this pool, and frees any resources associated with it. Invokes
|
||||
* {@link #clear()} to destroy and remove instances in the pool.
|
||||
* <p>
|
||||
* Calling {@link #addObject} or {@link #borrowObject} after invoking this
|
||||
* method on a pool will cause them to throw an
|
||||
* {@link IllegalStateException}.
|
||||
*/
|
||||
@Override
|
||||
public void close() {
|
||||
super.close();
|
||||
clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link PooledObjectFactory} used by this pool to create and
|
||||
* manage object instances.
|
||||
*
|
||||
* @return the factory
|
||||
*/
|
||||
public synchronized PooledObjectFactory<T> getFactory() {
|
||||
return factory;
|
||||
}
|
||||
|
||||
/**
|
||||
* If any idle objects were garbage collected, remove their
|
||||
* {@link Reference} wrappers from the idle object pool.
|
||||
*/
|
||||
private void pruneClearedReferences() {
|
||||
// Remove wrappers for enqueued references from idle and allReferences lists
|
||||
removeClearedReferences(idleReferences.iterator());
|
||||
removeClearedReferences(allReferences.iterator());
|
||||
while (refQueue.poll() != null) {
|
||||
// empty
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the PooledSoftReference in allReferences that points to obj.
|
||||
*
|
||||
* @param obj returning object
|
||||
* @return PooledSoftReference wrapping a soft reference to obj
|
||||
*/
|
||||
private PooledSoftReference<T> findReference(final T obj) {
|
||||
final Iterator<PooledSoftReference<T>> iterator = allReferences.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
final PooledSoftReference<T> reference = iterator.next();
|
||||
if (reference.getObject() != null && reference.getObject().equals(obj)) {
|
||||
return reference;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroys a {@code PooledSoftReference} and removes it from the idle and all
|
||||
* references pools.
|
||||
*
|
||||
* @param toDestroy PooledSoftReference to destroy
|
||||
*
|
||||
* @throws Exception If an error occurs while trying to destroy the object
|
||||
*/
|
||||
private void destroy(final PooledSoftReference<T> toDestroy) throws Exception {
|
||||
toDestroy.invalidate();
|
||||
idleReferences.remove(toDestroy);
|
||||
allReferences.remove(toDestroy);
|
||||
try {
|
||||
factory.destroyObject(toDestroy);
|
||||
} finally {
|
||||
destroyCount++;
|
||||
toDestroy.getReference().clear();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears cleared references from iterator's collection
|
||||
* @param iterator iterator over idle/allReferences
|
||||
*/
|
||||
private void removeClearedReferences(final Iterator<PooledSoftReference<T>> iterator) {
|
||||
PooledSoftReference<T> ref;
|
||||
while (iterator.hasNext()) {
|
||||
ref = iterator.next();
|
||||
if (ref.getReference() == null || ref.getReference().isEnqueued()) {
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void toStringAppendFields(final StringBuilder builder) {
|
||||
super.toStringAppendFields(builder);
|
||||
builder.append(", factory=");
|
||||
builder.append(factory);
|
||||
builder.append(", refQueue=");
|
||||
builder.append(refQueue);
|
||||
builder.append(", numActive=");
|
||||
builder.append(numActive);
|
||||
builder.append(", destroyCount=");
|
||||
builder.append(destroyCount);
|
||||
builder.append(", createCount=");
|
||||
builder.append(createCount);
|
||||
builder.append(", idleReferences=");
|
||||
builder.append(idleReferences);
|
||||
builder.append(", allReferences=");
|
||||
builder.append(allReferences);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* 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.impl;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
|
||||
/**
|
||||
* CallStack strategy that uses the stack trace from a {@link Throwable}. This strategy, while slower than the
|
||||
* SecurityManager implementation, provides call stack method names and other metadata in addition to the call stack
|
||||
* of classes.
|
||||
*
|
||||
* @see Throwable#fillInStackTrace()
|
||||
* @since 2.4.3
|
||||
*/
|
||||
public class ThrowableCallStack implements CallStack {
|
||||
|
||||
private final String messageFormat;
|
||||
//@GuardedBy("dateFormat")
|
||||
private final DateFormat dateFormat;
|
||||
|
||||
private volatile Snapshot snapshot;
|
||||
|
||||
/**
|
||||
* Create a new instance.
|
||||
*
|
||||
* @param messageFormat message format
|
||||
* @param useTimestamp whether to format the dates in the output message or not
|
||||
*/
|
||||
public ThrowableCallStack(final String messageFormat, final boolean useTimestamp) {
|
||||
this.messageFormat = messageFormat;
|
||||
this.dateFormat = useTimestamp ? new SimpleDateFormat(messageFormat) : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean printStackTrace(final PrintWriter writer) {
|
||||
final Snapshot snapshotRef = this.snapshot;
|
||||
if (snapshotRef == null) {
|
||||
return false;
|
||||
}
|
||||
final String message;
|
||||
if (dateFormat == null) {
|
||||
message = messageFormat;
|
||||
} else {
|
||||
synchronized (dateFormat) {
|
||||
message = dateFormat.format(Long.valueOf(snapshotRef.timestamp));
|
||||
}
|
||||
}
|
||||
writer.println(message);
|
||||
snapshotRef.printStackTrace(writer);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fillInStackTrace() {
|
||||
snapshot = new Snapshot();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
snapshot = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* A snapshot of a throwable.
|
||||
*/
|
||||
private static class Snapshot extends Throwable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
private final long timestamp = System.currentTimeMillis();
|
||||
}
|
||||
}
|
||||
41
java/org/apache/tomcat/dbcp/pool2/impl/package.html
Normal file
41
java/org/apache/tomcat/dbcp/pool2/impl/package.html
Normal file
@@ -0,0 +1,41 @@
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<html>
|
||||
<head>
|
||||
<title>Package Documentation for org.apache.tomcat.dbcp.pool2.impl</title>
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
Object pooling API implementations.
|
||||
</p>
|
||||
<p>
|
||||
{@link org.apache.tomcat.dbcp.pool2.impl.GenericObjectPool GenericObjectPool}
|
||||
({@link org.apache.tomcat.dbcp.pool2.impl.GenericKeyedObjectPool GenericKeyedObjectPool})
|
||||
provides a more robust (but also more complicated)
|
||||
implementation of {@link org.apache.tomcat.dbcp.pool2.ObjectPool ObjectPool}
|
||||
({@link org.apache.tomcat.dbcp.pool2.KeyedObjectPool KeyedObjectPool}).
|
||||
</p>
|
||||
<p>
|
||||
{@link org.apache.tomcat.dbcp.pool2.impl.SoftReferenceObjectPool SoftReferenceObjectPool}
|
||||
provides a {@link java.lang.ref.SoftReference SoftReference} based
|
||||
{@link org.apache.tomcat.dbcp.pool2.ObjectPool ObjectPool}.
|
||||
</p>
|
||||
<p>
|
||||
See also the {@link org.apache.tomcat.dbcp.pool2} package.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
62
java/org/apache/tomcat/dbcp/pool2/package.html
Normal file
62
java/org/apache/tomcat/dbcp/pool2/package.html
Normal file
@@ -0,0 +1,62 @@
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<html>
|
||||
<head>
|
||||
<title>Package Documentation for org.apache.tomcat.dbcp.pool2</title>
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
Object pooling API.
|
||||
</p>
|
||||
<p>
|
||||
The <code>org.apache.tomcat.dbcp.pool2</code> package defines a simple
|
||||
interface for a pool of object instances, and a handful of base
|
||||
classes that may be useful when creating pool implementations.
|
||||
</p>
|
||||
<p>
|
||||
The <code>pool</code> package itself doesn't define a specific object
|
||||
pooling implementation, but rather a contract that implementations may
|
||||
support in order to be fully interchangeable.
|
||||
</p>
|
||||
<p>
|
||||
The <code>pool</code> package separates the way in which instances are
|
||||
pooled from the way in which they are created, resulting in a pair of
|
||||
interfaces:
|
||||
</p>
|
||||
<dl>
|
||||
<dt>{@link org.apache.tomcat.dbcp.pool2.ObjectPool ObjectPool}</dt>
|
||||
<dd>
|
||||
defines a simple object pooling interface, with methods for
|
||||
borrowing instances from and returning them to the pool.
|
||||
</dd>
|
||||
<dt>{@link org.apache.tomcat.dbcp.pool2.PooledObjectFactory PooledObjectFactory}</dt>
|
||||
<dd>
|
||||
defines lifecycle methods for object instances contained within a pool.
|
||||
By associating a factory with a pool, the pool can create new object
|
||||
instances as needed.
|
||||
</dd>
|
||||
</dl>
|
||||
<p>
|
||||
The <code>pool</code> package also provides a keyed pool interface,
|
||||
which pools instances of multiple types, accessed according to an
|
||||
arbitrary key. See
|
||||
{@link org.apache.tomcat.dbcp.pool2.KeyedObjectPool KeyedObjectPool} and
|
||||
{@link org.apache.tomcat.dbcp.pool2.KeyedPooledObjectFactory
|
||||
KeyedPooledObjectFactory}.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user