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();
