Author: markt
Date: Thu Mar 24 11:32:07 2011
New Revision: 1084904

URL: http://svn.apache.org/viewvc?rev=1084904&view=rev
Log:
Additional fixes for POOL-180. Ensure the evictor tracks internal processing 
counts per key and remove unused keys only when they are truly unused.

Modified:
    
commons/proper/pool/trunk/src/java/org/apache/commons/pool2/impl/GenericKeyedObjectPool.java
    
commons/proper/pool/trunk/src/test/org/apache/commons/pool2/impl/TestGenericKeyedObjectPool.java

Modified: 
commons/proper/pool/trunk/src/java/org/apache/commons/pool2/impl/GenericKeyedObjectPool.java
URL: 
http://svn.apache.org/viewvc/commons/proper/pool/trunk/src/java/org/apache/commons/pool2/impl/GenericKeyedObjectPool.java?rev=1084904&r1=1084903&r2=1084904&view=diff
==============================================================================
--- 
commons/proper/pool/trunk/src/java/org/apache/commons/pool2/impl/GenericKeyedObjectPool.java
 (original)
+++ 
commons/proper/pool/trunk/src/java/org/apache/commons/pool2/impl/GenericKeyedObjectPool.java
 Thu Mar 24 11:32:07 2011
@@ -1164,6 +1164,12 @@ public class GenericKeyedObjectPool<K,V>
             if (pool != null) {
                 synchronized(this) {
                     pool.decrementActiveCount();
+                    if (pool.queue.isEmpty() &&
+                            pool.activeCount == 0 &&
+                            pool.internalProcessingCount == 0) {
+                        _poolMap.remove(key);
+                        _poolList.remove(key);
+                    }
                     allocate();
                 }
             }
@@ -1244,6 +1250,12 @@ public class GenericKeyedObjectPool<K,V>
             if (decrementNumActive) {
                 synchronized(this) {
                     pool.decrementActiveCount();
+                    if (pool.queue.isEmpty() &&
+                            pool.activeCount == 0 &&
+                            pool.internalProcessingCount == 0) {
+                        _poolMap.remove(key);
+                        _poolList.remove(key);
+                    }
                     allocate();
                 }
             }
@@ -1461,8 +1473,9 @@ public class GenericKeyedObjectPool<K,V>
                         _evictionCursor.previous() :
                         _evictionCursor.next();
                 _evictionCursor.remove();
+                ObjectQueue objectQueue = _poolMap.get(key);
+                objectQueue.incrementInternalProcessingCount();
                 _totalIdle--;
-                _totalInternalProcessing++;
             }
 
             boolean removeObject=false;
@@ -1497,28 +1510,19 @@ public class GenericKeyedObjectPool<K,V>
                     _factory.destroyObject(key, pair.getValue());
                 } catch(Exception e) {
                     // ignored
-                } finally {
-                    // Do not remove the key from the _poolList or _poolmap,
-                    // even if the list stored in the _poolMap for this key is
-                    // empty when minIdle > 0.
-                    //
-                    // Otherwise if it was the last object for that key,
-                    // drop that pool
-                    if (this.minIdlePerKey == 0) {
-                        synchronized (this) {
-                            ObjectQueue objectQueue =
-                                _poolMap.get(key);
-                            if (objectQueue != null &&
-                                    objectQueue.queue.isEmpty()) {
-                                _poolMap.remove(key);
-                                _poolList.remove(key);
-                            }
-                        }
-                    }
                 }
             }
             synchronized (this) {
-                if (!removeObject) {
+                ObjectQueue objectQueue = _poolMap.get(key);
+                objectQueue.decrementInternalProcessingCount();
+                if (removeObject) {
+                    if (objectQueue.queue.isEmpty() &&
+                            objectQueue.activeCount == 0 &&
+                            objectQueue.internalProcessingCount == 0) {
+                        _poolMap.remove(key);
+                        _poolList.remove(key);
+                    }
+                } else {
                     _evictionCursor.add(pair);
                     _totalIdle++;
                     if (this.lifo) {
@@ -1526,8 +1530,8 @@ public class GenericKeyedObjectPool<K,V>
                         _evictionCursor.previous();
                     }
                 }
-                _totalInternalProcessing--;
             }
+
         }
         allocate();
     }

