[jbosscache-commits] JBoss Cache SVN: r8167 - in core/trunk/src/main/java/org/jboss/cache: lock and 1 other directory.

jbosscache-commits at lists.jboss.org jbosscache-commits at lists.jboss.org
Fri Aug 7 06:59:23 EDT 2009


Author: manik.surtani at jboss.com
Date: 2009-08-07 06:59:23 -0400 (Fri, 07 Aug 2009)
New Revision: 8167

Modified:
   core/trunk/src/main/java/org/jboss/cache/PessimisticUnversionedNode.java
   core/trunk/src/main/java/org/jboss/cache/lock/PessimisticNodeBasedLockManager.java
Log:
Remove node creation race

Modified: core/trunk/src/main/java/org/jboss/cache/PessimisticUnversionedNode.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/PessimisticUnversionedNode.java	2009-08-07 10:28:08 UTC (rev 8166)
+++ core/trunk/src/main/java/org/jboss/cache/PessimisticUnversionedNode.java	2009-08-07 10:59:23 UTC (rev 8167)
@@ -26,6 +26,7 @@
 import org.jboss.cache.commands.legacy.write.CreateNodeCommand;
 import org.jboss.cache.lock.IdentityLock;
 import org.jboss.cache.lock.LockStrategyFactory;
+import org.jboss.cache.lock.PessimisticNodeBasedLockManager;
 import org.jboss.cache.marshall.MarshalledValue;
 import org.jboss.cache.transaction.GlobalTransaction;
 import org.jboss.cache.util.FastCopyHashMap;
@@ -161,7 +162,7 @@
          throw new CacheException("Attempting to add a child [" + child.getFqn() + "] to [" + getFqn() + "].  Can only add direct children.");
    }
 
-   private NodeSPI<K, V> getOrCreateChild(Object childName, GlobalTransaction gtx, boolean createIfNotExists, boolean notify)
+   private NodeSPI<K, V> getOrCreateChild(Object childName, GlobalTransaction gtx, boolean createIfNotExists, boolean notify, PessimisticNodeBasedLockManager.LockAcquirer la)
    {
       NodeSPI<K, V> child;
       if (childName == null)
@@ -190,6 +191,7 @@
             {
                if (notify) cache.getNotifier().notifyNodeCreated(childFqn, true, ctx);
                child = newChild;
+               if (la != null) la.acquire(child);
                children().put(childName, child);
             }
          }
@@ -216,7 +218,7 @@
       if (f.size() == 1)
       {
          GlobalTransaction gtx = cache.getInvocationContext().getGlobalTransaction();
-         return getOrCreateChild(f.getLastElement(), gtx, true, notify);
+         return getOrCreateChild(f.getLastElement(), gtx, true, notify, null);
       }
       else
       {
@@ -228,9 +230,15 @@
    public NodeSPI<K, V> addChildDirect(Object o, boolean notify)
    {
       GlobalTransaction gtx = cache.getInvocationContext().getGlobalTransaction();
-      return getOrCreateChild(o, gtx, true, notify);
+      return getOrCreateChild(o, gtx, true, notify, null);
    }
 
+   public NodeSPI<K, V> addChildAndAcquireLock(Object o, PessimisticNodeBasedLockManager.LockAcquirer la)
+   {
+      GlobalTransaction gtx = cache.getInvocationContext().getGlobalTransaction();
+      return getOrCreateChild(o, gtx, true, false, la);
+   }
+
    @Override
    public NodeSPI<K, V> getChildDirect(Fqn fqn)
    {
@@ -331,7 +339,7 @@
    @Override
    public NodeSPI<K, V> getOrCreateChild(Object childName, GlobalTransaction gtx)
    {
-      return getOrCreateChild(childName, gtx, true, true);
+      return getOrCreateChild(childName, gtx, true, true, null);
    }
 
    @Override

Modified: core/trunk/src/main/java/org/jboss/cache/lock/PessimisticNodeBasedLockManager.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/lock/PessimisticNodeBasedLockManager.java	2009-08-07 10:28:08 UTC (rev 8166)
+++ core/trunk/src/main/java/org/jboss/cache/lock/PessimisticNodeBasedLockManager.java	2009-08-07 10:59:23 UTC (rev 8167)
@@ -26,6 +26,7 @@
 import org.jboss.cache.Fqn;
 import org.jboss.cache.InvocationContext;
 import org.jboss.cache.NodeSPI;
+import org.jboss.cache.PessimisticUnversionedNode;
 import org.jboss.cache.commands.CommandsFactory;
 import org.jboss.cache.factories.annotations.Inject;
 import static org.jboss.cache.lock.LockType.WRITE;
@@ -137,12 +138,15 @@
 
       do
       {
+         boolean skipLockAcquire = false;
          if (currentNode == null)
          {
             if (createIfNotExists)
             {
                // if the new node is to be marked as deleted, do not notify!
-               currentNode = parent.addChildDirect(childName, !skipNotification);
+               PessimisticUnversionedNode parentInternalNode = (PessimisticUnversionedNode) parent.getDelegationTarget();
+               currentNode = parentInternalNode.addChildAndAcquireLock(childName, new LockAcquirer(ctx, WRITE, timeout, owner));
+               skipLockAcquire = true;
                if (!created)
                {
                   created = true;
@@ -171,8 +175,12 @@
          
 
          Fqn currentNodeFqn = currentNode.getFqn();
-         // actually acquire the lock we need.  This method blocks.
-         acquireNodeLock(ctx, currentNode, owner, lockTypeRequired, timeout);
+         if (!skipLockAcquire)
+         {
+            // actually acquire the lock we need.  This method blocks.
+            acquireNodeLock(ctx, currentNode, owner, lockTypeRequired, timeout);
+         }
+            
 
          LockUtil.manageReverseRemove(ctx, currentNode, reverseRemoveCheck, createdNodes, commandsFactory);
          // make sure the lock we acquired isn't on a deleted node/is an orphan!!
@@ -274,4 +282,31 @@
       // Record the lock for release on method return or tx commit/rollback
       if (acquired) ctx.addLock(lock);
    }
+
+   public class LockAcquirer
+   {
+      InvocationContext ctx;
+      LockType type;
+      long timeout;
+      Object owner;
+
+      public LockAcquirer(InvocationContext ctx, LockType type, long timeout, Object owner) {
+         this.ctx = ctx;
+         this.type = type;
+         this.timeout = timeout;
+         this.owner = owner;
+      }
+
+      public void acquire(NodeSPI node)
+      {
+         try
+         {
+            acquireNodeLock(ctx, node, owner, type, timeout);
+         }
+         catch (InterruptedException e)
+         {
+            Thread.currentThread().interrupt();
+         }
+      }
+   }
 }



More information about the jbosscache-commits mailing list