Author: markt
Date: Wed Aug 31 18:50:36 2011
New Revision: 1163741
URL: http://svn.apache.org/viewvc?rev=1163741&view=rev
Log:
Fix a bug in eviction that could see a destroyed object returned to the idle
object pool if:
- it was being validated by the evictor
- validation failed
- an attempt was made to borrow the object during validation
Modified:
commons/proper/pool/trunk/src/java/org/apache/commons/pool2/impl/GenericObjectPool.java
commons/proper/pool/trunk/src/java/org/apache/commons/pool2/impl/PooledObject.java
commons/proper/pool/trunk/src/test/org/apache/commons/pool2/impl/TestGenericObjectPool.java
Modified:
commons/proper/pool/trunk/src/java/org/apache/commons/pool2/impl/GenericObjectPool.java
URL:
http://svn.apache.org/viewvc/commons/proper/pool/trunk/src/java/org/apache/commons/pool2/impl/GenericObjectPool.java?rev=1163741&r1=1163740&r2=1163741&view=diff
==============================================================================
---
commons/proper/pool/trunk/src/java/org/apache/commons/pool2/impl/GenericObjectPool.java
(original)
+++
commons/proper/pool/trunk/src/java/org/apache/commons/pool2/impl/GenericObjectPool.java
Wed Aug 31 18:50:36 2011
@@ -1138,6 +1138,7 @@ public class GenericObjectPool<T> extend
}
private void destroy(PooledObject<T> toDestory) throws Exception {
+ toDestory.invalidate();
idleObjects.remove(toDestory);
allObjects.remove(toDestory.getObject());
try {
Modified:
commons/proper/pool/trunk/src/java/org/apache/commons/pool2/impl/PooledObject.java
URL:
http://svn.apache.org/viewvc/commons/proper/pool/trunk/src/java/org/apache/commons/pool2/impl/PooledObject.java?rev=1163741&r1=1163740&r2=1163741&view=diff
==============================================================================
---
commons/proper/pool/trunk/src/java/org/apache/commons/pool2/impl/PooledObject.java
(original)
+++
commons/proper/pool/trunk/src/java/org/apache/commons/pool2/impl/PooledObject.java
Wed Aug 31 18:50:36 2011
@@ -145,4 +145,8 @@ public class PooledObject<T> implements
return false;
}
+
+ public synchronized void invalidate() {
+ state = PooledObjectState.INVALID;
+ }
}
Modified:
commons/proper/pool/trunk/src/test/org/apache/commons/pool2/impl/TestGenericObjectPool.java
URL:
http://svn.apache.org/viewvc/commons/proper/pool/trunk/src/test/org/apache/commons/pool2/impl/TestGenericObjectPool.java?rev=1163741&r1=1163740&r2=1163741&view=diff
==============================================================================
---
commons/proper/pool/trunk/src/test/org/apache/commons/pool2/impl/TestGenericObjectPool.java
(original)
+++
commons/proper/pool/trunk/src/test/org/apache/commons/pool2/impl/TestGenericObjectPool.java
Wed Aug 31 18:50:36 2011
@@ -903,6 +903,70 @@ public class TestGenericObjectPool exten
}
@Test
+ public void testEvictionInvalid() throws Exception {
+ class InvalidFactory extends BasePoolableObjectFactory<Object> {
+
+ @Override
+ public Object makeObject() throws Exception {
+ return new Object();
+ }
+
+ @Override
+ public boolean validateObject(Object obj) {
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ // Ignore
+ }
+ return false;
+ }
+ }
+
+ final GenericObjectPool<Object> pool =
+ new GenericObjectPool<Object>(new InvalidFactory());
+
+ pool.setMaxIdle(1);
+ pool.setMaxTotal(1);
+ pool.setTestOnBorrow(false);
+ pool.setTestOnReturn(false);
+ pool.setTestWhileIdle(true);
+ pool.setMinEvictableIdleTimeMillis(100000);
+ pool.setNumTestsPerEvictionRun(1);
+
+ Object p = pool.borrowObject();
+ pool.returnObject(p);
+
+ // Run eviction in a separate thread
+ Thread t = new Thread() {
+ @Override
+ public void run() {
+ try {
+ pool.evict();
+ } catch (Exception e) {
+ // Ignore
+ }
+ }
+ };
+ t.start();
+
+ // Sleep to make sure evictor has started
+ Thread.sleep(300);
+
+ try {
+ p = pool.borrowObject(1);
+ } catch (NoSuchElementException nsee) {
+ // Ignore
+ }
+
+ // Make sure evictor has finished
+ Thread.sleep(1000);
+
+ // Should have an empty pool
+ assertEquals("Idle count different than expected.", 0,
pool.getNumIdle());
+ assertEquals("Total count different than expected.", 0,
pool.getNumActive());
+ }
+
+ @Test
public void testMinIdle() throws Exception {
pool.setMaxIdle(500);
pool.setMinIdle(5);