Index: core/src/main/java/org/infinispan/manager/DefaultCacheManager.java =================================================================== --- core/src/main/java/org/infinispan/manager/DefaultCacheManager.java (revision 2324) +++ core/src/main/java/org/infinispan/manager/DefaultCacheManager.java (revision ) @@ -22,6 +22,7 @@ package org.infinispan.manager; import org.infinispan.Cache; +import org.infinispan.CacheException; import org.infinispan.Version; import org.infinispan.config.Configuration; import org.infinispan.config.ConfigurationException; @@ -44,6 +45,7 @@ import org.infinispan.remoting.transport.Address; import org.infinispan.remoting.transport.Transport; import org.infinispan.util.Immutables; +import org.infinispan.util.concurrent.locks.containers.ReentrantPerEntryLockContainer; import org.infinispan.util.logging.Log; import org.infinispan.util.logging.LogFactory; import org.rhq.helpers.pluginAnnotations.agent.DataType; @@ -64,6 +66,8 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; +import static java.util.concurrent.TimeUnit.MILLISECONDS; + /** * A CacheManager is the primary mechanism for retrieving a {@link Cache} instance, and is often used as a * starting point to using the {@link Cache}. @@ -113,6 +117,7 @@ private final ConcurrentMap caches = new ConcurrentHashMap(); private final ConcurrentMap configurationOverrides = new ConcurrentHashMap(); private final GlobalComponentRegistry globalComponentRegistry; + private final ReentrantPerEntryLockContainer cacheNameLockContainer; /** * Constructs and starts a default instance of the CacheManager, using configuration defaults. See {@link Configuration} @@ -200,7 +205,8 @@ this.globalConfiguration.accept(new ConfigurationValidatingVisitor()); this.defaultConfiguration = defaultConfiguration == null ? new Configuration() : defaultConfiguration.clone(); this.defaultConfiguration.accept(new ConfigurationValidatingVisitor()); - globalComponentRegistry = new GlobalComponentRegistry(this.globalConfiguration, this); + this.globalComponentRegistry = new GlobalComponentRegistry(this.globalConfiguration, this); + this.cacheNameLockContainer = new ReentrantPerEntryLockContainer(this.defaultConfiguration.getConcurrencyLevel()); if (start) start(); } @@ -239,6 +245,7 @@ configurationOverrides.put(entry.getKey(), c); } globalComponentRegistry = new GlobalComponentRegistry(globalConfiguration, this); + cacheNameLockContainer = new ReentrantPerEntryLockContainer(defaultConfiguration.getConcurrencyLevel()); } catch (RuntimeException re) { throw new ConfigurationException(re); } @@ -280,6 +287,7 @@ configurationOverrides.put(entry.getKey(), c); } globalComponentRegistry = new GlobalComponentRegistry(globalConfiguration, this); + cacheNameLockContainer = new ReentrantPerEntryLockContainer(defaultConfiguration.getConcurrencyLevel()); } catch (ConfigurationException ce) { throw ce; } catch (RuntimeException re) { @@ -329,7 +337,7 @@ } globalComponentRegistry = new GlobalComponentRegistry(this.globalConfiguration, this); - + cacheNameLockContainer = new ReentrantPerEntryLockContainer(defaultConfiguration.getConcurrencyLevel()); } catch (RuntimeException re) { throw new ConfigurationException(re); } @@ -406,11 +414,26 @@ if (cacheName == null) throw new NullPointerException("Null arguments not allowed"); - if (caches.containsKey(cacheName)) + Cache cache = caches.get(cacheName); + if (cache != null && cache.getStatus() == ComponentStatus.RUNNING) return caches.get(cacheName); + boolean acquired = false; + try { + if (cacheNameLockContainer.acquireLock(cacheName, defaultConfiguration.getLockAcquisitionTimeout(), MILLISECONDS) != null) { + acquired = true; - return createCache(cacheName); + return createCache(cacheName); + } else { + throw new CacheException("Unable to acquire lock on cache with name " + cacheName); - } + } + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw new CacheException("Interrupted while trying to get lock on cache with cache name " + cacheName, e); + } finally { + if (acquired) + cacheNameLockContainer.releaseLock(cacheName); + } + } public String getClusterName() { return globalConfiguration.getClusterName();