You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by sa...@apache.org on 2006/05/14 02:54:02 UTC
svn commit: r406176 - in
/jakarta/commons/proper/pool/branches/performance-ideas/src:
java/org/apache/commons/pool/composite/ test/org/apache/commons/pool/
test/org/apache/commons/pool/composite/ test/org/apache/commons/pool/impl/
Author: sandymac
Date: Sat May 13 17:54:00 2006
New Revision: 406176
URL: http://svn.apache.org/viewcvs?rev=406176&view=rev
Log:
Fully minimized synchronization but this leaves a race condition for pools
with a max active limit. Created a unit test to verify this race condition.
Small Javadoc corrections.
Removed:
jakarta/commons/proper/pool/branches/performance-ideas/src/java/org/apache/commons/pool/composite/CompositeObjectPoolFullSync.java
jakarta/commons/proper/pool/branches/performance-ideas/src/test/org/apache/commons/pool/composite/TestCompositeObjectPoolFullSync.java
Modified:
jakarta/commons/proper/pool/branches/performance-ideas/src/java/org/apache/commons/pool/composite/AbstractManager.java
jakarta/commons/proper/pool/branches/performance-ideas/src/java/org/apache/commons/pool/composite/CompositeObjectPool.java
jakarta/commons/proper/pool/branches/performance-ideas/src/java/org/apache/commons/pool/composite/CompositeObjectPoolFactory.java
jakarta/commons/proper/pool/branches/performance-ideas/src/java/org/apache/commons/pool/composite/FailManager.java
jakarta/commons/proper/pool/branches/performance-ideas/src/java/org/apache/commons/pool/composite/GrowManager.java
jakarta/commons/proper/pool/branches/performance-ideas/src/java/org/apache/commons/pool/composite/WaitLimitManager.java
jakarta/commons/proper/pool/branches/performance-ideas/src/test/org/apache/commons/pool/TestBaseObjectPool.java
jakarta/commons/proper/pool/branches/performance-ideas/src/test/org/apache/commons/pool/TestObjectPool.java
jakarta/commons/proper/pool/branches/performance-ideas/src/test/org/apache/commons/pool/composite/PerformanceTest.java
jakarta/commons/proper/pool/branches/performance-ideas/src/test/org/apache/commons/pool/composite/TestAll.java
jakarta/commons/proper/pool/branches/performance-ideas/src/test/org/apache/commons/pool/composite/TestCompositeObjectPool.java
jakarta/commons/proper/pool/branches/performance-ideas/src/test/org/apache/commons/pool/composite/TestWaitLimitManager.java
jakarta/commons/proper/pool/branches/performance-ideas/src/test/org/apache/commons/pool/impl/TestGenericObjectPool.java
jakarta/commons/proper/pool/branches/performance-ideas/src/test/org/apache/commons/pool/impl/TestSoftReferenceObjectPool.java
jakarta/commons/proper/pool/branches/performance-ideas/src/test/org/apache/commons/pool/impl/TestStackObjectPool.java
Modified: jakarta/commons/proper/pool/branches/performance-ideas/src/java/org/apache/commons/pool/composite/AbstractManager.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/pool/branches/performance-ideas/src/java/org/apache/commons/pool/composite/AbstractManager.java?rev=406176&r1=406175&r2=406176&view=diff
==============================================================================
--- jakarta/commons/proper/pool/branches/performance-ideas/src/java/org/apache/commons/pool/composite/AbstractManager.java (original)
+++ jakarta/commons/proper/pool/branches/performance-ideas/src/java/org/apache/commons/pool/composite/AbstractManager.java Sat May 13 17:54:00 2006
@@ -80,11 +80,14 @@
public abstract Object nextFromPool() throws Exception;
/**
- * Return an object to the pool. Object will be {@link PoolableObjectFactory#passivateObject(Object) passivated}.
+ * Return an object to the pool.
+ * The Object's state will no longer be "active".
+ * The Object will be passes to a delegate to be made "idle".
*
* @param obj the object to return to the pool.
*/
public void returnToPool(final Object obj) {
+ objectPool.getTracker().returned(obj);
objectPool.getLender().repay(obj);
}
Modified: jakarta/commons/proper/pool/branches/performance-ideas/src/java/org/apache/commons/pool/composite/CompositeObjectPool.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/pool/branches/performance-ideas/src/java/org/apache/commons/pool/composite/CompositeObjectPool.java?rev=406176&r1=406175&r2=406176&view=diff
==============================================================================
--- jakarta/commons/proper/pool/branches/performance-ideas/src/java/org/apache/commons/pool/composite/CompositeObjectPool.java (original)
+++ jakarta/commons/proper/pool/branches/performance-ideas/src/java/org/apache/commons/pool/composite/CompositeObjectPool.java Sat May 13 17:54:00 2006
@@ -218,8 +218,9 @@
}
}
- protected boolean addObjectToPool(final Object obj) {
+ private boolean addObjectToPool(final Object obj) {
if (isOpen()) {
+ tracker.borrowed(obj); // pretend
manager.returnToPool(obj);
return true;
}
@@ -252,10 +253,8 @@
* @throws Exception if there is an unexpected problem.
* @see #borrowObject()
*/
- protected Object borrowObjectFromPool() throws Exception {
- final Object obj = manager.nextFromPool();
- tracker.borrowed(obj);
- return obj;
+ private Object borrowObjectFromPool() throws Exception {
+ return manager.nextFromPool();
}
/**
@@ -286,10 +285,9 @@
}
}
- protected boolean returnObjectToPool(final Object obj) {
+ private boolean returnObjectToPool(final Object obj) {
// if the pool is closed, don't return objects
if (isOpen()) {
- tracker.returned(obj);
manager.returnToPool(obj);
return true;
}
Modified: jakarta/commons/proper/pool/branches/performance-ideas/src/java/org/apache/commons/pool/composite/CompositeObjectPoolFactory.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/pool/branches/performance-ideas/src/java/org/apache/commons/pool/composite/CompositeObjectPoolFactory.java?rev=406176&r1=406175&r2=406176&view=diff
==============================================================================
--- jakarta/commons/proper/pool/branches/performance-ideas/src/java/org/apache/commons/pool/composite/CompositeObjectPoolFactory.java (original)
+++ jakarta/commons/proper/pool/branches/performance-ideas/src/java/org/apache/commons/pool/composite/CompositeObjectPoolFactory.java Sat May 13 17:54:00 2006
@@ -247,17 +247,8 @@
if (config == null) {
throw new IllegalArgumentException("config must not be null.");
}
- if (needsFullSync(config)) {
- return new CompositeObjectPoolFullSync(config.factory, getList(config), getManager(config), getLender(config),
- getTracker(config), config.validateOnReturn, config);
- } else {
- return new CompositeObjectPool(config.factory, getList(config), getManager(config), getLender(config),
- getTracker(config), config.validateOnReturn, config);
- }
- }
-
- private static boolean needsFullSync(final FactoryConfig config) {
- return config.maxActive > 0 && LimitPolicy.WAIT.equals(config.limitPolicy);
+ return new CompositeObjectPool(config.factory, getList(config), getManager(config), getLender(config),
+ getTracker(config), config.validateOnReturn, config);
}
/**
@@ -525,18 +516,20 @@
}
/**
- * Maximum number of objects associated with this pool. A non-positive value means there is no limit.
+ * Maximum number of active objects concurrently borrowed from the pool.
+ * A non-positive value means there is no limit.
*
- * @return if > 0 the the maximum number of objects else no size limit.
+ * @return if > 0 the the maximum number of concurrently active objects else no limit.
*/
public int getMaxActive() {
return maxActive;
}
/**
- * Set the maximum number of objects associated with this pool. Any non-positive value means there is no limit.
+ * Set the maximum number of active objects concurrently borrowed from the pool.
+ * Any non-positive value means there is no limit.
*
- * @param maxActive the limit of active and idle objects in the pool or <= 0 for no limit.
+ * @param maxActive the maximum number of active objects concurrently borrowed from the pool or <= 0 for no limit.
*/
public void setMaxActive(final int maxActive) {
synchronized (lock){
Modified: jakarta/commons/proper/pool/branches/performance-ideas/src/java/org/apache/commons/pool/composite/FailManager.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/pool/branches/performance-ideas/src/java/org/apache/commons/pool/composite/FailManager.java?rev=406176&r1=406175&r2=406176&view=diff
==============================================================================
--- jakarta/commons/proper/pool/branches/performance-ideas/src/java/org/apache/commons/pool/composite/FailManager.java (original)
+++ jakarta/commons/proper/pool/branches/performance-ideas/src/java/org/apache/commons/pool/composite/FailManager.java Sat May 13 17:54:00 2006
@@ -90,6 +90,7 @@
}
cause.set(null); // clear reference
+ objectPool.getTracker().borrowed(obj);
return obj;
}
Modified: jakarta/commons/proper/pool/branches/performance-ideas/src/java/org/apache/commons/pool/composite/GrowManager.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/pool/branches/performance-ideas/src/java/org/apache/commons/pool/composite/GrowManager.java?rev=406176&r1=406175&r2=406176&view=diff
==============================================================================
--- jakarta/commons/proper/pool/branches/performance-ideas/src/java/org/apache/commons/pool/composite/GrowManager.java (original)
+++ jakarta/commons/proper/pool/branches/performance-ideas/src/java/org/apache/commons/pool/composite/GrowManager.java Sat May 13 17:54:00 2006
@@ -87,12 +87,12 @@
if (generator != null) {
generator.cancel();
}
+ objectPool.getTracker().borrowed(obj);
return obj;
}
private class Generator extends TimerTask {
private boolean returnToThread = true;
- private volatile boolean done = false;
private volatile Object obj;
private Throwable throwable;
@@ -123,21 +123,19 @@
return;
}
final List pool = objectPool.getPool();
+ final boolean passivate;
synchronized (pool) {
- done = true;
if (returnToThread) {
this.obj = obj;
pool.notifyAll();
+ passivate = false;
} else {
- try {
- objectPool.getFactory().passivateObject(obj);
- } catch (Throwable t) {
- throwable = t;
- return;
- }
- objectPool.returnObjectToPoolManager(obj);
+ passivate = true;
}
}
+ if (passivate) {
+ passivateAndReturnToPool(obj);
+ }
} finally {
if (keys != null) {
keys.set(null);
@@ -145,9 +143,28 @@
}
}
+ private void passivateAndReturnToPool(final Object obj) {
+ final List pool = objectPool.getPool();
+ try {
+ objectPool.getFactory().passivateObject(obj);
+ } catch (Throwable t) {
+ throwable = t;
+ //return;
+ }
+ synchronized (pool) {
+ objectPool.getTracker().borrowed(obj); // pretend
+ objectPool.returnObjectToPoolManager(obj);
+ }
+ }
+
public boolean cancel() {
synchronized (objectPool.getPool()) {
returnToThread = false;
+ // If the originial thread borrowed from the pool before we could hand them an object.
+ if (obj != null) {
+ passivateAndReturnToPool(obj);
+ obj = null;
+ }
}
return super.cancel();
}
@@ -163,6 +180,8 @@
throw new Exception(throwable);
}
}
+ final Object obj = this.obj;
+ this.obj = null;
return obj;
}
}
Modified: jakarta/commons/proper/pool/branches/performance-ideas/src/java/org/apache/commons/pool/composite/WaitLimitManager.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/pool/branches/performance-ideas/src/java/org/apache/commons/pool/composite/WaitLimitManager.java?rev=406176&r1=406175&r2=406176&view=diff
==============================================================================
--- jakarta/commons/proper/pool/branches/performance-ideas/src/java/org/apache/commons/pool/composite/WaitLimitManager.java (original)
+++ jakarta/commons/proper/pool/branches/performance-ideas/src/java/org/apache/commons/pool/composite/WaitLimitManager.java Sat May 13 17:54:00 2006
@@ -51,10 +51,7 @@
* @throws InterruptedException when the {@link Thread} is interrupted.
*/
public Object nextFromPool() throws NoSuchElementException, Exception, InterruptedException {
- final Object poolLock = objectPool.getPool();
- if (!Thread.holdsLock(poolLock)) {
- throw new AssertionError("WaitLimitManager needs to be externally synchronized for proper behavior.");
- }
+ final Object pool = objectPool.getPool();
final long endTime = maxWaitMillis > 0 ? System.currentTimeMillis() + maxWaitMillis : Long.MAX_VALUE;
while (maxWaitMillis <= 0 || endTime > System.currentTimeMillis()) {
if (Thread.currentThread().isInterrupted()) {
@@ -63,12 +60,16 @@
if (objectPool.getNumActive() < getMaxActive()) {
return super.nextFromPool();
}
- // Don't wait if the pool was closed between the start of the while and here.
- if (objectPool.isOpen()) {
- final long waitTime = Math.max(1, endTime - System.currentTimeMillis());
- poolLock.wait(maxWaitMillis > 0 ? waitTime : 0);
- } else {
- throw new IllegalStateException("Trying to aquire an object from a closed pool.");
+ synchronized (pool) {
+ // Don't wait if the pool was closed between the start of the while and here.
+ if (objectPool.isOpen()) {
+ if (objectPool.getNumActive() >= getMaxActive()) {
+ final long waitTime = Math.max(1, endTime - System.currentTimeMillis());
+ pool.wait(maxWaitMillis > 0 ? waitTime : 0);
+ }
+ } else {
+ throw new IllegalStateException("Trying to aquire an object from a closed pool.");
+ }
}
}
if (objectPool.isOpen()) {
Modified: jakarta/commons/proper/pool/branches/performance-ideas/src/test/org/apache/commons/pool/TestBaseObjectPool.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/pool/branches/performance-ideas/src/test/org/apache/commons/pool/TestBaseObjectPool.java?rev=406176&r1=406175&r2=406176&view=diff
==============================================================================
--- jakarta/commons/proper/pool/branches/performance-ideas/src/test/org/apache/commons/pool/TestBaseObjectPool.java (original)
+++ jakarta/commons/proper/pool/branches/performance-ideas/src/test/org/apache/commons/pool/TestBaseObjectPool.java Sat May 13 17:54:00 2006
@@ -48,6 +48,13 @@
throw new UnsupportedOperationException("BaseObjectPool isn't a complete implementation.");
}
+ protected ObjectPool makeEmptyPoolWithActiveLimit(PoolableObjectFactory factory, int activeLimit) throws UnsupportedOperationException {
+ if (this.getClass() != TestBaseObjectPool.class) {
+ throw new AssertionError("Subclasses of TestBaseObjectPool must reimplement this method.");
+ }
+ throw new UnsupportedOperationException("BaseObjectPool isn't a complete implementation.");
+ }
+
protected Object getNthObject(final int n) {
if (this.getClass() != TestBaseObjectPool.class) {
throw new AssertionError("Subclasses of TestBaseObjectPool must reimplement this method.");
Modified: jakarta/commons/proper/pool/branches/performance-ideas/src/test/org/apache/commons/pool/TestObjectPool.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/pool/branches/performance-ideas/src/test/org/apache/commons/pool/TestObjectPool.java?rev=406176&r1=406175&r2=406176&view=diff
==============================================================================
--- jakarta/commons/proper/pool/branches/performance-ideas/src/test/org/apache/commons/pool/TestObjectPool.java (original)
+++ jakarta/commons/proper/pool/branches/performance-ideas/src/test/org/apache/commons/pool/TestObjectPool.java Sat May 13 17:54:00 2006
@@ -20,6 +20,8 @@
import java.util.List;
import java.util.ArrayList;
import java.util.Iterator;
+import java.util.Set;
+import java.util.HashSet;
/**
* Abstract {@link TestCase} for {@link ObjectPool} implementations.
@@ -41,6 +43,13 @@
*/
protected abstract ObjectPool makeEmptyPool(PoolableObjectFactory factory) throws UnsupportedOperationException;
+ /**
+ * Create an <code>ObjectPool</code> with the specified factory and
+ * limit on the number of concurrently active objects.
+ * @throws UnsupportedOperationException if the pool being tested does not have a max active limit.
+ */
+ protected abstract ObjectPool makeEmptyPoolWithActiveLimit(PoolableObjectFactory factory, int activeLimit) throws UnsupportedOperationException;
+
public void testClosedPoolBehavior() throws Exception {
final ObjectPool pool;
try {
@@ -378,5 +387,115 @@
private static void clear(final MethodCallPoolableObjectFactory factory, final List expectedMethods) {
factory.getMethodCalls().clear();
expectedMethods.clear();
+ }
+
+ public void testMaxActiveLimit() throws Exception {
+ final int activeLimit = 15;
+ final MaxActiveLimitTesterFactory factory = new MaxActiveLimitTesterFactory();
+ final ObjectPool pool;
+ try {
+ pool = makeEmptyPoolWithActiveLimit(factory, activeLimit);
+ } catch (UnsupportedOperationException uoe) {
+ return; // test not supported
+ }
+
+ final ThreadGroup tg = new ThreadGroup("MaxActiveLimitTesters");
+ final Object lock = new Object();
+ final Runnable runnable = new MaxActiveLimitTester(pool, lock);
+ final Thread[] workers = new Thread[100];
+ synchronized (lock) {
+ for (int i=0; i < workers.length; i++) {
+ Thread t = new Thread(tg, runnable);
+ workers[i] = t;
+ t.start();
+ }
+ }
+ for (int i=0; i < workers.length; i++) {
+ workers[i].join();
+ }
+ assertEquals("Too many objects concurrently activated.", activeLimit, factory.getMaxActive());
+ }
+
+ private static class MaxActiveLimitTesterFactory extends BasePoolableObjectFactory {
+ private final Object lock = new Object();
+ private int count = 0;
+
+ private final Set activeSet = new HashSet();
+ private final Set passiveSet = new HashSet();
+ private int maxActive = 0;
+ private int maxPassive = 0;
+
+ public Object makeObject() throws Exception {
+ synchronized (lock) {
+ final Integer integer = new Integer(count++);
+ if (!activeSet.add(integer)) {
+ throw new AssertionError("umm, sync issue!");
+ }
+ return integer;
+ }
+ }
+
+ public void activateObject(final Object obj) throws Exception {
+ synchronized (lock) {
+ if (!passiveSet.remove(obj)) {
+ throw new AssertionError("Should never activate an object that isn't passive!");
+ }
+ activeSet.add(obj);
+ maxActive = Math.max(maxActive, activeSet.size());
+ }
+ }
+
+ public void passivateObject(Object obj) throws Exception {
+ synchronized (lock) {
+ if (!activeSet.remove(obj)) {
+ throw new Error("Should never passivate an object that isn't active!");
+ }
+ passiveSet.add(obj);
+ maxPassive = Math.max(maxPassive, passiveSet.size());
+ }
+ }
+
+ public void destroyObject(Object obj) throws Exception {
+ synchronized (lock) {
+ activeSet.remove(obj);
+ passiveSet.remove(obj);
+ }
+ }
+
+ public int getCount() {
+ return count;
+ }
+
+ public int getMaxActive() {
+ return maxActive;
+ }
+
+ public int getMaxPassive() {
+ return maxPassive;
+ }
+ }
+
+ private static class MaxActiveLimitTester implements Runnable {
+ private final ObjectPool pool;
+ private final Object lock;
+
+ MaxActiveLimitTester(final ObjectPool pool, final Object lock) {
+ this.pool = pool;
+ this.lock = lock;
+ }
+
+ public void run() {
+ synchronized (lock) { // wait for it...
+ } // go!
+ final long end = System.currentTimeMillis() + (30 * 1000);
+ while (System.currentTimeMillis() < end) {
+ try {
+ final Object o = pool.borrowObject();
+ Thread.yield();
+ pool.returnObject(o);
+ } catch (Exception e) {
+ }
+ }
+ }
}
}
Modified: jakarta/commons/proper/pool/branches/performance-ideas/src/test/org/apache/commons/pool/composite/PerformanceTest.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/pool/branches/performance-ideas/src/test/org/apache/commons/pool/composite/PerformanceTest.java?rev=406176&r1=406175&r2=406176&view=diff
==============================================================================
--- jakarta/commons/proper/pool/branches/performance-ideas/src/test/org/apache/commons/pool/composite/PerformanceTest.java (original)
+++ jakarta/commons/proper/pool/branches/performance-ideas/src/test/org/apache/commons/pool/composite/PerformanceTest.java Sat May 13 17:54:00 2006
@@ -298,7 +298,8 @@
System.out.print("GenericObjectPool\t" + ccg + "\t");
objectPool = ccg.getGeneric();
gopBPS = runThreadedTest(objectPool, numThreads, seconds);
- System.out.println(objectPool);
+ //System.out.println(objectPool);
+ System.out.println(ccg.objectFactory);
} catch (Exception e) {
System.out.println("exception thrown! " + e.getMessage());
}
@@ -310,7 +311,8 @@
System.out.print("CompositeObjectPool\t" + ccg + "\t");
objectPool = ccg.getComposite();
copBPS = runThreadedTest(objectPool, numThreads, seconds);
- System.out.println(objectPool);
+ //System.out.println(objectPool);
+ System.out.println(ccg.objectFactory);
} catch (Exception e) {
System.out.println("exception thrown! " + e.getMessage());
}
@@ -537,6 +539,13 @@
private int count = 0;
private boolean oddValid = true;
private boolean evenValid = true;
+ private final transient Object lock = new Object();
+ private transient int maxActive = 0;
+ private transient int maxIdle = 0;
+ private transient Set active = new HashSet(100);
+ private transient Set idle = new HashSet(100);
+ private transient Set destroyed = new HashSet(100);
+
public Object makeObject() throws Exception {
long end = System.currentTimeMillis() + 30;
@@ -544,7 +553,11 @@
while (end > System.currentTimeMillis()) {
Math.random();
}
- return new Integer(count++);
+ final int count;
+ synchronized (lock) {
+ count = this.count++;
+ }
+ return new Integer(count);
}
public boolean validateObject(final Object obj) {
@@ -565,6 +578,35 @@
}
}
+ public void activateObject(Object obj) throws Exception {
+ synchronized (lock) {
+ active.add(obj);
+ idle.remove(obj);
+ if (active.size() > maxActive) {
+ maxActive = active.size();
+ }
+ }
+ }
+
+ public void passivateObject(Object obj) throws Exception {
+ synchronized (lock) {
+ idle.add(obj);
+ active.remove(obj);
+ if (idle.size() > maxIdle) {
+ maxIdle = idle.size();
+ }
+ }
+ }
+
+ public void destroyObject(Object obj) throws Exception {
+ synchronized (lock) {
+ destroyed.add(obj);
+ idle.remove(obj);
+ active.remove(obj);
+ }
+
+ }
+
public void setValid(final boolean valid) {
setEvenValid(valid);
setOddValid(valid);
@@ -582,10 +624,22 @@
count = 0;
oddValid = true;
evenValid = true;
+ maxActive = 0;
+ maxIdle = 0;
+ active.clear();
+ idle.clear();
+ destroyed.clear();
}
public String toString() {
- return "IntegerFactory{}";
+ final StringBuffer sb = new StringBuffer();
+ sb.append("IntegerFactory");
+ sb.append("{count=").append(count);
+ sb.append(", maxIdle=").append(maxIdle);
+ sb.append(", maxActive=").append(maxActive);
+ sb.append(", destroyed=").append(destroyed.size());
+ sb.append('}');
+ return sb.toString();
}
}
Modified: jakarta/commons/proper/pool/branches/performance-ideas/src/test/org/apache/commons/pool/composite/TestAll.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/pool/branches/performance-ideas/src/test/org/apache/commons/pool/composite/TestAll.java?rev=406176&r1=406175&r2=406176&view=diff
==============================================================================
--- jakarta/commons/proper/pool/branches/performance-ideas/src/test/org/apache/commons/pool/composite/TestAll.java (original)
+++ jakarta/commons/proper/pool/branches/performance-ideas/src/test/org/apache/commons/pool/composite/TestAll.java Sat May 13 17:54:00 2006
@@ -62,7 +62,6 @@
// Remaining unit tests
suite.addTest(TestCompositeObjectPool.suite());
- suite.addTest(TestCompositeObjectPoolFullSync.suite());
suite.addTest(TestCompositeKeyedObjectPool.suite());
suite.addTest(TestCompositeKeyedObjectPool2.suite());
suite.addTest(TestCompositeObjectPoolFactory.suite());
Modified: jakarta/commons/proper/pool/branches/performance-ideas/src/test/org/apache/commons/pool/composite/TestCompositeObjectPool.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/pool/branches/performance-ideas/src/test/org/apache/commons/pool/composite/TestCompositeObjectPool.java?rev=406176&r1=406175&r2=406176&view=diff
==============================================================================
--- jakarta/commons/proper/pool/branches/performance-ideas/src/test/org/apache/commons/pool/composite/TestCompositeObjectPool.java (original)
+++ jakarta/commons/proper/pool/branches/performance-ideas/src/test/org/apache/commons/pool/composite/TestCompositeObjectPool.java Sat May 13 17:54:00 2006
@@ -29,6 +29,8 @@
import java.util.NoSuchElementException;
import java.util.SortedSet;
import java.util.TreeSet;
+import java.util.Set;
+import java.util.HashSet;
import junit.framework.Test;
import junit.framework.TestSuite;
@@ -67,6 +69,12 @@
return new CompositeObjectPool(factory, new GrowManager(), new FifoLender(), new SimpleTracker(), false);
}
+ protected ObjectPool makeEmptyPoolWithActiveLimit(final PoolableObjectFactory factory, final int activeLimit) throws UnsupportedOperationException {
+ final CompositeObjectPoolFactory copf = new CompositeObjectPoolFactory(factory);
+ copf.setMaxActive(activeLimit);
+ return copf.createPool();
+ }
+
public void testConstructors() {
try {
new CompositeObjectPool(null, new GrowManager(), new FifoLender(), new SimpleTracker(), false);
@@ -269,12 +277,56 @@
manager.setMaxWaitMillis(100);
pool = new CompositeObjectPool(new IntegerFactory(), manager, new FifoLender(), new DebugTracker(), false);
+ assertEquals(0, pool.getNumActive());
+
+ final Integer zero = (Integer)pool.borrowObject();
+ assertEquals(1, pool.getNumActive());
+
+ // Test that the max wait
try {
pool.borrowObject();
- fail("WaitLimitManager should fail with a normal CompositeObjectPool.");
- } catch (AssertionError ae) {
+ fail("Should have thrown a NoSuchElementException");
+ } catch(NoSuchElementException nsee) {
// expected
}
+
+ // test that if an object is returned while waiting it works.
+ // What happens is:
+ // this thread locks pool.pool and starts Thread t.
+ // this thread will get wait for an object to become available and relase the lock on pool.pool
+ // Thread t will then be able to lock on pool.pool and return an object
+ // this thread will then be able to borrow an object and should reutrn.
+ final List actualOrder = new ArrayList();
+ final Runnable r = new Runnable() {
+ public void run() {
+ try {
+ synchronized(pool.getPool()) {
+ pool.returnObject(zero);
+ actualOrder.add("returned");
+ }
+ } catch (Exception e) {
+ waitFailed = true;
+ }
+ }
+ };
+ final Thread t = new Thread(r);
+
+ synchronized (pool.getPool()) {
+ t.start();
+
+ actualOrder.add("waiting");
+ assertEquals(zero, pool.borrowObject());
+ actualOrder.add("borrowed");
+ }
+
+ assertEquals("Wait failed", false, waitFailed);
+
+ List expectedOrder = new ArrayList();
+ expectedOrder.add("waiting");
+ expectedOrder.add("returned");
+ expectedOrder.add("borrowed");
+
+ assertEquals(expectedOrder, actualOrder);
}
private boolean waitFailed = false;
Modified: jakarta/commons/proper/pool/branches/performance-ideas/src/test/org/apache/commons/pool/composite/TestWaitLimitManager.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/pool/branches/performance-ideas/src/test/org/apache/commons/pool/composite/TestWaitLimitManager.java?rev=406176&r1=406175&r2=406176&view=diff
==============================================================================
--- jakarta/commons/proper/pool/branches/performance-ideas/src/test/org/apache/commons/pool/composite/TestWaitLimitManager.java (original)
+++ jakarta/commons/proper/pool/branches/performance-ideas/src/test/org/apache/commons/pool/composite/TestWaitLimitManager.java Sat May 13 17:54:00 2006
@@ -57,7 +57,7 @@
}
protected CompositeObjectPool createPool(final PoolableObjectFactory pof, final Manager manager) {
- return new CompositeObjectPoolFullSync(pof, manager, new FifoLender(), new SimpleTracker(), false, null);
+ return new CompositeObjectPool(pof, manager, new FifoLender(), new SimpleTracker(), false, null);
}
public void testMaxWaitMillis() throws Exception {
Modified: jakarta/commons/proper/pool/branches/performance-ideas/src/test/org/apache/commons/pool/impl/TestGenericObjectPool.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/pool/branches/performance-ideas/src/test/org/apache/commons/pool/impl/TestGenericObjectPool.java?rev=406176&r1=406175&r2=406176&view=diff
==============================================================================
--- jakarta/commons/proper/pool/branches/performance-ideas/src/test/org/apache/commons/pool/impl/TestGenericObjectPool.java (original)
+++ jakarta/commons/proper/pool/branches/performance-ideas/src/test/org/apache/commons/pool/impl/TestGenericObjectPool.java Sat May 13 17:54:00 2006
@@ -53,6 +53,12 @@
return new GenericObjectPool(factory);
}
+ protected ObjectPool makeEmptyPoolWithActiveLimit(final PoolableObjectFactory factory, final int activeLimit) throws UnsupportedOperationException {
+ final GenericObjectPool pool = (GenericObjectPool)makeEmptyPool(factory);
+ pool.setMaxActive(activeLimit);
+ return pool;
+ }
+
protected Object getNthObject(int n) {
return String.valueOf(n);
}
Modified: jakarta/commons/proper/pool/branches/performance-ideas/src/test/org/apache/commons/pool/impl/TestSoftReferenceObjectPool.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/pool/branches/performance-ideas/src/test/org/apache/commons/pool/impl/TestSoftReferenceObjectPool.java?rev=406176&r1=406175&r2=406176&view=diff
==============================================================================
--- jakarta/commons/proper/pool/branches/performance-ideas/src/test/org/apache/commons/pool/impl/TestSoftReferenceObjectPool.java (original)
+++ jakarta/commons/proper/pool/branches/performance-ideas/src/test/org/apache/commons/pool/impl/TestSoftReferenceObjectPool.java Sat May 13 17:54:00 2006
@@ -55,6 +55,10 @@
return new SoftReferenceObjectPool(factory);
}
+ protected ObjectPool makeEmptyPoolWithActiveLimit(final PoolableObjectFactory factory, final int activeLimit) throws UnsupportedOperationException {
+ throw new UnsupportedOperationException("SoftReferenceObjectPool doesn't support an active limit.");
+ }
+
protected Object getNthObject(int n) {
return String.valueOf(n);
}
Modified: jakarta/commons/proper/pool/branches/performance-ideas/src/test/org/apache/commons/pool/impl/TestStackObjectPool.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/pool/branches/performance-ideas/src/test/org/apache/commons/pool/impl/TestStackObjectPool.java?rev=406176&r1=406175&r2=406176&view=diff
==============================================================================
--- jakarta/commons/proper/pool/branches/performance-ideas/src/test/org/apache/commons/pool/impl/TestStackObjectPool.java (original)
+++ jakarta/commons/proper/pool/branches/performance-ideas/src/test/org/apache/commons/pool/impl/TestStackObjectPool.java Sat May 13 17:54:00 2006
@@ -51,6 +51,10 @@
return new StackObjectPool(factory);
}
+ protected ObjectPool makeEmptyPoolWithActiveLimit(final PoolableObjectFactory factory, final int activeLimit) throws UnsupportedOperationException {
+ throw new UnsupportedOperationException("StackObjectPool doesn't support an active limit.");
+ }
+
protected Object getNthObject(int n) {
return String.valueOf(n);
}
---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org