[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