Modified: 
commons/proper/pool/trunk/src/test/org/apache/commons/pool2/impl/TestGenericKeyedObjectPool.java
URL: 
http://svn.apache.org/viewvc/commons/proper/pool/trunk/src/test/org/apache/commons/pool2/impl/TestGenericKeyedObjectPool.java?rev=1084904&r1=1084903&r2=1084904&view=diff
==============================================================================
--- 
commons/proper/pool/trunk/src/test/org/apache/commons/pool2/impl/TestGenericKeyedObjectPool.java
 (original)
+++ 
commons/proper/pool/trunk/src/test/org/apache/commons/pool2/impl/TestGenericKeyedObjectPool.java
 Thu Mar 24 11:32:07 2011
@@ -755,36 +755,43 @@ public class TestGenericKeyedObjectPool 
         
         pool.evict(); // Kill (0,0),(0,1)
         assertEquals(3, pool.getNumIdle(zero));
-        Object obj = pool.borrowObject(zero);
-        assertTrue(lifo ? obj.equals("04") : obj.equals("02"));
+        String objZeroA = pool.borrowObject(zero);
+        assertTrue(lifo ? objZeroA.equals("04") : objZeroA.equals("02"));
         assertEquals(2, pool.getNumIdle(zero));
-        obj = pool.borrowObject(zero);
-        assertTrue(obj.equals("03"));
+        String objZeroB = pool.borrowObject(zero);
+        assertTrue(objZeroB.equals("03"));
         assertEquals(1, pool.getNumIdle(zero));
         
         pool.evict(); // Kill remaining 0 survivor and (1,5)
         assertEquals(0, pool.getNumIdle(zero));
         assertEquals(4, pool.getNumIdle(one));
-        obj = pool.borrowObject(one);
-        assertTrue(lifo ? obj.equals("19") : obj.equals("16"));
+        String objOneA = pool.borrowObject(one);
+        assertTrue(lifo ? objOneA.equals("19") : objOneA.equals("16"));
         assertEquals(3, pool.getNumIdle(one));
-        obj = pool.borrowObject(one);
-        assertTrue(lifo ? obj.equals("18") : obj.equals("17"));
+        String objOneB = pool.borrowObject(one);
+        assertTrue(lifo ? objOneB.equals("18") : objOneB.equals("17"));
         assertEquals(2, pool.getNumIdle(one));
         
         pool.evict(); // Kill remaining 1 survivors
         assertEquals(0, pool.getNumIdle(one));
         pool.evict(); // Kill (2,10), (2,11)
         assertEquals(3, pool.getNumIdle(two));
-        obj = pool.borrowObject(two);
-        assertTrue(lifo ? obj.equals("214") : obj.equals("212"));
+        String objTwoA = pool.borrowObject(two);
+        assertTrue(lifo ? objTwoA.equals("214") : objTwoA.equals("212"));
         assertEquals(2, pool.getNumIdle(two));
         pool.evict(); // All dead now
         assertEquals(0, pool.getNumIdle(two));  
         
         pool.evict(); // Should do nothing - make sure no exception
-        pool.evict();
-        
+        // Currently 2 zero, 2 one and 1 two active. Return them
+        pool.returnObject(zero, objZeroA);
+        pool.returnObject(zero, objZeroB);
+        pool.returnObject(one, objOneA);
+        pool.returnObject(one, objOneB);
+        pool.returnObject(two, objTwoA);
+        // Remove all idle objects
+        pool.clear();
+
         // Reload
         pool.setMinEvictableIdleTimeMillis(500);
         factory.counter = 0; // Reset counter
@@ -824,7 +831,7 @@ public class TestGenericKeyedObjectPool 
         pool.evict(); // kill (1,6), (1,7) - (1,5) missed
         assertEquals(3, pool.getNumIdle(one));
         assertEquals(5, pool.getNumIdle(two));
-        obj = pool.borrowObject(one);
+        String obj = pool.borrowObject(one);
         assertTrue(lifo ? obj.equals("19") : obj.equals("15"));  
     }
     


Reply via email to