Author: markt
Date: Wed Mar 23 17:05:44 2011
New Revision: 1084641

URL: http://svn.apache.org/viewvc?rev=1084641&view=rev
Log:
Fix POOL-180. Only stop tracking objects for a key when there are no idle 
objects, no active objects and no objects being processed.

Modified:
    commons/proper/pool/branches/POOL_1_X/src/changes/changes.xml
    
commons/proper/pool/branches/POOL_1_X/src/java/org/apache/commons/pool/impl/GenericKeyedObjectPool.java
    
commons/proper/pool/branches/POOL_1_X/src/test/org/apache/commons/pool/impl/TestGenericKeyedObjectPool.java

Modified: commons/proper/pool/branches/POOL_1_X/src/changes/changes.xml
URL: 
http://svn.apache.org/viewvc/commons/proper/pool/branches/POOL_1_X/src/changes/changes.xml?rev=1084641&r1=1084640&r2=1084641&view=diff
==============================================================================
--- commons/proper/pool/branches/POOL_1_X/src/changes/changes.xml (original)
+++ commons/proper/pool/branches/POOL_1_X/src/changes/changes.xml Wed Mar 23 
17:05:44 2011
@@ -25,6 +25,10 @@
       Correctly handle an InterruptedException when waiting for an object from
       the pool.
     </action>
+    <action dev="markt" type="fix" issue="POOL-180">
+      Only stop tracking objects for a key when there are no idle objects, no
+      active objects and no objects being processed.
+    </action>
   </release>
   <release version="1.5.5" date="2010-09-10" description=
      "This is a patch release, including bugfixes, documentation improvements 
and some deprecations

Modified: 
commons/proper/pool/branches/POOL_1_X/src/java/org/apache/commons/pool/impl/GenericKeyedObjectPool.java
URL: 
http://svn.apache.org/viewvc/commons/proper/pool/branches/POOL_1_X/src/java/org/apache/commons/pool/impl/GenericKeyedObjectPool.java?rev=1084641&r1=1084640&r2=1084641&view=diff
==============================================================================
--- 
commons/proper/pool/branches/POOL_1_X/src/java/org/apache/commons/pool/impl/GenericKeyedObjectPool.java
 (original)
+++ 
commons/proper/pool/branches/POOL_1_X/src/java/org/apache/commons/pool/impl/GenericKeyedObjectPool.java
 Wed Mar 23 17:05:44 2011
@@ -1404,8 +1404,8 @@ public class GenericKeyedObjectPool exte
                 // key references is the key of the list it belongs to.
                 Object key = entry.getValue();
                 ObjectTimestampPair pairTimeStamp = (ObjectTimestampPair) 
entry.getKey();
-                final CursorableLinkedList list =
-                    ((ObjectQueue)(_poolMap.get(key))).queue;
+                ObjectQueue objectQueue = (ObjectQueue)_poolMap.get(key);
+                final CursorableLinkedList list = objectQueue.queue;
                 list.remove(pairTimeStamp);
 
                 if (toDestroy.containsKey(key)) {
@@ -1415,13 +1415,8 @@ public class GenericKeyedObjectPool exte
                     listForKey.add(pairTimeStamp);
                     toDestroy.put(key, listForKey);
                 }
-                // if that was the last object for that key, drop that pool
-                if (list.isEmpty()) {
-                    _poolMap.remove(key);
-                    _poolList.remove(key);
-                }
+                objectQueue.incrementInternalProcessingCount();
                 _totalIdle--;
-                _totalInternalProcessing++;
                 itemsToRemove--;
             }
 
@@ -1478,7 +1473,17 @@ public class GenericKeyedObjectPool exte
                     // ignore error, keep destroying the rest
                 } finally {
                     synchronized(this) {
-                        _totalInternalProcessing--;
+                        ObjectQueue objectQueue =
+                                (ObjectQueue) _poolMap.get(key);
+                        if (objectQueue != null) {
+                            objectQueue.decrementInternalProcessingCount();
+                            if (objectQueue.internalProcessingCount == 0 &&
+                                    objectQueue.activeCount == 0 &&
+                                    objectQueue.queue.isEmpty()) {
+                                _poolMap.remove(key);
+                                _poolList.remove(key);
+                            }
+                        }
                         allocate();
                     }
                 }

Modified: 
commons/proper/pool/branches/POOL_1_X/src/test/org/apache/commons/pool/impl/TestGenericKeyedObjectPool.java
URL: 
http://svn.apache.org/viewvc/commons/proper/pool/branches/POOL_1_X/src/test/org/apache/commons/pool/impl/TestGenericKeyedObjectPool.java?rev=1084641&r1=1084640&r2=1084641&view=diff
==============================================================================
--- 
commons/proper/pool/branches/POOL_1_X/src/test/org/apache/commons/pool/impl/TestGenericKeyedObjectPool.java
 (original)
+++ 
commons/proper/pool/branches/POOL_1_X/src/test/org/apache/commons/pool/impl/TestGenericKeyedObjectPool.java
 Wed Mar 23 17:05:44 2011
@@ -28,6 +28,7 @@ import org.apache.commons.pool.KeyedPool
 import org.apache.commons.pool.TestBaseKeyedObjectPool;
 import org.apache.commons.pool.VisitTracker;
 import org.apache.commons.pool.VisitTrackerFactory;
+import org.apache.commons.pool.WaiterFactory;
 
 /**
  * @author Rodney Waldhoff
@@ -1398,6 +1399,20 @@ public class TestGenericKeyedObjectPool 
         assertEquals("Expected half the threads to fail",wtt.length/2,failed);
     }
 
+    /**
+     * Test case for POOL-180.
+     */
+    public void testMaxActivePerKeyExceeded() {
+        WaiterFactory factory = new WaiterFactory(0, 20, 0, 0, 0, 0, 8, 5, 0);
+        pool = new GenericKeyedObjectPool(factory);
+        pool.setMaxActive(5);
+        pool.setMaxTotal(8);
+        pool.setTestOnBorrow(true);
+        pool.setMaxIdle(5);
+        pool.setMaxWait(-1);
+        runTestThreads(20, 300, 250);
+    }
+    
     /*
      * Very simple test thread that just tries to borrow an object from
      * the provided pool with the specified key and returns it


Reply via email to