[jbosscache-commits] JBoss Cache SVN: r5290 - in core/trunk/src/main/java/org/jboss/cache: invocation and 1 other directories.

jbosscache-commits at lists.jboss.org jbosscache-commits at lists.jboss.org
Tue Feb 5 09:33:41 EST 2008


Author: mircea.markus
Date: 2008-02-05 09:33:41 -0500 (Tue, 05 Feb 2008)
New Revision: 5290

Modified:
   core/trunk/src/main/java/org/jboss/cache/interceptors/PessimisticLockInterceptor.java
   core/trunk/src/main/java/org/jboss/cache/invocation/NodeInvocationDelegate.java
   core/trunk/src/main/java/org/jboss/cache/lock/ReadWriteLockWithUpgrade.java
Log:
fixed tests


Modified: core/trunk/src/main/java/org/jboss/cache/interceptors/PessimisticLockInterceptor.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/interceptors/PessimisticLockInterceptor.java	2008-02-05 04:22:07 UTC (rev 5289)
+++ core/trunk/src/main/java/org/jboss/cache/interceptors/PessimisticLockInterceptor.java	2008-02-05 14:33:41 UTC (rev 5290)
@@ -14,10 +14,7 @@
 import org.jboss.cache.config.Configuration;
 import org.jboss.cache.factories.annotations.ComponentName;
 import org.jboss.cache.factories.annotations.Inject;
-import org.jboss.cache.lock.IsolationLevel;
-import org.jboss.cache.lock.LockingException;
-import org.jboss.cache.lock.NodeLock;
-import org.jboss.cache.lock.TimeoutException;
+import org.jboss.cache.lock.*;
 import org.jboss.cache.marshall.MethodDeclarations;
 import org.jboss.cache.transaction.GlobalTransaction;
 import org.jboss.cache.transaction.TransactionEntry;
@@ -80,9 +77,46 @@
    public Object invoke(InvocationContext ctx) throws Throwable
    {
       if (rootNode == null) rootNode = cache.getRoot();
-      return super.invoke(ctx);
+      try
+      {
+         return super.invoke(ctx);
+      } catch (LockingException le)
+      {
+         if (trace) log.trace("Locking exception occured, cleaning up locks." , le);
+         releaseLocks(ctx);
+         throw le;
+      } catch (TimeoutException te)
+      {
+         if (trace) log.trace("Locking exception occured, cleaning up locks." , te);
+         releaseLocks(ctx);
+         throw te;
+      }
    }
 
+   /**
+    * If an issue appears while acquiring a lock (e.g. timeout exception, upgrade exception) then acquire
+    * release all acquired locks before throwing it.
+    */
+   private void releaseLocks(InvocationContext ctx)
+   {
+      GlobalTransaction gtx = ctx.getGlobalTransaction();
+      if (trace) log.trace("Releasing existing locks. Global tx?" + gtx);
+      if (gtx != null)
+      {
+         TransactionEntry  te = cache.getTransactionTable().get(gtx);
+         te.releaseAllLocksFIFO(gtx);
+      } else
+      {
+         Thread currentThread = Thread.currentThread();
+         List<NodeLock> locks = getLocks(currentThread);
+         for (NodeLock aLock : locks)
+         {
+            aLock.release(currentThread);
+         }
+      }      
+   }
+
+
    protected Object handlePutDataMethod(InvocationContext ctx, GlobalTransaction tx, Fqn fqn, Map data, boolean createUndoOps) throws Throwable
    {
       return handlePutMethod(ctx, fqn);
@@ -251,9 +285,9 @@
          if (trace) log.trace("There were new nodes created, skiping notification on delete");
          Object[] args = ctx.getMethodCall().getArgs();
          if (trace) log.trace("Changing 'skipNotification' for method '_remove' from " + args[args.length - 1] + " to true");
-         args[args.length - 1] = Boolean.TRUE;         
+         args[args.length - 1] = Boolean.TRUE;
       }
