From 6a60d902b86ea0d983338195314a3344efd60cd0 Mon Sep 17 00:00:00 2001 From: "Brian S. O'Neill" Date: Sat, 11 Nov 2006 00:43:33 +0000 Subject: Fixed deadlock when using unsupported Storage for the first time. --- .../amazon/carbonado/spi/StorageCollection.java | 57 ++++++++++++---------- 1 file changed, 32 insertions(+), 25 deletions(-) (limited to 'src/main/java/com/amazon') diff --git a/src/main/java/com/amazon/carbonado/spi/StorageCollection.java b/src/main/java/com/amazon/carbonado/spi/StorageCollection.java index f0d38ad..45ab6f5 100644 --- a/src/main/java/com/amazon/carbonado/spi/StorageCollection.java +++ b/src/main/java/com/amazon/carbonado/spi/StorageCollection.java @@ -70,35 +70,42 @@ public abstract class StorageCollection { } } - synchronized (lock) { - // Check storage map again before creating new storage. - while (true) { - storage = mStorageMap.get(type); - if (storage != null) { - return storage; - } - if (doCreate) { - break; - } - try { - lock.wait(); - } catch (InterruptedException e) { - throw new RepositoryException("Interrupted"); - } - } + if (Thread.holdsLock(lock)) { + throw new IllegalStateException + ("Recursively trying to create storage for type: " + type); + } - // Examine and throw exception early if there is a problem. - StorableIntrospector.examine(type); + try { + synchronized (lock) { + // Check storage map again before creating new storage. + while (true) { + storage = mStorageMap.get(type); + if (storage != null) { + return storage; + } + if (doCreate) { + break; + } + try { + lock.wait(); + } catch (InterruptedException e) { + throw new RepositoryException("Interrupted"); + } + } - storage = createStorage(type); + // Examine and throw exception early if there is a problem. + StorableIntrospector.examine(type); - mStorageMap.put(type, storage); - lock.notifyAll(); - } + storage = createStorage(type); - // Storable type lock no longer needed. - synchronized (mStorableTypeLockMap) { - mStorableTypeLockMap.remove(type); + mStorageMap.put(type, storage); + lock.notifyAll(); + } + } finally { + // Storable type lock no longer needed. + synchronized (mStorableTypeLockMap) { + mStorableTypeLockMap.remove(type); + } } return storage; -- cgit v1.2.3