[infinispan-commits] Infinispan SVN: r989 - trunk/core/src/main/java/org/infinispan/factories.
infinispan-commits at lists.jboss.org
infinispan-commits at lists.jboss.org
Fri Oct 23 08:45:59 EDT 2009
Author: mircea.markus
Date: 2009-10-23 08:45:59 -0400 (Fri, 23 Oct 2009)
New Revision: 989
Modified:
trunk/core/src/main/java/org/infinispan/factories/EntryFactoryImpl.java
Log:
[ISPN-227] - (Have Lucene LockManager use atomic operations) - fixed race condition
Modified: trunk/core/src/main/java/org/infinispan/factories/EntryFactoryImpl.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/factories/EntryFactoryImpl.java 2009-10-23 09:56:08 UTC (rev 988)
+++ trunk/core/src/main/java/org/infinispan/factories/EntryFactoryImpl.java 2009-10-23 12:45:59 UTC (rev 989)
@@ -140,23 +140,28 @@
if (trace) log.trace("Retrieved from container.");
// exists in cache! Just acquire lock if needed, and wrap.
// do we need a lock?
- boolean needToCopy = alreadyLocked || acquireLock(ctx, key) || ctx.hasFlag(Flag.SKIP_LOCKING); // even if we do not acquire a lock, if skip-locking is enabled we should copy
- mvccEntry = createWrappedEntry(key, cacheEntry.getValue(), false, false, cacheEntry.getLifespan());
- ctx.putLookedUpEntry(key, mvccEntry);
- if (needToCopy) mvccEntry.copyForUpdate(container, writeSkewCheck);
- cacheEntry = mvccEntry;
+ boolean lockAcquired = acquireLock(ctx, key);
+ mvccEntry = wrapExistingEntryForWriting(ctx, key, alreadyLocked, cacheEntry, lockAcquired);
} else if (createIfAbsent) {
// this is the *only* point where new entries can be created!!
if (trace) log.trace("Creating new entry.");
+
+ boolean lockAcquired = false;
// now to lock and create the entry. Lock first to prevent concurrent creation!
- if (!alreadyLocked) acquireLock(ctx, key);
- notifier.notifyCacheEntryCreated(key, true, ctx);
- mvccEntry = createWrappedEntry(key, null, true, false, -1);
- mvccEntry.setCreated(true);
- ctx.putLookedUpEntry(key, mvccEntry);
- mvccEntry.copyForUpdate(container, writeSkewCheck);
- notifier.notifyCacheEntryCreated(key, false, ctx);
- cacheEntry = mvccEntry;
+ if (!alreadyLocked) {
+ lockAcquired = acquireLock(ctx, key);
+ }
+ if (lockAcquired) {
+ //double check existance, as the prev lock owner might have created a cache entry for the same key
+ cacheEntry = container.get(key);
+ if (cacheEntry != null) {
+ mvccEntry = wrapExistingEntryForWriting(ctx, key, true, cacheEntry, lockAcquired);
+ } else {
+ mvccEntry = createAndWrapEntryForWriting(ctx, key);
+ }
+ } else {
+ mvccEntry = createAndWrapEntryForWriting(ctx, key);
+ }
}
}
@@ -169,6 +174,26 @@
return mvccEntry;
}
+ private MVCCEntry createAndWrapEntryForWriting(InvocationContext ctx, Object key) {
+ MVCCEntry mvccEntry;
+ notifier.notifyCacheEntryCreated(key, true, ctx);
+ mvccEntry = createWrappedEntry(key, null, true, false, -1);
+ mvccEntry.setCreated(true);
+ ctx.putLookedUpEntry(key, mvccEntry);
+ mvccEntry.copyForUpdate(container, writeSkewCheck);
+ notifier.notifyCacheEntryCreated(key, false, ctx);
+ return mvccEntry;
+ }
+
+ private MVCCEntry wrapExistingEntryForWriting(InvocationContext ctx, Object key, boolean alreadyLocked, CacheEntry cacheEntry, boolean lockAquired) {
+ MVCCEntry mvccEntry;
+ mvccEntry = createWrappedEntry(key, cacheEntry.getValue(), false, false, cacheEntry.getLifespan());
+ ctx.putLookedUpEntry(key, mvccEntry);
+ boolean needToCopy = alreadyLocked || lockAquired || ctx.hasFlag(Flag.SKIP_LOCKING); // even if we do not acquire a lock, if skip-locking is enabled we should copy
+ if (needToCopy) mvccEntry.copyForUpdate(container, writeSkewCheck);
+ return mvccEntry;
+ }
+
/**
* Attempts to lock an entry if the lock isn't already held in the current scope, and records the lock in the
* context.
More information about the infinispan-commits
mailing list