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