-      
+
       Object retVal = nextInterceptor(ctx);
       // and make sure we remove all nodes we've created for the sake of later removal.
       if (ctx.getGlobalTransaction() == null)
@@ -424,13 +458,14 @@
             lockTypeRequired = NodeLock.LockType.WRITE;
          }
 
+         Fqn currentNodeFqn = currentNode.getFqn();
          // actually acquire the lock we need.  This method blocks.
          acquireNodeLock(currentNode, owner, gtx, lockTypeRequired, timeout);
 
          manageReverseRemove(gtx, currentNode, reverseRemoveCheck);
          // make sure the lock we acquired isn't on a deleted node/is an orphan!!
          // look into invalidated nodes as well
-         NodeSPI repeek = peekNode(ctx, currentNode.getFqn(), true, true, true);
+         NodeSPI repeek = peekNode(ctx, currentNodeFqn, true, true, true);
          if (currentNode != repeek)
          {
             if (trace)
@@ -445,25 +480,32 @@
                if (trace) log.trace("Parent has been deleted again.  Go through the lock method all over again.");
                currentNode = rootNode;
                parent = null;
-            }
-            else
+            } else
             {
                currentNode = parent;
+               currentIndex--;
                parent = null;
                if (System.currentTimeMillis() > expiryTime)
                {
                   throw new TimeoutException("Unable to acquire lock on child node " + new Fqn(currentNode.getFqn(), childName) + " after " + timeout + " millis.");
                }
+               if (trace) log.trace("Moving one level up, current node is :" + currentNode);
             }
-         }
-         else
+         } else
          {
-            if (currentNode.getFqn().equals(fqn))//we've just processed the last child
+            if (currentNodeFqn.equals(fqn))//we've just processed the last child
             {
                break;
             }
+            if (!fqn.isChildOrEquals(currentNode.getFqn()))
+            {
+               String message = new StringBuffer("currentNode instance changed the FQN(").append(currentNode.getFqn())
+                     .append(") and do not match the FQN on which we want to acquire lock(").append(fqn).append(")").toString();
+               log.trace(message);
+               throw new LockingException(message);
+            }
             parent = currentNode;
-            currentIndex = currentNode.getFqn().size();
+            currentIndex = currentNodeFqn.size();
             currentNode = currentNode.getChildDirect(fqn.get(currentIndex));
             childName = fqn.get(currentIndex);
          }

Modified: core/trunk/src/main/java/org/jboss/cache/invocation/NodeInvocationDelegate.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/invocation/NodeInvocationDelegate.java	2008-02-05 04:22:07 UTC (rev 5289)
+++ core/trunk/src/main/java/org/jboss/cache/invocation/NodeInvocationDelegate.java	2008-02-05 14:33:41 UTC (rev 5290)
@@ -491,4 +491,9 @@
       if (!node.isValid())
          throw new NodeNotValidException("Node " + getFqn() + " is not valid.  Perhaps it has been moved or removed.");
    }
+
+   public String toString()
+   {
+      return node == null ? null : node.toString();
+   }
 }

Modified: core/trunk/src/main/java/org/jboss/cache/lock/ReadWriteLockWithUpgrade.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/lock/ReadWriteLockWithUpgrade.java	2008-02-05 04:22:07 UTC (rev 5289)
+++ core/trunk/src/main/java/org/jboss/cache/lock/ReadWriteLockWithUpgrade.java	2008-02-05 14:33:41 UTC (rev 5290)
@@ -16,7 +16,7 @@
 import java.util.concurrent.locks.Lock;
 import java.util.concurrent.locks.ReadWriteLock;
 
-/*
+/**
  * <p> This class is similar to PreferredWriterReadWriteLock except that
  * the read lock is upgradable to write lock. I.e., when a user calls
  * upgradeLock(), it will release the read lock, wait for




More information about the jbosscache-commits mailing list