This is an automated email from the ASF dual-hosted git repository.

ggregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-pool.git


The following commit(s) were added to refs/heads/master by this push:
     new 354b445c [POOL-411] NPE when deregistering key at end of borrow
354b445c is described below

commit 354b445c75e4bee819577548f25da94cc9b8831c
Author: Gary Gregory <[email protected]>
AuthorDate: Fri Jul 7 19:44:08 2023 -0400

    [POOL-411] NPE when deregistering key at end of borrow
---
 .../commons/pool2/impl/GenericKeyedObjectPool.java | 41 +++++++++++-----------
 1 file changed, 20 insertions(+), 21 deletions(-)

diff --git 
a/src/main/java/org/apache/commons/pool2/impl/GenericKeyedObjectPool.java 
b/src/main/java/org/apache/commons/pool2/impl/GenericKeyedObjectPool.java
index 0f8a275d..5500f48a 100644
--- a/src/main/java/org/apache/commons/pool2/impl/GenericKeyedObjectPool.java
+++ b/src/main/java/org/apache/commons/pool2/impl/GenericKeyedObjectPool.java
@@ -30,6 +30,7 @@ import java.util.Objects;
 import java.util.TreeMap;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.atomic.AtomicLong;
 import java.util.concurrent.locks.Lock;
@@ -833,20 +834,17 @@ public class GenericKeyedObjectPool<K, T, E extends 
Exception> extends BaseGener
             lock.lock();
             final ObjectDeque<T> objectDeque = poolMap.get(k);
             if (objectDeque != null) {
-                final long numInterested = 
objectDeque.getNumInterested().decrementAndGet();
-                if (numInterested == 0 && objectDeque.getCreateCount().get() 
== 0) {
-                    // Potential to remove key
-                    // Upgrade to write lock
-                    lock.unlock();
-                    lock = keyLock.writeLock();
-                    lock.lock();
-                    if (objectDeque.getCreateCount().get() == 0 && 
objectDeque.getNumInterested().get() == 0) {
-                        // NOTE: Keys must always be removed from both poolMap 
and
-                        // poolKeyList at the same time while protected by
-                        // keyLock.writeLock()
-                        poolMap.remove(k);
-                        poolKeyList.remove(k);
-                    }
+                // Potential to remove key
+                // Upgrade to write lock
+                lock.unlock();
+                lock = keyLock.writeLock();
+                lock.lock();
+                if (objectDeque.getNumInterested().decrementAndGet() == 0 && 
objectDeque.getCreateCount().get() == 0) {
+                    // NOTE: Keys must always be removed from both poolMap and
+                    // poolKeyList at the same time while protected by
+                    // keyLock.writeLock()
+                    poolMap.remove(k);
+                    poolKeyList.remove(k);
                 }
             }
         } finally {
@@ -1385,16 +1383,17 @@ public class GenericKeyedObjectPool<K, T, E extends 
Exception> extends BaseGener
                 lock.unlock();
                 lock = keyLock.writeLock();
                 lock.lock();
-                objectDeque = poolMap.get(k);
-                if (objectDeque == null) {
-                    objectDeque = new ObjectDeque<>(fairness);
-                    objectDeque.getNumInterested().incrementAndGet();
+                final AtomicBoolean allocated = new AtomicBoolean(); 
+                objectDeque = poolMap.computeIfAbsent(k, key -> {
+                    allocated.set(true);
+                    final ObjectDeque<T> deque = new ObjectDeque<>(fairness);
+                    deque.getNumInterested().incrementAndGet();
                     // NOTE: Keys must always be added to both poolMap and
                     //       poolKeyList at the same time while protected by
-                    //       keyLock.writeLock()
-                    poolMap.put(k, objectDeque);
                     poolKeyList.add(k);
-                } else {
+                    return deque;
+                });
+                if (!allocated.get()) {
                     objectDeque.getNumInterested().incrementAndGet();
                 }
             } else {

Reply via email to