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

davsclaus pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git

commit bef1c22700930ad1d493890d216e5ac9b5374663
Author: Krzysztof Jamróz <[email protected]>
AuthorDate: Fri Jan 21 19:23:19 2022 +0100

    CAMEL-17536 Fixed: ServicePool.doStop hangs during shutdown
---
 .../java/org/apache/camel/support/cache/ServicePool.java    | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git 
a/core/camel-support/src/main/java/org/apache/camel/support/cache/ServicePool.java
 
b/core/camel-support/src/main/java/org/apache/camel/support/cache/ServicePool.java
index a797ec8..4ac811b 100644
--- 
a/core/camel-support/src/main/java/org/apache/camel/support/cache/ServicePool.java
+++ 
b/core/camel-support/src/main/java/org/apache/camel/support/cache/ServicePool.java
@@ -51,6 +51,8 @@ abstract class ServicePool<S extends Service> extends 
ServiceSupport implements
     private final ConcurrentMap<Endpoint, Pool<S>> singlePoolEvicted = new 
ConcurrentHashMap<>();
     private int capacity;
     private Map<S, S> cache;
+    // synchronizes access only to cache
+    private final Object cacheLock;
 
     private interface Pool<S> {
         S acquire() throws Exception;
@@ -71,6 +73,7 @@ abstract class ServicePool<S extends Service> extends 
ServiceSupport implements
         this.getEndpoint = getEndpoint;
         this.capacity = capacity;
         this.cache = capacity > 0 ? LRUCacheFactory.newLRUCache(capacity, 
this::onEvict) : null;
+        this.cacheLock = capacity > 0 ? new Object() : null;
     }
 
     /**
@@ -108,7 +111,9 @@ abstract class ServicePool<S extends Service> extends 
ServiceSupport implements
         }
         S s = getOrCreatePool(endpoint).acquire();
         if (s != null && cache != null) {
-            cache.putIfAbsent(s, s);
+            synchronized (cacheLock) {
+                cache.putIfAbsent(s, s);
+            }
         }
         return s;
     }
@@ -178,8 +183,10 @@ abstract class ServicePool<S extends Service> extends 
ServiceSupport implements
         pool.values().forEach(Pool::stop);
         pool.clear();
         if (cache != null) {
-            cache.values().forEach(ServicePool::stop);
-            cache.clear();
+            synchronized (cacheLock) {
+                cache.values().forEach(ServicePool::stop);
+                cache.clear();
+            }
         }
         singlePoolEvicted.values().forEach(Pool::stop);
         singlePoolEvicted.clear();

Reply via email to