[infinispan-commits] Infinispan SVN: r2372 - in branches/4.2.x: core/src/main/java/org/infinispan/affinity and 13 other directories.

infinispan-commits at lists.jboss.org infinispan-commits at lists.jboss.org
Tue Sep 14 20:16:20 EDT 2010


Author: mircea.markus
Date: 2010-09-14 20:16:18 -0400 (Tue, 14 Sep 2010)
New Revision: 2372

Added:
   branches/4.2.x/core/src/test/java/org/infinispan/tx/dld/
   branches/4.2.x/core/src/test/java/org/infinispan/tx/dld/AsyncDeadlockDetectionTest.java
   branches/4.2.x/core/src/test/java/org/infinispan/tx/dld/BaseDldEagerLockingTest.java
   branches/4.2.x/core/src/test/java/org/infinispan/tx/dld/BaseDldLazyLockingTest.java
   branches/4.2.x/core/src/test/java/org/infinispan/tx/dld/BaseDldTest.java
   branches/4.2.x/core/src/test/java/org/infinispan/tx/dld/ControlledRpcManager.java
   branches/4.2.x/core/src/test/java/org/infinispan/tx/dld/DldEagerLockingDistributedTest.java
   branches/4.2.x/core/src/test/java/org/infinispan/tx/dld/DldEagerLockingReplicationTest.java
   branches/4.2.x/core/src/test/java/org/infinispan/tx/dld/DldLazyLockingDistributionTest.java
   branches/4.2.x/core/src/test/java/org/infinispan/tx/dld/DldLazyLockingReplicationTest.java
   branches/4.2.x/core/src/test/java/org/infinispan/tx/dld/LocalDeadlockDetectionTest.java
Removed:
   branches/4.2.x/core/src/main/java/org/infinispan/transaction/xa/DistDldGlobalTransaction.java
   branches/4.2.x/core/src/test/java/org/infinispan/distribution/DeadlockDetectionDistributionTest.java
   branches/4.2.x/core/src/test/java/org/infinispan/tx/AsyncDeadlockDetectionTest.java
   branches/4.2.x/core/src/test/java/org/infinispan/tx/EagerTxDeadlockDetectionTest.java
   branches/4.2.x/core/src/test/java/org/infinispan/tx/LocalDeadlockDetectionTest.java
   branches/4.2.x/core/src/test/java/org/infinispan/tx/ReplDeadlockDetectionTest.java
Modified:
   branches/4.2.x/core/src/main/java/org/infinispan/affinity/KeyAffinityServiceImpl.java
   branches/4.2.x/core/src/main/java/org/infinispan/commands/CommandsFactoryImpl.java
   branches/4.2.x/core/src/main/java/org/infinispan/commands/control/LockControlCommand.java
   branches/4.2.x/core/src/main/java/org/infinispan/commands/tx/PrepareCommand.java
   branches/4.2.x/core/src/main/java/org/infinispan/context/InvocationContext.java
   branches/4.2.x/core/src/main/java/org/infinispan/context/impl/AbstractInvocationContext.java
   branches/4.2.x/core/src/main/java/org/infinispan/interceptors/DeadlockDetectingInterceptor.java
   branches/4.2.x/core/src/main/java/org/infinispan/marshall/Ids.java
   branches/4.2.x/core/src/main/java/org/infinispan/transaction/xa/DldGlobalTransaction.java
   branches/4.2.x/core/src/main/java/org/infinispan/transaction/xa/GlobalTransactionFactory.java
   branches/4.2.x/core/src/main/java/org/infinispan/transaction/xa/RemoteTransaction.java
   branches/4.2.x/core/src/main/java/org/infinispan/transaction/xa/TransactionTable.java
   branches/4.2.x/core/src/main/java/org/infinispan/util/concurrent/locks/DeadlockDetectingLockManager.java
   branches/4.2.x/core/src/test/java/org/infinispan/util/DeadlockDetectingLockManagerTest.java
   branches/4.2.x/pom.xml
Log:
[ISPN-631] - DLD and dist tests are disabled - enable and enhance these tests

Modified: branches/4.2.x/core/src/main/java/org/infinispan/affinity/KeyAffinityServiceImpl.java
===================================================================
--- branches/4.2.x/core/src/main/java/org/infinispan/affinity/KeyAffinityServiceImpl.java	2010-09-14 17:11:35 UTC (rev 2371)
+++ branches/4.2.x/core/src/main/java/org/infinispan/affinity/KeyAffinityServiceImpl.java	2010-09-15 00:16:18 UTC (rev 2372)
@@ -94,6 +94,8 @@
       if (!started) {
          throw new IllegalStateException("You have to start the service first!");
       }
+      if (address == null)
+         throw new NullPointerException("Null address not supported!");
       BlockingQueue queue = address2key.get(address);
       try {
          maxNumberInvariant.readLock().lock();

Modified: branches/4.2.x/core/src/main/java/org/infinispan/commands/CommandsFactoryImpl.java
===================================================================
--- branches/4.2.x/core/src/main/java/org/infinispan/commands/CommandsFactoryImpl.java	2010-09-14 17:11:35 UTC (rev 2371)
+++ branches/4.2.x/core/src/main/java/org/infinispan/commands/CommandsFactoryImpl.java	2010-09-15 00:16:18 UTC (rev 2372)
@@ -59,7 +59,9 @@
 import org.infinispan.interceptors.InterceptorChain;
 import org.infinispan.notifications.cachelistener.CacheNotifier;
 import org.infinispan.remoting.transport.Address;
+import org.infinispan.transaction.xa.DldGlobalTransaction;
 import org.infinispan.transaction.xa.GlobalTransaction;
+import org.infinispan.transaction.xa.RemoteTransaction;
 import org.infinispan.transaction.xa.TransactionTable;
 import org.infinispan.util.logging.Log;
 import org.infinispan.util.logging.LogFactory;
@@ -67,6 +69,7 @@
 import java.util.Collection;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 
 /**
  * @author Mircea.Markus at jboss.com
@@ -256,8 +259,14 @@
             pc.init(interceptorChain, icc, txTable);
             pc.initialize(notifier);
             if (pc.getModifications() != null)
-               for (ReplicableCommand nested : pc.getModifications()) initializeReplicableCommand(nested, false);
+               for (ReplicableCommand nested : pc.getModifications())  {
+                  initializeReplicableCommand(nested, false);
+               }
             pc.markTransactionAsRemote(isRemote);
+            if (configuration.isEnableDeadlockDetection() && isRemote) {
+               DldGlobalTransaction transaction = (DldGlobalTransaction) pc.getGlobalTransaction();
+               transaction.setLocksHeldAtOrigin(pc.getAffectedKeys());
+            }
             break;
          case CommitCommand.COMMAND_ID:
             CommitCommand commitCommand = (CommitCommand) c;
@@ -281,6 +290,21 @@
             LockControlCommand lcc = (LockControlCommand) c;
             lcc.init(interceptorChain, icc, txTable);
             lcc.markTransactionAsRemote(isRemote);
+            if (configuration.isEnableDeadlockDetection() && isRemote) {
+               DldGlobalTransaction gtx = (DldGlobalTransaction) lcc.getGlobalTransaction();
+               RemoteTransaction transaction = txTable.getRemoteTransaction(gtx);
+               if (transaction != null) {
+                  if (!configuration.getCacheMode().isDistributed()) {
+                     Set<Object> keys = txTable.getLockedKeysForRemoteTransaction(gtx);
+                     GlobalTransaction gtx2 = transaction.getGlobalTransaction();
+                     ((DldGlobalTransaction) gtx2).setLocksHeldAtOrigin(keys);
+                     gtx.setLocksHeldAtOrigin(keys);
+                  } else {
+                     GlobalTransaction gtx2 = transaction.getGlobalTransaction();
+                     ((DldGlobalTransaction) gtx2).setLocksHeldAtOrigin(gtx.getLocksHeldAtOrigin());
+                  }
+               }
+            }
             break;
          case RehashControlCommand.COMMAND_ID:
             RehashControlCommand rcc = (RehashControlCommand) c;

Modified: branches/4.2.x/core/src/main/java/org/infinispan/commands/control/LockControlCommand.java
===================================================================
--- branches/4.2.x/core/src/main/java/org/infinispan/commands/control/LockControlCommand.java	2010-09-14 17:11:35 UTC (rev 2371)
+++ branches/4.2.x/core/src/main/java/org/infinispan/commands/control/LockControlCommand.java	2010-09-15 00:16:18 UTC (rev 2372)
@@ -48,7 +48,6 @@
  *
  * @author Vladimir Blagojevic (<a href="mailto:vblagoje at redhat.com">vblagoje at redhat.com</a>)
  * @author Mircea.Markus at jboss.com
- * @param
  * @since 4.0
  */
 @Marshallable(externalizer = ReplicableCommandExternalizer.class, id = Ids.LOCK_CONTROL_COMMAND)

Modified: branches/4.2.x/core/src/main/java/org/infinispan/commands/tx/PrepareCommand.java
===================================================================
--- branches/4.2.x/core/src/main/java/org/infinispan/commands/tx/PrepareCommand.java	2010-09-14 17:11:35 UTC (rev 2371)
+++ branches/4.2.x/core/src/main/java/org/infinispan/commands/tx/PrepareCommand.java	2010-09-15 00:16:18 UTC (rev 2372)
@@ -105,7 +105,7 @@
       ctx.setRemoteTransaction(remoteTransaction);
 
       if (trace)
-         log.trace("Invoking remotly orginated prepare: " + this);
+         log.trace("Invoking remotely originated prepare: " + this + " with invocation context: " + ctx);
       notifier.notifyTransactionRegistered(ctx.getGlobalTransaction(), ctx);
       try {
          return invoker.invoke(ctx, this);

Modified: branches/4.2.x/core/src/main/java/org/infinispan/context/InvocationContext.java
===================================================================
--- branches/4.2.x/core/src/main/java/org/infinispan/context/InvocationContext.java	2010-09-14 17:11:35 UTC (rev 2371)
+++ branches/4.2.x/core/src/main/java/org/infinispan/context/InvocationContext.java	2010-09-15 00:16:18 UTC (rev 2372)
@@ -48,15 +48,15 @@
     */
    Object getLockOwner();
 
-   /**
-    * Returns true if the context has any locked entries associated with it.
-    */
-   boolean hasLockedEntries();
-
    boolean isUseFutureReturnType();
 
    void setUseFutureReturnType(boolean useFutureReturnType);
 
    InvocationContext clone();
 
+   /**
+    * Returns the set of keys that are locked for writing.
+    */
+   public Set getLockedKeys();
+
 }

Modified: branches/4.2.x/core/src/main/java/org/infinispan/context/impl/AbstractInvocationContext.java
===================================================================
--- branches/4.2.x/core/src/main/java/org/infinispan/context/impl/AbstractInvocationContext.java	2010-09-14 17:11:35 UTC (rev 2371)
+++ branches/4.2.x/core/src/main/java/org/infinispan/context/impl/AbstractInvocationContext.java	2010-09-15 00:16:18 UTC (rev 2372)
@@ -3,11 +3,11 @@
 import org.infinispan.container.entries.CacheEntry;
 import org.infinispan.context.Flag;
 import org.infinispan.context.InvocationContext;
-import org.infinispan.util.BidirectionalMap;
 
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.EnumSet;
+import java.util.HashSet;
 import java.util.Set;
 
 /**
@@ -123,18 +123,7 @@
       }
    }
 
-   public boolean hasLockedEntries() {
-      BidirectionalMap<Object, CacheEntry> lookedUpEntries = getLookedUpEntries();
-      boolean result = false;
-      for (CacheEntry e : lookedUpEntries.values()) {
-         if (e.isChanged()) {
-            result = true;
-         }
-      }
-      return result;
-   }
 
-
    public boolean isUseFutureReturnType() {
       return isContextFlagSet(ContextFlag.USE_FUTURE_RETURN_TYPE);
    }
@@ -154,6 +143,15 @@
       }
    }
 
+   public Set getLockedKeys() {
+      Set result = new HashSet();
+      for (Object key : getLookedUpEntries().keySet()) {
+         if (hasLockedKey(key))
+            result.add(key);
+      }
+      return result;
+   }
+
    @Override
    public String toString() {
       return getClass().getSimpleName() + "{" +

Modified: branches/4.2.x/core/src/main/java/org/infinispan/interceptors/DeadlockDetectingInterceptor.java
===================================================================
--- branches/4.2.x/core/src/main/java/org/infinispan/interceptors/DeadlockDetectingInterceptor.java	2010-09-14 17:11:35 UTC (rev 2371)
+++ branches/4.2.x/core/src/main/java/org/infinispan/interceptors/DeadlockDetectingInterceptor.java	2010-09-15 00:16:18 UTC (rev 2372)
@@ -12,12 +12,12 @@
 import org.infinispan.factories.annotations.Start;
 import org.infinispan.interceptors.base.CommandInterceptor;
 import org.infinispan.transaction.xa.DldGlobalTransaction;
-import org.infinispan.util.concurrent.locks.DeadlockDetectedException;
-import org.infinispan.util.concurrent.locks.LockManager;
+import org.infinispan.transaction.xa.GlobalTransaction;
+import org.infinispan.transaction.xa.RemoteTransaction;
+import org.infinispan.transaction.xa.TransactionTable;
 
-import javax.transaction.Transaction;
-import javax.transaction.TransactionManager;
 import java.util.Collections;
+import java.util.Set;
 
 /**
  * This interceptor populates the {@link org.infinispan.transaction.xa.DldGlobalTransaction} with
@@ -32,15 +32,6 @@
  */
 public class DeadlockDetectingInterceptor extends CommandInterceptor {
 
-   private LockManager lockManager;
-   private TransactionManager txManager;
-
-   @Inject
-   public void init(LockManager lockManager, TransactionManager txManager) {
-      this.lockManager = lockManager;
-      this.txManager = txManager;
-   }
-
    /**
     * Only does a sanity check.
     */
@@ -71,7 +62,12 @@
       DldGlobalTransaction globalTransaction = (DldGlobalTransaction) ctx.getGlobalTransaction();
       if (ctx.isOriginLocal()) {
          globalTransaction.setRemoteLockIntention(command.getKeys());
-      }      
+         //in the case of DIST we need to propagate the list of keys. In all other situations in can be determined
+         // based on the actual command
+         if (configuration.getCacheMode().isDistributed()) {
+            ((DldGlobalTransaction) ctx.getGlobalTransaction()).setLocksHeldAtOrigin(ctx.getLockedKeys());
+         }
+      }
       return handleDataCommand(ctx, command);
    }
 

Modified: branches/4.2.x/core/src/main/java/org/infinispan/marshall/Ids.java
===================================================================
--- branches/4.2.x/core/src/main/java/org/infinispan/marshall/Ids.java	2010-09-14 17:11:35 UTC (rev 2371)
+++ branches/4.2.x/core/src/main/java/org/infinispan/marshall/Ids.java	2010-09-15 00:16:18 UTC (rev 2372)
@@ -117,7 +117,4 @@
    static final byte BYTE_ARRAY_KEY = 57;
    static final byte TOPOLOGY_ADDRESS = 58;
    static final byte TOPOLOGY_VIEW = 59;
-
-   //added in 4.2
-   static final byte LOCK_INTENTION_NOTIFICATION_COMMAND = 60;
 }

Deleted: branches/4.2.x/core/src/main/java/org/infinispan/transaction/xa/DistDldGlobalTransaction.java
===================================================================
--- branches/4.2.x/core/src/main/java/org/infinispan/transaction/xa/DistDldGlobalTransaction.java	2010-09-14 17:11:35 UTC (rev 2371)
+++ branches/4.2.x/core/src/main/java/org/infinispan/transaction/xa/DistDldGlobalTransaction.java	2010-09-15 00:16:18 UTC (rev 2372)
@@ -1,35 +0,0 @@
-package org.infinispan.transaction.xa;
-
-import org.infinispan.distribution.DistributionManager;
-import org.infinispan.remoting.transport.Address;
-
-/**
- * @author Mircea.Markus at jboss.com
- * @since 4.1
- */
-public class DistDldGlobalTransaction extends DldGlobalTransaction {
-
-   private volatile DistributionManager distManager;
-   private volatile int numOwners;
-
-   public DistDldGlobalTransaction(DistributionManager distManager, int numOwners) {
-      this.distManager = distManager;
-      this.numOwners = numOwners;
-   }
-
-   public DistDldGlobalTransaction(Address addr, boolean remote, DistributionManager distManager, int numOwners) {
-      super(addr, remote);
-      this.distManager = distManager;
-      this.numOwners = numOwners;
-   }
-
-   @Override
-   public boolean isAcquiringRemoteLock(Object key, Address address) {
-      boolean affectsKey = remoteLockIntention.contains(key);
-      if (affectsKey) {
-         return distManager.getConsistentHash().isKeyLocalToAddress(address, key, numOwners);
-      } else {
-         return false;
-      }
-   }
-}

Modified: branches/4.2.x/core/src/main/java/org/infinispan/transaction/xa/DldGlobalTransaction.java
===================================================================
--- branches/4.2.x/core/src/main/java/org/infinispan/transaction/xa/DldGlobalTransaction.java	2010-09-14 17:11:35 UTC (rev 2371)
+++ branches/4.2.x/core/src/main/java/org/infinispan/transaction/xa/DldGlobalTransaction.java	2010-09-15 00:16:18 UTC (rev 2372)
@@ -28,10 +28,11 @@
 
    private volatile boolean isMarkedForRollback;
 
-   private transient volatile Object lockLocalLockIntention;
+   private transient volatile Object localLockIntention;
 
    protected volatile Set<Object> remoteLockIntention = Collections.EMPTY_SET;
 
+   private volatile Set<Object> locksAtOrigin = Collections.EMPTY_SET;
 
    public DldGlobalTransaction() {
    }
@@ -76,8 +77,9 @@
       return "DldGlobalTransaction{" +
             "coinToss=" + coinToss +
             ", isMarkedForRollback=" + isMarkedForRollback +
-            ", lockIntention=" + lockLocalLockIntention +
+            ", lockIntention=" + localLockIntention +
             ", affectedKeys=" + remoteLockIntention +
+            ", locksAtOrigin=" + locksAtOrigin +
             "} " + super.toString();
    }
 
@@ -93,11 +95,11 @@
     * Returns the key this transaction intends to lock. 
     */
    public Object getLockIntention() {
-      return lockLocalLockIntention;
+      return localLockIntention;
    }
 
-   public void setLockLocalLockIntention(Object lockIntention) {
-      this.lockLocalLockIntention = lockIntention;
+   public void setLockIntention(Object lockIntention) {                                                                                                       
+      this.localLockIntention = lockIntention;
    }
 
    public boolean wouldLose(DldGlobalTransaction other) {
@@ -112,7 +114,7 @@
 
    public void setRemoteLockIntention(Set<Object> remoteLockIntention) {
       if (trace) {
-         log.trace("Setting the affected keys set to: " + remoteLockIntention);
+         log.trace("Setting the remote lock intention: " + remoteLockIntention);
       }
       this.remoteLockIntention = remoteLockIntention;
    }
@@ -121,6 +123,25 @@
       return remoteLockIntention;
    }
 
+   public boolean hasLockAtOrigin(Set<Object> remoteLockIntention) {
+      if (log.isTraceEnabled()) log.trace("Our(" + this + ") locks at origin are: " + locksAtOrigin + ". Others remote lock intention is: " + remoteLockIntention);
+      for (Object key : remoteLockIntention) {
+         if (this.locksAtOrigin.contains(key)) {
+            return true;
+         }
+      }
+      return false;
+   }
+
+   public void setLocksHeldAtOrigin(Set<Object> locksAtOrigin) {
+      if (trace) log.trace("Setting locks at origin for (" + this + ")  to " + locksAtOrigin);
+      this.locksAtOrigin = locksAtOrigin;
+   }
+
+   public Set<Object> getLocksHeldAtOrigin() {
+      return this.locksAtOrigin;
+   }
+
    public static class Externalizer extends GlobalTransaction.Externalizer {
       public Externalizer() {
          gtxFactory = new GlobalTransactionFactory(true);
@@ -131,12 +152,23 @@
          super.writeObject(output, subject);
          DldGlobalTransaction ddGt = (DldGlobalTransaction) subject;
          output.writeLong(ddGt.getCoinToss());
+         if (ddGt.locksAtOrigin.isEmpty()) {
+            output.writeObject(null);
+         } else {
+            output.writeObject(ddGt.locksAtOrigin);
+         }
       }
 
       @Override
       public Object readObject(ObjectInput input) throws IOException, ClassNotFoundException {
          DldGlobalTransaction ddGt = (DldGlobalTransaction) super.readObject(input);
          ddGt.setCoinToss(input.readLong());
+         Object locksAtOriginObj = input.readObject();
+         if (locksAtOriginObj == null) {
+            ddGt.setLocksHeldAtOrigin(Collections.EMPTY_SET);
+         } else {
+            ddGt.setLocksHeldAtOrigin((Set<Object>) locksAtOriginObj);
+         }
          return ddGt;
       }
    }

Modified: branches/4.2.x/core/src/main/java/org/infinispan/transaction/xa/GlobalTransactionFactory.java
===================================================================
--- branches/4.2.x/core/src/main/java/org/infinispan/transaction/xa/GlobalTransactionFactory.java	2010-09-14 17:11:35 UTC (rev 2371)
+++ branches/4.2.x/core/src/main/java/org/infinispan/transaction/xa/GlobalTransactionFactory.java	2010-09-15 00:16:18 UTC (rev 2372)
@@ -64,17 +64,12 @@
       GlobalTransaction gtx;
       if (isEddEnabled) {
          DldGlobalTransaction globalTransaction;
-         if (configuration.getCacheMode().isDistributed()) {
-            globalTransaction = new DistDldGlobalTransaction(addr, remote, distributionManager, configuration.getNumOwners());
-         } else {
-            globalTransaction = new DldGlobalTransaction(addr, remote);
-         }
+         globalTransaction = new DldGlobalTransaction(addr, remote);
          globalTransaction.setCoinToss(generateRandomId());
          gtx = globalTransaction;
       } else {
          gtx = new GlobalTransaction(addr, remote);
       }
-
       return gtx;
    }
 }

Modified: branches/4.2.x/core/src/main/java/org/infinispan/transaction/xa/RemoteTransaction.java
===================================================================
--- branches/4.2.x/core/src/main/java/org/infinispan/transaction/xa/RemoteTransaction.java	2010-09-14 17:11:35 UTC (rev 2371)
+++ branches/4.2.x/core/src/main/java/org/infinispan/transaction/xa/RemoteTransaction.java	2010-09-15 00:16:18 UTC (rev 2372)
@@ -4,11 +4,15 @@
 import org.infinispan.container.entries.CacheEntry;
 import org.infinispan.util.BidirectionalLinkedHashMap;
 import org.infinispan.util.BidirectionalMap;
+import org.infinispan.util.logging.Log;
+import org.infinispan.util.logging.LogFactory;
 
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.HashSet;
 import java.util.LinkedList;
 import java.util.List;
+import java.util.Set;
 
 /**
  * Defines the state of a remotely originated transaction.
@@ -18,6 +22,8 @@
  */
 public class RemoteTransaction implements CacheTransaction, Cloneable {
 
+   private static Log log = LogFactory.getLog(RemoteTransaction.class);
+
    private List<WriteCommand> modifications;
 
    private BidirectionalLinkedHashMap<Object, CacheEntry> lookedUpEntries;
@@ -58,6 +64,9 @@
    }
 
    public void putLookedUpEntry(Object key, CacheEntry e) {
+      if (log.isTraceEnabled()) {
+         log.trace("Adding key " + key + " to tx " + getGlobalTransaction());
+      }
       lookedUpEntries.put(key, e);
    }
 
@@ -103,4 +112,14 @@
             ", tx=" + tx +
             '}';
    }
+
+   public Set<Object> getLockedKeys() {
+      Set<Object> result = new HashSet<Object>();
+      for (Object key : getLookedUpEntries().keySet()) {
+         result.add(key);
+      }
+      if (lookedUpEntries.entrySet().size() != result.size())
+         throw new IllegalStateException("Different sizes!");
+      return result;
+   }
 }

Modified: branches/4.2.x/core/src/main/java/org/infinispan/transaction/xa/TransactionTable.java
===================================================================
--- branches/4.2.x/core/src/main/java/org/infinispan/transaction/xa/TransactionTable.java	2010-09-14 17:11:35 UTC (rev 2371)
+++ branches/4.2.x/core/src/main/java/org/infinispan/transaction/xa/TransactionTable.java	2010-09-15 00:16:18 UTC (rev 2372)
@@ -23,7 +23,7 @@
 import org.infinispan.util.logging.LogFactory;
 
 import javax.transaction.Transaction;
-import java.util.HashMap;
+import java.util.Collections;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
@@ -83,6 +83,12 @@
       lockBreakingService.shutdownNow();
    }
 
+   public Set<Object> getLockedKeysForRemoteTransaction(GlobalTransaction gtx) {
+      RemoteTransaction transaction = remoteTransactions.get(gtx);
+      if (transaction == null) return Collections.EMPTY_SET;
+      return transaction.getLockedKeys();
+   }
+
    @Listener
    public class StaleTransactionCleanup {
       @ViewChanged

Modified: branches/4.2.x/core/src/main/java/org/infinispan/util/concurrent/locks/DeadlockDetectingLockManager.java
===================================================================
--- branches/4.2.x/core/src/main/java/org/infinispan/util/concurrent/locks/DeadlockDetectingLockManager.java	2010-09-14 17:11:35 UTC (rev 2371)
+++ branches/4.2.x/core/src/main/java/org/infinispan/util/concurrent/locks/DeadlockDetectingLockManager.java	2010-09-15 00:16:18 UTC (rev 2372)
@@ -6,7 +6,6 @@
 import org.infinispan.jmx.annotations.ManagedAttribute;
 import org.infinispan.jmx.annotations.ManagedOperation;
 import org.infinispan.transaction.xa.DldGlobalTransaction;
-import org.infinispan.transaction.xa.TransactionTable;
 import org.infinispan.util.logging.Log;
 import org.infinispan.util.logging.LogFactory;
 import org.rhq.helpers.pluginAnnotations.agent.MeasurementType;
@@ -62,12 +61,12 @@
          if (trace) log.trace("Using early dead lock detection");
          final long start = System.currentTimeMillis();
          DldGlobalTransaction thisTx = (DldGlobalTransaction) ctx.getLockOwner();
-         thisTx.setLockLocalLockIntention(key);
+         thisTx.setLockIntention(key);
          if (trace) log.trace("Setting lock intention to: " + key);
 
          while (System.currentTimeMillis() < (start + lockTimeout)) {
             if (lockContainer.acquireLock(key, spinDuration, MILLISECONDS) != null) {
-               thisTx.setLockLocalLockIntention(null); //clear lock intention
+               thisTx.setLockIntention(null); //clear lock intention
                if (trace) log.trace("successfully acquired lock on " + key + ", returning ...");
                return true;
             } else {
@@ -112,26 +111,21 @@
    private boolean ownsRemoteIntention(DldGlobalTransaction lockOwnerTx, DldGlobalTransaction thisTx, Object key) {
       if (!lockOwnerTx.isRemote()) {
          // I've already acquired lock on this key before replicating here, so this mean we are in deadlock. This assumes the fact that
-         // if trying to acquire a remote lock, a tx first acquires a local lock. This stands true in all situations but
-         // when DLD + eager locking is used (in this scenario remote locks are acquired first).
-         if (lockOwnerTx.isAcquiringRemoteLock(key, thisTx.getAddress())) {
+         // if trying to acquire a remote lock, a tx first acquires a local lock. 
+         if (thisTx.hasLockAtOrigin(lockOwnerTx.getRemoteLockIntention())) {
             if (trace)
                log.trace("Same key deadlock detected: lock owner tries to acquire lock remotely on " + key + " but we have it!");
             return true;
          }
-         for (Object remoteIntention : lockOwnerTx.getRemoteLockIntention()) {
-            if (ownsLock(remoteIntention, thisTx)) {
-                  if (trace) log.trace("We own lock on a key ('" + remoteIntention + "') on which other tx wants to acquire remote lock");
-               return true;
-            }
-         }
+      } else {
+         if (trace) log.trace("Lock owner is remote: " + lockOwnerTx);
       }
       return false;
    }
 
-   private boolean ownsLocalIntention(DldGlobalTransaction tx, Object intention) {
-      boolean result = intention != null && ownsLock(intention, tx);
-      if (trace) log.trace("Intention is '" + intention + "'. Do we own lock for it? " + result + " We == " + tx);
+   private boolean ownsLocalIntention(DldGlobalTransaction thisTx, Object intention) {
+      boolean result = intention != null && ownsLock(intention, thisTx);
+      if (trace) log.trace("Local intention is '" + intention + "'. Do we own lock for it? " + result + " We == " + thisTx);
       return result;
    }
 

Deleted: branches/4.2.x/core/src/test/java/org/infinispan/distribution/DeadlockDetectionDistributionTest.java
===================================================================
--- branches/4.2.x/core/src/test/java/org/infinispan/distribution/DeadlockDetectionDistributionTest.java	2010-09-14 17:11:35 UTC (rev 2371)
+++ branches/4.2.x/core/src/test/java/org/infinispan/distribution/DeadlockDetectionDistributionTest.java	2010-09-15 00:16:18 UTC (rev 2372)
@@ -1,42 +0,0 @@
-package org.infinispan.distribution;
-
-import org.infinispan.config.Configuration;
-import org.infinispan.tx.ReplDeadlockDetectionTest;
-import static org.testng.Assert.fail;
-import org.testng.annotations.Test;
-
-/**
- * Test deadlock detection when cache is configured for distribution.
- *
- * @author Mircea.Markus at jboss.com
- */
- at Test(groups = "functional",  testName = "distribution.DeadlockDetectionDistributionTest")
-public class DeadlockDetectionDistributionTest extends ReplDeadlockDetectionTest {
-
-//   public DeadlockDetectionDistributionTest() {
-//      cacheMode = Configuration.CacheMode.DIST_SYNC;
-//   }
-//
-//
-//   public void testDeadlockDetectedTwoTransactions() throws Exception {
-//      fail("This test should be updated to make sure tx replicate on opposite nodes");
-//   }
-//
-//
-//   //following methods are overridden as TestNG will otherwise run them even if I mark the class as enabled = false
-//
-//   @Override
-//   public void testExpectedInnerStructure() {
-//      throw new IllegalStateException("TODO - please implement me!!!"); //todo implement!!!
-//   }
-//
-//   @Override
-//   public void testDeadlockDetectedOneTx() throws Exception {
-//      throw new IllegalStateException("TODO - please implement me!!!"); //todo implement!!!
-//   }
-//
-//   @Override
-//   public void testLockReleasedWhileTryingToAcquire() throws Exception {
-//      throw new IllegalStateException("TODO - please implement me!!!"); //todo implement!!!
-//   }
-}

Deleted: branches/4.2.x/core/src/test/java/org/infinispan/tx/AsyncDeadlockDetectionTest.java
===================================================================
--- branches/4.2.x/core/src/test/java/org/infinispan/tx/AsyncDeadlockDetectionTest.java	2010-09-14 17:11:35 UTC (rev 2371)
+++ branches/4.2.x/core/src/test/java/org/infinispan/tx/AsyncDeadlockDetectionTest.java	2010-09-15 00:16:18 UTC (rev 2372)
@@ -1,186 +0,0 @@
-package org.infinispan.tx;
-
-import org.infinispan.Cache;
-import org.infinispan.commands.VisitableCommand;
-import org.infinispan.commands.write.PutKeyValueCommand;
-import org.infinispan.config.Configuration;
-import org.infinispan.context.InvocationContext;
-import org.infinispan.interceptors.base.CommandInterceptor;
-import org.infinispan.test.MultipleCacheManagersTest;
-import org.infinispan.test.PerCacheExecutorThread;
-import org.infinispan.test.TestingUtil;
-import org.infinispan.transaction.xa.TransactionTable;
-import org.infinispan.util.concurrent.locks.DeadlockDetectedException;
-import org.infinispan.util.concurrent.locks.DeadlockDetectingLockManager;
-import org.infinispan.util.concurrent.locks.LockManager;
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertFalse;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-/**
- * Tests deadlock detection for async caches.
- *
- * @author Mircea.Markus at jboss.com
- */
- at Test(groups = "functional", testName = "tx.AsyncDeadlockDetectionTest")
-public class AsyncDeadlockDetectionTest extends MultipleCacheManagersTest {   
-   private PerCacheExecutorThread t0;
-   private PerCacheExecutorThread t1;
-   private RemoteReplicationInterceptor remoteReplicationInterceptor;
-
-
-   protected void createCacheManagers() throws Throwable {
-      Configuration config = getDefaultClusteredConfig(Configuration.CacheMode.REPL_ASYNC, true);
-      config.setEnableDeadlockDetection(true);
-      config.setSyncCommitPhase(true);
-      config.setSyncRollbackPhase(true);
-      config.setUseLockStriping(false);
-      assert config.isEnableDeadlockDetection();
-      createClusteredCaches(2, "test", config);
-      assert config.isEnableDeadlockDetection();
-
-      
-      remoteReplicationInterceptor = new RemoteReplicationInterceptor();
-      Cache cache0 = cache(0, "test");
-      Cache cache1 = cache(1, "test");
-      cache1.getAdvancedCache().addInterceptor(remoteReplicationInterceptor, 0);
-      assert cache0.getConfiguration().isEnableDeadlockDetection();
-      assert cache1.getConfiguration().isEnableDeadlockDetection();
-      assert !cache0.getConfiguration().isExposeJmxStatistics();
-      assert !cache1.getConfiguration().isExposeJmxStatistics();
-
-      ((DeadlockDetectingLockManager) TestingUtil.extractLockManager(cache0)).setExposeJmxStats(true);
-      ((DeadlockDetectingLockManager) TestingUtil.extractLockManager(cache1)).setExposeJmxStats(true);
-   }
-
-   @BeforeMethod
-   public void beforeMethod() {
-      Cache cache0 = cache(0, "test");
-      Cache cache1 = cache(1, "test");
-      t0 = new PerCacheExecutorThread(cache0, 0);
-      t1 = new PerCacheExecutorThread(cache1, 1);
-   }
-
-   @AfterMethod
-   public void afterMethod() {
-      Cache cache0 = cache(0, "test");
-      Cache cache1 = cache(1, "test");
-      t0.stopThread();
-      t1.stopThread();
-      ((DeadlockDetectingLockManager) TestingUtil.extractLockManager(cache0)).resetStatistics();
-      ((DeadlockDetectingLockManager) TestingUtil.extractLockManager(cache1)).resetStatistics();
-      remoteReplicationInterceptor.executionResponse = null;
-      remoteReplicationInterceptor = null;
-      t0 = null;
-      t1 = null;
-   }
-
-   public void testRemoteTxVsLocal() throws Exception {
-      Cache cache0 = cache(0, "test");
-      Cache cache1 = cache(1, "test");
-      assertEquals(PerCacheExecutorThread.OperationsResult.BEGGIN_TX_OK, t0.execute(PerCacheExecutorThread.Operations.BEGGIN_TX));
-      t0.setKeyValue("k1", "v1_t0");
-      assertEquals(PerCacheExecutorThread.OperationsResult.PUT_KEY_VALUE_OK, t0.execute(PerCacheExecutorThread.Operations.PUT_KEY_VALUE));
-      t0.setKeyValue("k2", "v2_t0");
-      assertEquals(PerCacheExecutorThread.OperationsResult.PUT_KEY_VALUE_OK, t0.execute(PerCacheExecutorThread.Operations.PUT_KEY_VALUE));
-
-      assertEquals(PerCacheExecutorThread.OperationsResult.BEGGIN_TX_OK, t1.execute(PerCacheExecutorThread.Operations.BEGGIN_TX));
-      t1.setKeyValue("k2", "v2_t1");
-      assertEquals(PerCacheExecutorThread.OperationsResult.PUT_KEY_VALUE_OK, t1.execute(PerCacheExecutorThread.Operations.PUT_KEY_VALUE));
-
-      t0.execute(PerCacheExecutorThread.Operations.COMMIT_TX);
-
-      final LockManager lm1 = TestingUtil.extractLockManager(cache1);
-
-      eventually(new Condition() {
-         public boolean isSatisfied() throws Exception {
-            return lm1.isLocked("k1");
-         }
-      }); //now t0 replicated, acquired lock on k1 and it tries to acquire lock on k2
-
-
-      t1.setKeyValue("k1", "v1_t1");
-      t1.executeNoResponse(PerCacheExecutorThread.Operations.PUT_KEY_VALUE);
-
-
-      Object t1Response = t1.waitForResponse();
-      Object t0Response = remoteReplicationInterceptor.getResponse();
-
-      log.trace("t0Response = " + t0Response);
-      log.trace("t1Response = " + t1Response);
-
-      assert xor(t1Response instanceof DeadlockDetectedException, t0Response instanceof DeadlockDetectedException);
-      TransactionTable transactionTable1 = TestingUtil.extractComponent(cache1, TransactionTable.class);
-
-
-      if (t0Response instanceof DeadlockDetectedException) {
-         replListener(cache0).expectWithTx(PutKeyValueCommand.class, PutKeyValueCommand.class);
-         assertEquals(t1.execute(PerCacheExecutorThread.Operations.COMMIT_TX), PerCacheExecutorThread.OperationsResult.COMMIT_TX_OK);
-         replListener(cache0).waitForRpc();
-         assertEquals(transactionTable1.getLocalTxCount(), 0);         
-      }
-
-      DeadlockDetectingLockManager ddLm0 = (DeadlockDetectingLockManager) TestingUtil.extractLockManager(cache0);
-      DeadlockDetectingLockManager ddLm1 = (DeadlockDetectingLockManager) TestingUtil.extractLockManager(cache1);
-      
-      assertFalse(ddLm0.isLocked("k1"));
-      assertFalse(ddLm1.isLocked("k1"));
-      assertFalse(ddLm0.isLocked("k2"));
-      assertFalse(ddLm1.isLocked("k2"));
-      TransactionTable transactionTable0 = TestingUtil.extractComponent(cache0, TransactionTable.class);
-      assertEquals(transactionTable0.getLocalTxCount(), 0);
-      for (int i = 0; i < 20; i++) {
-         if (!(transactionTable0.getRemoteTxCount() == 0)) Thread.sleep(50);
-      }
-
-      assertEquals(transactionTable0.getRemoteTxCount(), 0);
-
-      for (int i = 0; i < 20; i++) {
-         if (!(transactionTable1.getRemoteTxCount() == 0)) Thread.sleep(50);
-      }
-      assertEquals(transactionTable1.getRemoteTxCount(), 0);
-
-      if (t1Response instanceof DeadlockDetectedException) {
-         assertEquals(cache0.get("k1"), "v1_t0");
-         assertEquals(cache0.get("k2"), "v2_t0");
-         assertEquals(cache1.get("k1"), "v1_t0");
-         assertEquals(cache1.get("k2"), "v2_t0");
-      } else {
-         assertEquals(cache0.get("k1"), "v1_t1");
-         assertEquals(cache0.get("k2"), "v2_t1");
-         assertEquals(cache1.get("k1"), "v1_t1");
-         assertEquals(cache1.get("k2"), "v2_t1");
-      }
-   }
-
-
-   public static class RemoteReplicationInterceptor extends CommandInterceptor {
-
-      public volatile Object executionResponse;
-
-      @Override
-      protected Object handleDefault(InvocationContext ctx, VisitableCommand command) throws Throwable {
-         try {
-            return invokeNextInterceptor(ctx, command);
-         } catch (Throwable throwable) {
-            if (!ctx.isOriginLocal()) {
-               log.trace("Setting executionResponse to " + throwable);
-               executionResponse = throwable;
-            } else {
-               log.trace("Ignoring throwable " + throwable);
-               executionResponse = "NONE";
-            }
-            throw throwable;
-         }
-      }
-
-      public Object getResponse() throws Exception {
-         while (executionResponse == null) {
-            Thread.sleep(50);
-         }
-         return executionResponse;
-      }
-   }
-}

Deleted: branches/4.2.x/core/src/test/java/org/infinispan/tx/EagerTxDeadlockDetectionTest.java
===================================================================
--- branches/4.2.x/core/src/test/java/org/infinispan/tx/EagerTxDeadlockDetectionTest.java	2010-09-14 17:11:35 UTC (rev 2371)
+++ branches/4.2.x/core/src/test/java/org/infinispan/tx/EagerTxDeadlockDetectionTest.java	2010-09-15 00:16:18 UTC (rev 2372)
@@ -1,128 +0,0 @@
-package org.infinispan.tx;
-
-import org.infinispan.config.Configuration;
-import org.infinispan.context.Flag;
-import org.infinispan.test.MultipleCacheManagersTest;
-import org.infinispan.test.PerCacheExecutorThread;
-import org.infinispan.test.TestingUtil;
-import org.infinispan.util.concurrent.TimeoutException;
-import org.infinispan.util.concurrent.locks.DeadlockDetectingLockManager;
-import org.infinispan.util.concurrent.locks.containers.LockContainer;
-import org.testng.annotations.Test;
-
-import javax.transaction.Status;
-import javax.transaction.TransactionManager;
-import java.util.concurrent.TimeUnit;
-
-/**
- * @author Mircea.Markus at jboss.com
- * @since 4.1
- */
- at Test(groups = "functional", testName = "tx.EagerTxDeadlockDetectionTest")
-public class EagerTxDeadlockDetectionTest extends MultipleCacheManagersTest {
-   private PerCacheExecutorThread ex1;
-   private PerCacheExecutorThread ex2;
-   private DeadlockDetectingLockManager lm0;
-   private DeadlockDetectingLockManager lm1;
-
-   @Override
-   protected void createCacheManagers() throws Throwable {
-      Configuration configuration = getConfiguration();
-      createClusteredCaches(2, configuration);
-      ex1 = new PerCacheExecutorThread(cache(0), 1);
-      ex2 = new PerCacheExecutorThread(cache(1), 2);
-      lm0 = (DeadlockDetectingLockManager) TestingUtil.extractLockManager(cache(0));
-      lm0.setExposeJmxStats(true);
-      lm1 = (DeadlockDetectingLockManager) TestingUtil.extractLockManager(cache(1));
-      lm1.setExposeJmxStats(true);
-   }
-
-   protected Configuration getConfiguration() throws Exception {
-      Configuration configuration = getDefaultClusteredConfig(Configuration.CacheMode.REPL_SYNC, true);
-      configuration.setUseEagerLocking(true);
-      configuration.setEnableDeadlockDetection(true);
-      configuration.setUseLockStriping(false);
-      return configuration;
-   }
-
-   public void testDeadlock() throws Exception {
-      long start = System.currentTimeMillis();
-      ex1.execute(PerCacheExecutorThread.Operations.BEGGIN_TX);
-      ex2.execute(PerCacheExecutorThread.Operations.BEGGIN_TX);
-
-      ex1.setKeyValue("k1", "v1_1");
-      ex1.execute(PerCacheExecutorThread.Operations.PUT_KEY_VALUE);
-      ex2.setKeyValue("k2", "v2_2");
-      ex2.execute(PerCacheExecutorThread.Operations.PUT_KEY_VALUE);
-      assert lm0.isLocked("k1");
-      assert lm0.isLocked("k2");
-      assert lm1.isLocked("k1");
-      assert lm1.isLocked("k2");
-
-      log.trace("After first set of puts");
-
-      ex1.clearResponse();
-      ex2.clearResponse();
-
-      log.info("Here is where DLD happens");
-
-      ex2.setKeyValue("k1", "v1_2");
-      ex2.executeNoResponse(PerCacheExecutorThread.Operations.PUT_KEY_VALUE);
-      ex1.setKeyValue("k2", "v2_1");
-      ex1.executeNoResponse(PerCacheExecutorThread.Operations.PUT_KEY_VALUE);
-      ex1.waitForResponse();
-      ex2.waitForResponse();
-
-
-      boolean b1 = ex1.lastResponse() instanceof Exception;
-      boolean b2 = ex2.lastResponse() instanceof Exception;
-      log.info("b1:", b1);
-      log.info("b2:", b2);
-      assert xor(b1, b2) : "Both are " + (b1 || b2);
-
-      assert xor(ex1.getOngoingTransaction().getStatus() == Status.STATUS_MARKED_ROLLBACK,
-                 ex2.getOngoingTransaction().getStatus() == Status.STATUS_MARKED_ROLLBACK);
-
-
-      ex1.execute(PerCacheExecutorThread.Operations.COMMIT_TX);
-      ex2.execute(PerCacheExecutorThread.Operations.COMMIT_TX);
-
-
-      assert cache(0).get("k1") != null;
-      assert cache(0).get("k2") != null;
-      assert cache(1).get("k1") != null;
-      assert cache(1).get("k2") != null;
-
-      long totalDeadlocks = lm0.getTotalNumberOfDetectedDeadlocks() + lm1.getTotalNumberOfDetectedDeadlocks();
-      assert totalDeadlocks == 1 : "Expected 1 but received " + totalDeadlocks;                              
-
-      System.out.println("Test took " + (System.currentTimeMillis() - start) + " millis.");
-   }
-
-   /**
-    * On eager locking, remote locks are being acquired at first, and then local locks. This is for specifying the
-    * behavior whe remote acquisition succeeds and local fails.
-    */
-   public void testDeadlockFailedToAcquireLocalLocks() throws Exception {
-      //first acquire a local lock on k1
-      TransactionManager tm = TestingUtil.getTransactionManager(cache(0));
-      tm.begin();
-      cache(0).getAdvancedCache().withFlags(Flag.CACHE_MODE_LOCAL).put("k1","v1");
-      assert lm0.isLocked("k1");
-      assert !lm1.isLocked("k1");
-
-      try {
-         ex1.execute(PerCacheExecutorThread.Operations.BEGGIN_TX);
-         ex1.setKeyValue("k1", "v1_1");
-         ex1.execute(PerCacheExecutorThread.Operations.PUT_KEY_VALUE);
-         assert ex1.lastResponse() instanceof TimeoutException;
-         eventually(new Condition() {
-            public boolean isSatisfied() throws Exception {
-               return !lm1.isLocked("k1");
-            }
-         });
-      } finally {
-         tm.rollback();
-      }
-   }
-}

Deleted: branches/4.2.x/core/src/test/java/org/infinispan/tx/LocalDeadlockDetectionTest.java
===================================================================
--- branches/4.2.x/core/src/test/java/org/infinispan/tx/LocalDeadlockDetectionTest.java	2010-09-14 17:11:35 UTC (rev 2371)
+++ branches/4.2.x/core/src/test/java/org/infinispan/tx/LocalDeadlockDetectionTest.java	2010-09-15 00:16:18 UTC (rev 2372)
@@ -1,190 +0,0 @@
-package org.infinispan.tx;
-
-import org.infinispan.config.Configuration;
-import org.infinispan.manager.EmbeddedCacheManager;
-import org.infinispan.test.PerCacheExecutorThread;
-import org.infinispan.test.SingleCacheManagerTest;
-import org.infinispan.test.TestingUtil;
-import org.infinispan.test.fwk.TestCacheManagerFactory;
-import org.infinispan.util.concurrent.locks.DeadlockDetectedException;
-import org.infinispan.util.concurrent.locks.DeadlockDetectingLockManager;
-import static org.testng.Assert.assertEquals;
-
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-import javax.transaction.RollbackException;
-
-/**
- * Tests deadlock detection functionality for local caches.
- *
- * @author Mircea.Markus at jboss.com
- */
- at Test(groups = "functional", testName = "tx.LocalDeadlockDetectionTest")
-public class LocalDeadlockDetectionTest extends SingleCacheManagerTest {
-
-   private PerCacheExecutorThread t1;
-   private PerCacheExecutorThread t2;
-   private DeadlockDetectingLockManager lockManager;
-   private Object response1;
-   private Object response2;
-
-   protected EmbeddedCacheManager createCacheManager() throws Exception {
-      cacheManager = TestCacheManagerFactory.createLocalCacheManager();
-      Configuration configuration = getDefaultStandaloneConfig(true);
-      configuration.setEnableDeadlockDetection(true);
-      configuration.setUseLockStriping(false);
-      configuration.setExposeJmxStatistics(true);
-      cacheManager.defineConfiguration("test", configuration);
-      cache = cacheManager.getCache("test");
-      lockManager = (DeadlockDetectingLockManager) TestingUtil.extractLockManager(cache);
-      return cacheManager;
-   }
-
-   @BeforeMethod
-   public void startExecutors() {
-      t1 = new PerCacheExecutorThread(cache, 0);
-      t2 = new PerCacheExecutorThread(cache, 1);
-      lockManager.resetStatistics();
-   }
-
-
-   @AfterMethod
-   public void stopExecutors() {
-      t1.stopThread();
-      t2.stopThread();
-   }
-
-   public void testDldPutAndPut() {
-      testLocalVsLocalTxDeadlock(PerCacheExecutorThread.Operations.PUT_KEY_VALUE,
-                                 PerCacheExecutorThread.Operations.PUT_KEY_VALUE);
-      if (response1 instanceof Exception) {
-         assertEquals("value_1_t2", cache.get("k1"));
-         assertEquals("value_2_t2", cache.get("k2"));
-      } else {
-         assertEquals("value_1_t1", cache.get("k1"));
-         assertEquals("value_2_t1", cache.get("k2"));
-      }
-   }
-
-   public void testDldPutAndRemove() {
-      testLocalVsLocalTxDeadlock(PerCacheExecutorThread.Operations.PUT_KEY_VALUE,
-                                 PerCacheExecutorThread.Operations.REMOVE_KEY);
-      if (response1 instanceof Exception) {
-         assertEquals(cache.get("k1"), null);
-         assertEquals("value_2_t2", cache.get("k2"));
-      } else {
-         assertEquals("value_1_t1", cache.get("k1"));
-         assertEquals(null, cache.get("k2"));
-      }
-   }
-
-   public void testDldRemoveAndPut() {
-      testLocalVsLocalTxDeadlock(PerCacheExecutorThread.Operations.REMOVE_KEY,
-                                 PerCacheExecutorThread.Operations.PUT_KEY_VALUE);
-      if (response1 instanceof Exception) {
-         System.out.println("t1 failure");
-         assertEquals(cache.get("k1"), "value_1_t2");
-         assertEquals(cache.get("k2"), null);
-      } else {
-         System.out.println("t2 failure");
-         assertEquals(cache.get("k1"), null);
-         assertEquals(cache.get("k2"), "value_2_t1");
-      }
-   }
-
-   public void testDldRemoveAndRemove() {
-      testLocalVsLocalTxDeadlock(PerCacheExecutorThread.Operations.REMOVE_KEY,
-                                 PerCacheExecutorThread.Operations.REMOVE_KEY);
-      if (response1 instanceof Exception) {
-         System.out.println("t1 failure");
-         assertEquals(cache.get("k1"), null);
-         assertEquals(cache.get("k2"), null);
-      } else {
-         System.out.println("t2 failure");
-         assertEquals(cache.get("k1"), null);
-         assertEquals(cache.get("k2"), null);
-      }
-   }
-
-   public void testDldPutAndReplace() {
-
-      cache.put("k1", "initial_1");
-      cache.put("k2", "initial_2");
-
-      testLocalVsLocalTxDeadlock(PerCacheExecutorThread.Operations.PUT_KEY_VALUE,
-                                 PerCacheExecutorThread.Operations.REPLACE_KEY_VALUE);
-      if (response1 instanceof Exception) {
-         System.out.println("t1 failure");
-         assertEquals(cache.get("k1"), "value_1_t2");
-         assertEquals(cache.get("k2"), "value_2_t2");
-      } else {
-         System.out.println("t2 failure");
-         assertEquals(cache.get("k1"), "value_1_t1");
-         assertEquals(cache.get("k2"), "value_2_t1");
-      }
-   }
-
-   public void testDldReplaceAndPut() {
-
-      cache.put("k1", "initial_1");
-      cache.put("k2", "initial_2");
-
-      testLocalVsLocalTxDeadlock(PerCacheExecutorThread.Operations.REPLACE_KEY_VALUE,
-                                 PerCacheExecutorThread.Operations.PUT_KEY_VALUE);
-      if (response1 instanceof Exception) {
-         System.out.println("t1 failure");
-         assertEquals(cache.get("k1"), "value_1_t2");
-         assertEquals(cache.get("k2"), "value_2_t2");
-      } else {
-         System.out.println("t2 failure");
-         assertEquals(cache.get("k1"), "value_1_t1");
-         assertEquals(cache.get("k2"), "value_2_t1");
-      }
-   }
-
-
-   private void testLocalVsLocalTxDeadlock(PerCacheExecutorThread.Operations firstOperation, PerCacheExecutorThread.Operations secondOperation) {
-
-      assert PerCacheExecutorThread.OperationsResult.BEGGIN_TX_OK == t1.execute(PerCacheExecutorThread.Operations.BEGGIN_TX);
-      assert PerCacheExecutorThread.OperationsResult.BEGGIN_TX_OK == t2.execute(PerCacheExecutorThread.Operations.BEGGIN_TX);
-      System.out.println("After begin");
-
-      t1.setKeyValue("k1", "value_1_t1");
-      t2.setKeyValue("k2", "value_2_t2");
-
-      assertEquals(t1.execute(firstOperation), firstOperation.getCorrespondingOkResult());
-      assertEquals(t2.execute(firstOperation), firstOperation.getCorrespondingOkResult());
-
-      assert lockManager.isLocked("k1");
-      assert lockManager.isLocked("k2");
-
-
-      t1.setKeyValue("k2", "value_2_t1");
-      t2.setKeyValue("k1", "value_1_t2");
-      t1.executeNoResponse(secondOperation);
-      t2.executeNoResponse(secondOperation);
-
-      response1 = t1.waitForResponse();
-      response2 = t2.waitForResponse();
-
-      assert xor(response1 instanceof DeadlockDetectedException, response2 instanceof DeadlockDetectedException) : "expected one and only one exception: " + response1 + ", " + response2;
-      assert xor(response1 == secondOperation.getCorrespondingOkResult(), response2 == secondOperation.getCorrespondingOkResult()) : "expected one and only one exception: " + response1 + ", " + response2;
-
-      assert lockManager.isLocked("k1");
-      assert lockManager.isLocked("k2");
-      assert lockManager.getOwner("k1") == lockManager.getOwner("k2");
-
-      if (response1 instanceof Exception) {
-         assert PerCacheExecutorThread.OperationsResult.COMMIT_TX_OK == t2.execute(PerCacheExecutorThread.Operations.COMMIT_TX);
-         assert t1.execute(PerCacheExecutorThread.Operations.COMMIT_TX) instanceof RollbackException;
-      } else {
-         assert PerCacheExecutorThread.OperationsResult.COMMIT_TX_OK == t1.execute(PerCacheExecutorThread.Operations.COMMIT_TX);
-         assert t2.execute(PerCacheExecutorThread.Operations.COMMIT_TX) instanceof RollbackException;
-      }
-      assert lockManager.getNumberOfLocksHeld() == 0;
-      assertEquals(lockManager.getDetectedLocalDeadlocks(), 1);
-   }
-
-}

Deleted: branches/4.2.x/core/src/test/java/org/infinispan/tx/ReplDeadlockDetectionTest.java
===================================================================
--- branches/4.2.x/core/src/test/java/org/infinispan/tx/ReplDeadlockDetectionTest.java	2010-09-14 17:11:35 UTC (rev 2371)
+++ branches/4.2.x/core/src/test/java/org/infinispan/tx/ReplDeadlockDetectionTest.java	2010-09-15 00:16:18 UTC (rev 2372)
@@ -1,319 +0,0 @@
-package org.infinispan.tx;
-
-import org.infinispan.api.mvcc.LockAssert;
-import org.infinispan.commands.ReplicableCommand;
-import org.infinispan.config.Configuration;
-import org.infinispan.context.impl.NonTxInvocationContext;
-import org.infinispan.interceptors.DeadlockDetectingInterceptor;
-import org.infinispan.interceptors.InterceptorChain;
-import org.infinispan.remoting.ReplicationException;
-import org.infinispan.remoting.responses.Response;
-import org.infinispan.remoting.rpc.ResponseFilter;
-import org.infinispan.remoting.rpc.ResponseMode;
-import org.infinispan.remoting.rpc.RpcManager;
-import org.infinispan.remoting.transport.Address;
-import org.infinispan.remoting.transport.Transport;
-import org.infinispan.statetransfer.StateTransferException;
-import org.infinispan.test.MultipleCacheManagersTest;
-import org.infinispan.test.PerCacheExecutorThread;
-import org.infinispan.test.TestingUtil;
-import org.infinispan.util.concurrent.NotifyingNotifiableFuture;
-import org.infinispan.util.concurrent.locks.DeadlockDetectingLockManager;
-import org.infinispan.util.concurrent.locks.LockManager;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-import java.util.Collection;
-import java.util.List;
-import java.util.concurrent.CountDownLatch;
-
-/**
- * Functional test for deadlock detection.
- *
- * @author Mircea.Markus at jboss.com
- */
- at Test(testName = "tx.ReplDeadlockDetectionTest", groups = "functional")
-public class ReplDeadlockDetectionTest extends MultipleCacheManagersTest {
-
-   protected ControlledRpcManager controlledRpcManager1;
-   protected ControlledRpcManager controlledRpcManager2;
-   protected CountDownLatch replicationLatch;
-   protected PerCacheExecutorThread t1;
-   protected PerCacheExecutorThread t2;
-   protected DeadlockDetectingLockManager ddLm1;
-   protected DeadlockDetectingLockManager ddLm2;
-
-   protected Configuration.CacheMode cacheMode = Configuration.CacheMode.REPL_SYNC;
-
-   protected void createCacheManagers() throws Throwable {
-      Configuration config = getDefaultClusteredConfig(cacheMode, true);
-      config.setEnableDeadlockDetection(true);
-      config.setSyncCommitPhase(true);
-      config.setSyncRollbackPhase(true);
-      config.setUseLockStriping(false);
-      assert config.isEnableDeadlockDetection();
-      createClusteredCaches(2, "test", config);
-      assert config.isEnableDeadlockDetection();
-
-      assert cache(0, "test").getConfiguration().isEnableDeadlockDetection();
-      assert cache(1, "test").getConfiguration().isEnableDeadlockDetection();
-      assert !cache(0, "test").getConfiguration().isExposeJmxStatistics();
-      assert !cache(1, "test").getConfiguration().isExposeJmxStatistics();
-
-      ((DeadlockDetectingLockManager) TestingUtil.extractLockManager(cache(0, "test"))).setExposeJmxStats(true);
-      ((DeadlockDetectingLockManager) TestingUtil.extractLockManager(cache(1, "test"))).setExposeJmxStats(true);
-
-      RpcManager rpcManager1 = TestingUtil.extractComponent(cache(0, "test"), RpcManager.class);
-      RpcManager rpcManager2 = TestingUtil.extractComponent(cache(1, "test"), RpcManager.class);
-
-      controlledRpcManager1 = new ControlledRpcManager(rpcManager1);
-      controlledRpcManager2 = new ControlledRpcManager(rpcManager2);
-      TestingUtil.replaceComponent(cache(0, "test"), RpcManager.class, controlledRpcManager1, true);
-      TestingUtil.replaceComponent(cache(1, "test"), RpcManager.class, controlledRpcManager2, true);
-
-      assert TestingUtil.extractComponent(cache(0, "test"), RpcManager.class) instanceof ControlledRpcManager;
-      assert TestingUtil.extractComponent(cache(1, "test"), RpcManager.class) instanceof ControlledRpcManager;
-
-      ddLm1 = (DeadlockDetectingLockManager) TestingUtil.extractLockManager(cache(0, "test"));
-      ddLm2 = (DeadlockDetectingLockManager) TestingUtil.extractLockManager(cache(1, "test"));
-   }
-
-
-   @BeforeMethod
-   public void beforeMethod() {
-      t1 = new PerCacheExecutorThread(cache(0, "test"), 1);
-      t2 = new PerCacheExecutorThread(cache(1, "test"), 2);
-      replicationLatch = new CountDownLatch(1);
-      controlledRpcManager1.setReplicationLatch(replicationLatch);
-      controlledRpcManager2.setReplicationLatch(replicationLatch);
-      log.trace("_________________________ Here it begins");
-   }
-
-   @AfterMethod
-   public void afterMethod() {
-      t1.stopThread();
-      t2.stopThread();
-      ((DeadlockDetectingLockManager) TestingUtil.extractLockManager(cache(0, "test"))).resetStatistics();
-      ((DeadlockDetectingLockManager) TestingUtil.extractLockManager(cache(1, "test"))).resetStatistics();
-   }
-   
-   public void testExpectedInnerStructure() {
-      LockManager lockManager = TestingUtil.extractComponent(cache(0, "test"), LockManager.class);
-      assert lockManager instanceof DeadlockDetectingLockManager;
-
-      InterceptorChain ic = TestingUtil.extractComponent(cache(0, "test"), InterceptorChain.class);
-      assert ic.containsInterceptorType(DeadlockDetectingInterceptor.class);
-   }
-
-   public void testDeadlockDetectedTwoTransactions() throws Exception {
-      t1.setKeyValue("key", "value1");
-      t2.setKeyValue("key", "value2");
-      assert PerCacheExecutorThread.OperationsResult.BEGGIN_TX_OK == t1.execute(PerCacheExecutorThread.Operations.BEGGIN_TX);
-      assert PerCacheExecutorThread.OperationsResult.BEGGIN_TX_OK == t2.execute(PerCacheExecutorThread.Operations.BEGGIN_TX);
-      System.out.println("After begin");
-
-      t1.execute(PerCacheExecutorThread.Operations.PUT_KEY_VALUE);
-      t2.execute(PerCacheExecutorThread.Operations.PUT_KEY_VALUE);
-      System.out.println("After put key value");
-
-      t1.clearResponse();
-      t2.clearResponse();
-
-      t1.executeNoResponse(PerCacheExecutorThread.Operations.COMMIT_TX);
-      t2.executeNoResponse(PerCacheExecutorThread.Operations.COMMIT_TX);
-
-      System.out.println("Now replication is triggered");
-      replicationLatch.countDown();
-
-
-      Object t1Commit = t1.waitForResponse();
-      Object t2Commit = t2.waitForResponse();
-      System.out.println("After commit: " + t1Commit + ", " + t2Commit);
-
-      assert xor(t1Commit instanceof Exception, t2Commit instanceof Exception) : "only one thread must be failing " + t1Commit + "," + t2Commit;
-      System.out.println("t2Commit = " + t2Commit);
-      System.out.println("t1Commit = " + t1Commit);
-
-      if (t1Commit instanceof Exception) {
-         System.out.println("t1 rolled back");
-         Object o = cache(0, "test").get("key");
-         assert o != null;
-         assert o.equals("value2");
-      } else {
-         System.out.println("t2 rolled back");
-         Object o = cache(0, "test").get("key");
-         assert o != null;
-         assert o.equals("value1");
-         o = cache(1, "test").get("key");
-         assert o != null;
-         assert o.equals("value1");
-      }
-
-      assert ddLm1.getDetectedRemoteDeadlocks() + ddLm2.getDetectedRemoteDeadlocks() >= 1;
-
-      LockManager lm1 = TestingUtil.extractComponent(cache(0, "test"), LockManager.class);
-      assert !lm1.isLocked("key") : "It is locked by " + lm1.getOwner("key");
-      LockManager lm2 = TestingUtil.extractComponent(cache(1, "test"), LockManager.class);
-      assert !lm2.isLocked("key") : "It is locked by " + lm2.getOwner("key");
-      LockAssert.assertNoLocks(cache(0, "test"));
-   }
-
-   public void testDeadlockDetectedOneTx() throws Exception {
-      t1.setKeyValue("key", "value1");
-
-      LockManager lm2 = TestingUtil.extractComponent(cache(1, "test"), LockManager.class);
-      NonTxInvocationContext ctx = cache(1, "test").getAdvancedCache().getInvocationContextContainer().createNonTxInvocationContext();
-      lm2.lockAndRecord("key", ctx);
-      assert lm2.isLocked("key");
-
-
-      assert PerCacheExecutorThread.OperationsResult.BEGGIN_TX_OK == t1.execute(PerCacheExecutorThread.Operations.BEGGIN_TX) : "but received " + t1.lastResponse();
-      t1.execute(PerCacheExecutorThread.Operations.PUT_KEY_VALUE);
-
-      t1.clearResponse();
-      t1.executeNoResponse(PerCacheExecutorThread.Operations.COMMIT_TX);
-
-      replicationLatch.countDown();
-      System.out.println("Now replication is triggered");
-
-      t1.waitForResponse();
-
-
-      Object t1CommitRsp = t1.lastResponse();
-
-      assert t1CommitRsp instanceof Exception : "expected exception, received " + t1.lastResponse();
-
-      LockManager lm1 = TestingUtil.extractComponent(cache(0, "test"), LockManager.class);
-      assert !lm1.isLocked("key") : "It is locked by " + lm1.getOwner("key");
-
-      lm2.unlock("key");
-      assert !lm2.isLocked("key");
-      assert !lm1.isLocked("key");
-   }
-
-   public void testLockReleasedWhileTryingToAcquire() throws Exception {
-      t1.setKeyValue("key", "value1");
-
-      LockManager lm2 = TestingUtil.extractComponent(cache(1, "test"), LockManager.class);
-      NonTxInvocationContext ctx = cache(1, "test").getAdvancedCache().getInvocationContextContainer().createNonTxInvocationContext();
-      lm2.lockAndRecord("key", ctx);
-      assert lm2.isLocked("key");
-
-
-      assert PerCacheExecutorThread.OperationsResult.BEGGIN_TX_OK == t1.execute(PerCacheExecutorThread.Operations.BEGGIN_TX) : "but received " + t1.lastResponse();
-      t1.execute(PerCacheExecutorThread.Operations.PUT_KEY_VALUE);
-
-      t1.clearResponse();
-      t1.executeNoResponse(PerCacheExecutorThread.Operations.COMMIT_TX);
-
-      replicationLatch.countDown();
-
-      Thread.sleep(3000); //just to make sure the remote tx thread managed to spin around for some times.
-      lm2.unlock("key");
-
-      t1.waitForResponse();
-
-
-      Object t1CommitRsp = t1.lastResponse();
-
-      assert t1CommitRsp == PerCacheExecutorThread.OperationsResult.COMMIT_TX_OK : "expected true, received " + t1.lastResponse();
-
-      LockManager lm1 = TestingUtil.extractComponent(cache(0, "test"), LockManager.class);
-      assert !lm1.isLocked("key") : "It is locked by " + lm1.getOwner("key");
-
-      assert !lm2.isLocked("key");
-      assert !lm1.isLocked("key");
-   }
-
-   public static final class ControlledRpcManager implements RpcManager {
-
-      private volatile CountDownLatch replicationLatch;
-
-      public ControlledRpcManager(RpcManager realOne) {
-         this.realOne = realOne;
-      }
-
-      private RpcManager realOne;
-
-      public void setReplicationLatch(CountDownLatch replicationLatch) {
-         this.replicationLatch = replicationLatch;
-      }
-
-      public List<Response> invokeRemotely(Collection<Address> recipients, ReplicableCommand rpcCommand, ResponseMode mode, long timeout, boolean usePriorityQueue, ResponseFilter responseFilter) {
-         return realOne.invokeRemotely(recipients, rpcCommand, mode, timeout, usePriorityQueue, responseFilter);
-      }
-
-      public List<Response> invokeRemotely(Collection<Address> recipients, ReplicableCommand rpcCommand, ResponseMode mode, long timeout, boolean usePriorityQueue) {
-         return realOne.invokeRemotely(recipients, rpcCommand, mode, timeout, usePriorityQueue);
-      }
-
-      public List<Response> invokeRemotely(Collection<Address> recipients, ReplicableCommand rpcCommand, ResponseMode mode, long timeout) throws Exception {
-         return realOne.invokeRemotely(recipients, rpcCommand, mode, timeout);
-      }
-
-      public void retrieveState(String cacheName, long timeout) throws StateTransferException {
-         realOne.retrieveState(cacheName, timeout);
-      }
-
-      public void broadcastRpcCommand(ReplicableCommand rpc, boolean sync) throws ReplicationException {
-         waitFirst();
-         realOne.broadcastRpcCommand(rpc, sync);
-      }
-
-      public void broadcastRpcCommand(ReplicableCommand rpc, boolean sync, boolean usePriorityQueue) throws ReplicationException {
-         waitFirst();
-         realOne.broadcastRpcCommand(rpc, sync, usePriorityQueue);
-      }
-
-      private void waitFirst() {
-         System.out.println(Thread.currentThread().getName() + " -- replication trigger called!");
-         try {
-            replicationLatch.await();
-         } catch (Exception e) {
-            throw new RuntimeException("Unexpected exception!", e);
-         }
-      }
-
-      public void broadcastRpcCommandInFuture(ReplicableCommand rpc, NotifyingNotifiableFuture<Object> future) {
-         realOne.broadcastRpcCommandInFuture(rpc, future);
-      }
-
-      public void broadcastRpcCommandInFuture(ReplicableCommand rpc, boolean usePriorityQueue, NotifyingNotifiableFuture<Object> future) {
-         realOne.broadcastRpcCommandInFuture(rpc, usePriorityQueue, future);
-      }
-
-      public void invokeRemotely(Collection<Address> recipients, ReplicableCommand rpc, boolean sync) throws ReplicationException {
-         realOne.invokeRemotely(recipients, rpc, sync);
-      }
-
-      public void invokeRemotely(Collection<Address> recipients, ReplicableCommand rpc, boolean sync, boolean usePriorityQueue) throws ReplicationException {
-         realOne.invokeRemotely(recipients, rpc, sync, usePriorityQueue);
-      }
-
-      public void invokeRemotelyInFuture(Collection<Address> recipients, ReplicableCommand rpc, NotifyingNotifiableFuture<Object> future) {
-         realOne.invokeRemotelyInFuture(recipients, rpc, future);
-      }
-
-      public void invokeRemotelyInFuture(Collection<Address> recipients, ReplicableCommand rpc, boolean usePriorityQueue, NotifyingNotifiableFuture<Object> future) {
-         realOne.invokeRemotelyInFuture(recipients, rpc, usePriorityQueue, future);
-      }
-
-      public void invokeRemotelyInFuture(Collection<Address> recipients, ReplicableCommand rpc, boolean usePriorityQueue, NotifyingNotifiableFuture<Object> future, long timeout) {
-         realOne.invokeRemotelyInFuture(recipients, rpc, usePriorityQueue, future, timeout);
-      }
-
-      public Transport getTransport() {
-         return realOne.getTransport();
-      }
-
-      public Address getCurrentStateTransferSource() {
-         return realOne.getCurrentStateTransferSource();
-      }
-
-      @Override
-      public Address getAddress() {
-         return null;
-      }
-   }
-}

Copied: branches/4.2.x/core/src/test/java/org/infinispan/tx/dld/AsyncDeadlockDetectionTest.java (from rev 2340, branches/4.2.x/core/src/test/java/org/infinispan/tx/AsyncDeadlockDetectionTest.java)
===================================================================
--- branches/4.2.x/core/src/test/java/org/infinispan/tx/dld/AsyncDeadlockDetectionTest.java	                        (rev 0)
+++ branches/4.2.x/core/src/test/java/org/infinispan/tx/dld/AsyncDeadlockDetectionTest.java	2010-09-15 00:16:18 UTC (rev 2372)
@@ -0,0 +1,186 @@
+package org.infinispan.tx.dld;
+
+import org.infinispan.Cache;
+import org.infinispan.commands.VisitableCommand;
+import org.infinispan.commands.write.PutKeyValueCommand;
+import org.infinispan.config.Configuration;
+import org.infinispan.context.InvocationContext;
+import org.infinispan.interceptors.base.CommandInterceptor;
+import org.infinispan.test.MultipleCacheManagersTest;
+import org.infinispan.test.PerCacheExecutorThread;
+import org.infinispan.test.TestingUtil;
+import org.infinispan.transaction.xa.TransactionTable;
+import org.infinispan.util.concurrent.locks.DeadlockDetectedException;
+import org.infinispan.util.concurrent.locks.DeadlockDetectingLockManager;
+import org.infinispan.util.concurrent.locks.LockManager;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+/**
+ * Tests deadlock detection for async caches.
+ *
+ * @author Mircea.Markus at jboss.com
+ */
+ at Test(groups = "functional", testName = "tx.AsyncDeadlockDetectionTest")
+public class AsyncDeadlockDetectionTest extends MultipleCacheManagersTest {   
+   private PerCacheExecutorThread t0;
+   private PerCacheExecutorThread t1;
+   private RemoteReplicationInterceptor remoteReplicationInterceptor;
+
+
+   protected void createCacheManagers() throws Throwable {
+      Configuration config = getDefaultClusteredConfig(Configuration.CacheMode.REPL_ASYNC, true);
+      config.setEnableDeadlockDetection(true);
+      config.setSyncCommitPhase(true);
+      config.setSyncRollbackPhase(true);
+      config.setUseLockStriping(false);
+      assert config.isEnableDeadlockDetection();
+      createClusteredCaches(2, "test", config);
+      assert config.isEnableDeadlockDetection();
+
+      
+      remoteReplicationInterceptor = new RemoteReplicationInterceptor();
+      Cache cache0 = cache(0, "test");
+      Cache cache1 = cache(1, "test");
+      cache1.getAdvancedCache().addInterceptor(remoteReplicationInterceptor, 0);
+      assert cache0.getConfiguration().isEnableDeadlockDetection();
+      assert cache1.getConfiguration().isEnableDeadlockDetection();
+      assert !cache0.getConfiguration().isExposeJmxStatistics();
+      assert !cache1.getConfiguration().isExposeJmxStatistics();
+
+      ((DeadlockDetectingLockManager) TestingUtil.extractLockManager(cache0)).setExposeJmxStats(true);
+      ((DeadlockDetectingLockManager) TestingUtil.extractLockManager(cache1)).setExposeJmxStats(true);
+   }
+
+   @BeforeMethod
+   public void beforeMethod() {
+      Cache cache0 = cache(0, "test");
+      Cache cache1 = cache(1, "test");
+      t0 = new PerCacheExecutorThread(cache0, 0);
+      t1 = new PerCacheExecutorThread(cache1, 1);
+   }
+
+   @AfterMethod
+   public void afterMethod() {
+      Cache cache0 = cache(0, "test");
+      Cache cache1 = cache(1, "test");
+      t0.stopThread();
+      t1.stopThread();
+      ((DeadlockDetectingLockManager) TestingUtil.extractLockManager(cache0)).resetStatistics();
+      ((DeadlockDetectingLockManager) TestingUtil.extractLockManager(cache1)).resetStatistics();
+      remoteReplicationInterceptor.executionResponse = null;
+      remoteReplicationInterceptor = null;
+      t0 = null;
+      t1 = null;
+   }
+
+   public void testRemoteTxVsLocal() throws Exception {
+      Cache cache0 = cache(0, "test");
+      Cache cache1 = cache(1, "test");
+      assertEquals(PerCacheExecutorThread.OperationsResult.BEGGIN_TX_OK, t0.execute(PerCacheExecutorThread.Operations.BEGGIN_TX));
+      t0.setKeyValue("k1", "v1_t0");
+      assertEquals(PerCacheExecutorThread.OperationsResult.PUT_KEY_VALUE_OK, t0.execute(PerCacheExecutorThread.Operations.PUT_KEY_VALUE));
+      t0.setKeyValue("k2", "v2_t0");
+      assertEquals(PerCacheExecutorThread.OperationsResult.PUT_KEY_VALUE_OK, t0.execute(PerCacheExecutorThread.Operations.PUT_KEY_VALUE));
+
+      assertEquals(PerCacheExecutorThread.OperationsResult.BEGGIN_TX_OK, t1.execute(PerCacheExecutorThread.Operations.BEGGIN_TX));
+      t1.setKeyValue("k2", "v2_t1");
+      assertEquals(PerCacheExecutorThread.OperationsResult.PUT_KEY_VALUE_OK, t1.execute(PerCacheExecutorThread.Operations.PUT_KEY_VALUE));
+
+      t0.execute(PerCacheExecutorThread.Operations.COMMIT_TX);
+
+      final LockManager lm1 = TestingUtil.extractLockManager(cache1);
+
+      eventually(new Condition() {
+         public boolean isSatisfied() throws Exception {
+            return lm1.isLocked("k1");
+         }
+      }); //now t0 replicated, acquired lock on k1 and it tries to acquire lock on k2
+
+
+      t1.setKeyValue("k1", "v1_t1");
+      t1.executeNoResponse(PerCacheExecutorThread.Operations.PUT_KEY_VALUE);
+
+
+      Object t1Response = t1.waitForResponse();
+      Object t0Response = remoteReplicationInterceptor.getResponse();
+
+      log.trace("t0Response = " + t0Response);
+      log.trace("t1Response = " + t1Response);
+
+      assert xor(t1Response instanceof DeadlockDetectedException, t0Response instanceof DeadlockDetectedException);
+      TransactionTable transactionTable1 = TestingUtil.extractComponent(cache1, TransactionTable.class);
+
+
+      if (t0Response instanceof DeadlockDetectedException) {
+         replListener(cache0).expectWithTx(PutKeyValueCommand.class, PutKeyValueCommand.class);
+         assertEquals(t1.execute(PerCacheExecutorThread.Operations.COMMIT_TX), PerCacheExecutorThread.OperationsResult.COMMIT_TX_OK);
+         replListener(cache0).waitForRpc();
+         assertEquals(transactionTable1.getLocalTxCount(), 0);         
+      }
+
+      DeadlockDetectingLockManager ddLm0 = (DeadlockDetectingLockManager) TestingUtil.extractLockManager(cache0);
+      DeadlockDetectingLockManager ddLm1 = (DeadlockDetectingLockManager) TestingUtil.extractLockManager(cache1);
+      
+      assertFalse(ddLm0.isLocked("k1"));
+      assertFalse(ddLm1.isLocked("k1"));
+      assertFalse(ddLm0.isLocked("k2"));
+      assertFalse(ddLm1.isLocked("k2"));
+      TransactionTable transactionTable0 = TestingUtil.extractComponent(cache0, TransactionTable.class);
+      assertEquals(transactionTable0.getLocalTxCount(), 0);
+      for (int i = 0; i < 20; i++) {
+         if (!(transactionTable0.getRemoteTxCount() == 0)) Thread.sleep(50);
+      }
+
+      assertEquals(transactionTable0.getRemoteTxCount(), 0);
+
+      for (int i = 0; i < 20; i++) {
+         if (!(transactionTable1.getRemoteTxCount() == 0)) Thread.sleep(50);
+      }
+      assertEquals(transactionTable1.getRemoteTxCount(), 0);
+
+      if (t1Response instanceof DeadlockDetectedException) {
+         assertEquals(cache0.get("k1"), "v1_t0");
+         assertEquals(cache0.get("k2"), "v2_t0");
+         assertEquals(cache1.get("k1"), "v1_t0");
+         assertEquals(cache1.get("k2"), "v2_t0");
+      } else {
+         assertEquals(cache0.get("k1"), "v1_t1");
+         assertEquals(cache0.get("k2"), "v2_t1");
+         assertEquals(cache1.get("k1"), "v1_t1");
+         assertEquals(cache1.get("k2"), "v2_t1");
+      }
+   }
+
+
+   public static class RemoteReplicationInterceptor extends CommandInterceptor {
+
+      public volatile Object executionResponse;
+
+      @Override
+      protected Object handleDefault(InvocationContext ctx, VisitableCommand command) throws Throwable {
+         try {
+            return invokeNextInterceptor(ctx, command);
+         } catch (Throwable throwable) {
+            if (!ctx.isOriginLocal()) {
+               log.trace("Setting executionResponse to " + throwable);
+               executionResponse = throwable;
+            } else {
+               log.trace("Ignoring throwable " + throwable);
+               executionResponse = "NONE";
+            }
+            throw throwable;
+         }
+      }
+
+      public Object getResponse() throws Exception {
+         while (executionResponse == null) {
+            Thread.sleep(50);
+         }
+         return executionResponse;
+      }
+   }
+}


Property changes on: branches/4.2.x/core/src/test/java/org/infinispan/tx/dld/AsyncDeadlockDetectionTest.java
___________________________________________________________________
Name: svn:keywords
   + Id Revision
Name: svn:eol-style
   + LF

Added: branches/4.2.x/core/src/test/java/org/infinispan/tx/dld/BaseDldEagerLockingTest.java
===================================================================
--- branches/4.2.x/core/src/test/java/org/infinispan/tx/dld/BaseDldEagerLockingTest.java	                        (rev 0)
+++ branches/4.2.x/core/src/test/java/org/infinispan/tx/dld/BaseDldEagerLockingTest.java	2010-09-15 00:16:18 UTC (rev 2372)
@@ -0,0 +1,104 @@
+package org.infinispan.tx.dld;
+
+import org.infinispan.test.PerCacheExecutorThread;
+import org.infinispan.test.TestingUtil;
+import org.infinispan.util.concurrent.locks.DeadlockDetectingLockManager;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+
+import javax.transaction.RollbackException;
+import javax.transaction.Status;
+import javax.transaction.SystemException;
+
+import static org.testng.Assert.assertEquals;
+
+/**
+ * // TODO: Document this
+ *
+ * @author Mircea.Markus at jboss.com
+ * @since 4.2
+ */
+public abstract class BaseDldEagerLockingTest extends BaseDldTest {
+   protected PerCacheExecutorThread ex0;
+   protected PerCacheExecutorThread ex1;
+   protected DeadlockDetectingLockManager lm0;
+   protected DeadlockDetectingLockManager lm1;
+
+   @BeforeMethod
+   public void beforeMethod() {
+      ex0 = new PerCacheExecutorThread(cache(0), 0);
+      ex1 = new PerCacheExecutorThread(cache(1), 1);
+
+      lm0 = (DeadlockDetectingLockManager) TestingUtil.extractLockManager(cache(0));
+      lm0.setExposeJmxStats(true);
+      lm1 = (DeadlockDetectingLockManager) TestingUtil.extractLockManager(cache(1));
+      lm1.setExposeJmxStats(true);
+   }
+
+   @AfterMethod
+   public void afterMethod() {
+      ex0.stopThread();
+      ex1.stopThread();
+   }
+
+   protected void testSymmetricDld(Object k0, Object k1) throws SystemException {
+
+      long start = System.currentTimeMillis();
+
+      log.trace("Here is where the test starts");
+
+      ex0.execute(PerCacheExecutorThread.Operations.BEGGIN_TX);
+      ex1.execute(PerCacheExecutorThread.Operations.BEGGIN_TX);
+
+
+      ex0.setKeyValue(k0, "v0_0");
+      assertEquals(ex0.execute(PerCacheExecutorThread.Operations.PUT_KEY_VALUE), PerCacheExecutorThread.OperationsResult.PUT_KEY_VALUE_OK);
+      ex1.setKeyValue(k1, "v1_1");
+      assertEquals(ex1.execute(PerCacheExecutorThread.Operations.PUT_KEY_VALUE), PerCacheExecutorThread.OperationsResult.PUT_KEY_VALUE_OK);
+
+      assert lm0.isLocked(k0);
+//      assert lm0.isLocked(k1);
+//      assert lm1.isLocked(k0);
+      assert lm1.isLocked(k1);
+
+      log.trace("After first set of puts");
+
+      ex0.clearResponse();
+      ex1.clearResponse();
+
+      log.info("Here is where DLD happens");
+
+      ex1.setKeyValue(k0, "v0_1");
+      ex1.executeNoResponse(PerCacheExecutorThread.Operations.PUT_KEY_VALUE);
+      ex0.setKeyValue(k1, "v1_0");
+      ex0.executeNoResponse(PerCacheExecutorThread.Operations.PUT_KEY_VALUE);
+      ex0.waitForResponse();
+      ex1.waitForResponse();
+
+      boolean b1 = ex0.lastResponse() instanceof Exception;
+      boolean b2 = ex1.lastResponse() instanceof Exception;
+      log.info("b1:", b1);
+      log.info("b2:", b2);
+      assert xor(b1, b2) : "Both are " + (b1 || b2);
+
+      assert xor(ex0.getOngoingTransaction().getStatus() == Status.STATUS_MARKED_ROLLBACK,
+                 ex1.getOngoingTransaction().getStatus() == Status.STATUS_MARKED_ROLLBACK);
+
+      Object txOutcome1 = ex0.execute(PerCacheExecutorThread.Operations.COMMIT_TX);
+      Object txOutcome2 = ex1.execute(PerCacheExecutorThread.Operations.COMMIT_TX);
+      assert xor(txOutcome1 == PerCacheExecutorThread.OperationsResult.COMMIT_TX_OK, txOutcome2 == PerCacheExecutorThread.OperationsResult.COMMIT_TX_OK);
+      assert xor(txOutcome1 instanceof RollbackException, txOutcome2 instanceof RollbackException);
+
+      assert cache(0).get(k0) != null;
+      assert cache(0).get(k1) != null;
+      assert cache(1).get(k0) != null;
+      assert cache(1).get(k1) != null;
+
+      long totalDeadlocks = lm0.getTotalNumberOfDetectedDeadlocks() + lm1.getTotalNumberOfDetectedDeadlocks();
+      assert totalDeadlocks == 1 : "Expected 1 but received " + totalDeadlocks;
+
+      System.out.println("Test took " + (System.currentTimeMillis() - start) + " millis.");
+   }
+
+
+}

Added: branches/4.2.x/core/src/test/java/org/infinispan/tx/dld/BaseDldLazyLockingTest.java
===================================================================
--- branches/4.2.x/core/src/test/java/org/infinispan/tx/dld/BaseDldLazyLockingTest.java	                        (rev 0)
+++ branches/4.2.x/core/src/test/java/org/infinispan/tx/dld/BaseDldLazyLockingTest.java	2010-09-15 00:16:18 UTC (rev 2372)
@@ -0,0 +1,82 @@
+package org.infinispan.tx.dld;
+
+import org.infinispan.Cache;
+import org.infinispan.remoting.rpc.RpcManager;
+import org.infinispan.test.MultipleCacheManagersTest;
+import org.infinispan.test.PerCacheExecutorThread;
+import org.infinispan.test.TestingUtil;
+import org.infinispan.util.concurrent.locks.DeadlockDetectingLockManager;
+import org.infinispan.util.concurrent.locks.LockManager;
+
+import java.util.concurrent.CountDownLatch;
+
+import static org.testng.Assert.assertEquals;
+
+/**
+ * // TODO: Document this
+ *
+ * @author Mircea.Markus at jboss.com
+ * @since 4.2
+ */
+public abstract class BaseDldLazyLockingTest extends BaseDldTest {
+
+   protected void testSymmetricDeadlock(Object k0, Object k1) {
+
+      CountDownLatch replLatch = new CountDownLatch(1);
+      rpcManager0.setReplicationLatch(replLatch);
+      rpcManager1.setReplicationLatch(replLatch);
+
+      DeadlockDetectingLockManager ddLm0 = (DeadlockDetectingLockManager) TestingUtil.extractLockManager(cache(0));
+      ddLm0.setExposeJmxStats(true);
+      DeadlockDetectingLockManager ddLm1 = (DeadlockDetectingLockManager) TestingUtil.extractLockManager(cache(1));
+      ddLm1.setExposeJmxStats(true);
+
+
+      PerCacheExecutorThread t0 = new PerCacheExecutorThread(cache(0), 0);
+      PerCacheExecutorThread t1 = new PerCacheExecutorThread(cache(1), 1);
+
+      assert PerCacheExecutorThread.OperationsResult.BEGGIN_TX_OK == t0.execute(PerCacheExecutorThread.Operations.BEGGIN_TX);
+      assert PerCacheExecutorThread.OperationsResult.BEGGIN_TX_OK == t1.execute(PerCacheExecutorThread.Operations.BEGGIN_TX);
+
+      t0.setKeyValue(k0, "k0_0");
+      t1.setKeyValue(k1, "k1_0");
+
+      t0.execute(PerCacheExecutorThread.Operations.PUT_KEY_VALUE);
+      t1.execute(PerCacheExecutorThread.Operations.PUT_KEY_VALUE);
+
+      t0.setKeyValue(k1, "k1_0");
+      t1.setKeyValue(k0, "k0_1");
+
+      assertEquals(t0.execute(PerCacheExecutorThread.Operations.PUT_KEY_VALUE), PerCacheExecutorThread.OperationsResult.PUT_KEY_VALUE_OK);
+      assertEquals(t1.execute(PerCacheExecutorThread.Operations.PUT_KEY_VALUE), PerCacheExecutorThread.OperationsResult.PUT_KEY_VALUE_OK);
+
+      log.info("---Before commit");
+      t0.executeNoResponse(PerCacheExecutorThread.Operations.COMMIT_TX);
+      t1.executeNoResponse(PerCacheExecutorThread.Operations.COMMIT_TX);
+
+      replLatch.countDown();
+
+
+      Object t0Response = t0.waitForResponse();
+      Object t1Response = t1.waitForResponse();
+
+      assert xor(t0Response instanceof Exception, t1Response instanceof Exception);
+
+      if (t0Response instanceof Exception) {
+         Object o = cache(0).get(k0);
+         assert o != null;
+         assert o.equals("k0_1");
+      } else {
+         Object o = cache(1).get(k0);
+         assert o != null;
+         assert o.equals("k0_0");
+      }
+
+      assert ddLm0.getDetectedRemoteDeadlocks() + ddLm1.getDetectedRemoteDeadlocks() >= 1;
+
+      LockManager lm0 = TestingUtil.extractComponent(cache(0), LockManager.class);
+      assert !lm0.isLocked("key") : "It is locked by " + lm0.getOwner("key");
+      LockManager lm1 = TestingUtil.extractComponent(cache(1), LockManager.class);
+      assert !lm1.isLocked("key") : "It is locked by " + lm1.getOwner("key");
+   }
+}

Added: branches/4.2.x/core/src/test/java/org/infinispan/tx/dld/BaseDldTest.java
===================================================================
--- branches/4.2.x/core/src/test/java/org/infinispan/tx/dld/BaseDldTest.java	                        (rev 0)
+++ branches/4.2.x/core/src/test/java/org/infinispan/tx/dld/BaseDldTest.java	2010-09-15 00:16:18 UTC (rev 2372)
@@ -0,0 +1,26 @@
+package org.infinispan.tx.dld;
+
+import org.infinispan.Cache;
+import org.infinispan.remoting.rpc.RpcManager;
+import org.infinispan.test.MultipleCacheManagersTest;
+import org.infinispan.test.TestingUtil;
+
+/**
+ * // TODO: Document this
+ *
+ * @author Mircea.Markus at jboss.com
+ * @since 4.2
+ */
+public abstract class BaseDldTest extends MultipleCacheManagersTest {
+
+   protected ControlledRpcManager rpcManager0;
+   protected ControlledRpcManager rpcManager1;   
+
+   public static ControlledRpcManager replaceRpcManager(Cache cache) {
+      RpcManager rpcManager1 = TestingUtil.extractComponent(cache, RpcManager.class);
+      ControlledRpcManager controlledRpcManager1 = new ControlledRpcManager(rpcManager1);
+      TestingUtil.replaceComponent(cache, RpcManager.class, controlledRpcManager1, true);
+      return controlledRpcManager1;
+   }
+
+}

Added: branches/4.2.x/core/src/test/java/org/infinispan/tx/dld/ControlledRpcManager.java
===================================================================
--- branches/4.2.x/core/src/test/java/org/infinispan/tx/dld/ControlledRpcManager.java	                        (rev 0)
+++ branches/4.2.x/core/src/test/java/org/infinispan/tx/dld/ControlledRpcManager.java	2010-09-15 00:16:18 UTC (rev 2372)
@@ -0,0 +1,118 @@
+package org.infinispan.tx.dld;
+
+import org.infinispan.commands.ReplicableCommand;
+import org.infinispan.commands.control.LockControlCommand;
+import org.infinispan.commands.remote.ClusteredGetCommand;
+import org.infinispan.remoting.ReplicationException;
+import org.infinispan.remoting.responses.Response;
+import org.infinispan.remoting.rpc.ResponseFilter;
+import org.infinispan.remoting.rpc.ResponseMode;
+import org.infinispan.remoting.rpc.RpcManager;
+import org.infinispan.remoting.transport.Address;
+import org.infinispan.remoting.transport.Transport;
+import org.infinispan.statetransfer.StateTransferException;
+import org.infinispan.util.concurrent.NotifyingNotifiableFuture;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+
+/**
+* @author Mircea.Markus at jboss.com
+* @since 4.2
+*/
+public final class ControlledRpcManager implements RpcManager {
+
+   private volatile CountDownLatch replicationLatch;
+
+   public ControlledRpcManager(RpcManager realOne) {
+      this.realOne = realOne;
+   }
+
+   private RpcManager realOne;
+
+   public void setReplicationLatch(CountDownLatch replicationLatch) {
+      this.replicationLatch = replicationLatch;
+   }
+
+   public List<Response> invokeRemotely(Collection<Address> recipients, ReplicableCommand rpcCommand, ResponseMode mode, long timeout, boolean usePriorityQueue, ResponseFilter responseFilter) {
+      waitFirst(rpcCommand);
+      return realOne.invokeRemotely(recipients, rpcCommand, mode, timeout, usePriorityQueue, responseFilter);
+   }
+
+   public List<Response> invokeRemotely(Collection<Address> recipients, ReplicableCommand rpcCommand, ResponseMode mode, long timeout, boolean usePriorityQueue) {
+      waitFirst(rpcCommand);
+      return realOne.invokeRemotely(recipients, rpcCommand, mode, timeout, usePriorityQueue);
+   }
+
+   public List<Response> invokeRemotely(Collection<Address> recipients, ReplicableCommand rpcCommand, ResponseMode mode, long timeout) throws Exception {
+      waitFirst(rpcCommand);
+      return realOne.invokeRemotely(recipients, rpcCommand, mode, timeout);
+   }
+
+   public void retrieveState(String cacheName, long timeout) throws StateTransferException {
+      realOne.retrieveState(cacheName, timeout);
+   }
+
+   public void broadcastRpcCommand(ReplicableCommand rpc, boolean sync) throws ReplicationException {
+      waitFirst(rpc);
+      realOne.broadcastRpcCommand(rpc, sync);
+   }
+
+   public void broadcastRpcCommand(ReplicableCommand rpc, boolean sync, boolean usePriorityQueue) throws ReplicationException {
+      waitFirst(rpc);
+      realOne.broadcastRpcCommand(rpc, sync, usePriorityQueue);
+   }
+
+   private void waitFirst(ReplicableCommand rpcCommand) {
+      if (!(rpcCommand instanceof ClusteredGetCommand) && !(rpcCommand instanceof LockControlCommand)) {
+         System.out.println(Thread.currentThread().getName() + " -- replication trigger called!");
+         try {
+            replicationLatch.await();
+         } catch (Exception e) {
+            throw new RuntimeException("Unexpected exception!", e);
+         }
+      }
+
+   }
+
+   public void broadcastRpcCommandInFuture(ReplicableCommand rpc, NotifyingNotifiableFuture<Object> future) {
+      realOne.broadcastRpcCommandInFuture(rpc, future);
+   }
+
+   public void broadcastRpcCommandInFuture(ReplicableCommand rpc, boolean usePriorityQueue, NotifyingNotifiableFuture<Object> future) {
+      realOne.broadcastRpcCommandInFuture(rpc, usePriorityQueue, future);
+   }
+
+   public void invokeRemotely(Collection<Address> recipients, ReplicableCommand rpc, boolean sync) throws ReplicationException {
+      realOne.invokeRemotely(recipients, rpc, sync);
+   }
+
+   public void invokeRemotely(Collection<Address> recipients, ReplicableCommand rpc, boolean sync, boolean usePriorityQueue) throws ReplicationException {
+      realOne.invokeRemotely(recipients, rpc, sync, usePriorityQueue);
+   }
+
+   public void invokeRemotelyInFuture(Collection<Address> recipients, ReplicableCommand rpc, NotifyingNotifiableFuture<Object> future) {
+      realOne.invokeRemotelyInFuture(recipients, rpc, future);
+   }
+
+   public void invokeRemotelyInFuture(Collection<Address> recipients, ReplicableCommand rpc, boolean usePriorityQueue, NotifyingNotifiableFuture<Object> future) {
+      realOne.invokeRemotelyInFuture(recipients, rpc, usePriorityQueue, future);
+   }
+
+   public void invokeRemotelyInFuture(Collection<Address> recipients, ReplicableCommand rpc, boolean usePriorityQueue, NotifyingNotifiableFuture<Object> future, long timeout) {
+      realOne.invokeRemotelyInFuture(recipients, rpc, usePriorityQueue, future, timeout);
+   }
+
+   public Transport getTransport() {
+      return realOne.getTransport();
+   }
+
+   public Address getCurrentStateTransferSource() {
+      return realOne.getCurrentStateTransferSource();
+   }
+
+   public Address getAddress() {
+      return realOne.getAddress();
+   }
+}

Added: branches/4.2.x/core/src/test/java/org/infinispan/tx/dld/DldEagerLockingDistributedTest.java
===================================================================
--- branches/4.2.x/core/src/test/java/org/infinispan/tx/dld/DldEagerLockingDistributedTest.java	                        (rev 0)
+++ branches/4.2.x/core/src/test/java/org/infinispan/tx/dld/DldEagerLockingDistributedTest.java	2010-09-15 00:16:18 UTC (rev 2372)
@@ -0,0 +1,57 @@
+package org.infinispan.tx.dld;
+
+import org.infinispan.affinity.KeyAffinityService;
+import org.infinispan.affinity.KeyAffinityServiceFactory;
+import org.infinispan.affinity.RndKeyGenerator;
+import org.infinispan.config.Configuration;
+import org.infinispan.distribution.BaseDistFunctionalTest;
+import org.infinispan.manager.EmbeddedCacheManager;
+import org.infinispan.test.TestingUtil;
+import org.infinispan.test.fwk.TestCacheManagerFactory;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.Test;
+
+import javax.transaction.SystemException;
+import java.util.concurrent.Executor;
+
+/**
+ * // TODO: Document this
+ *
+ * @author Mircea.Markus at jboss.com
+ * @since 4.2
+ */
+ at Test (groups = "functional", testName = "tx.dld.DldEagerLockingDistributedTest")
+public class DldEagerLockingDistributedTest extends BaseDldEagerLockingTest {
+
+   private KeyAffinityService cas;
+   private Object k0;
+   private Object k1;
+
+   @Override
+   protected void createCacheManagers() throws Throwable {
+      Configuration config = getDefaultClusteredConfig(Configuration.CacheMode.DIST_SYNC);
+      config.setUnsafeUnreliableReturnValues(true);
+      config.setNumOwners(1);
+      config.setEnableDeadlockDetection(true);
+      config.setUseEagerLocking(true);
+      EmbeddedCacheManager cm1 = TestCacheManagerFactory.createCacheManager(config, true);
+      EmbeddedCacheManager cm2 = TestCacheManagerFactory.createCacheManager(config, true);
+      registerCacheManager(cm1);
+      registerCacheManager(cm2);
+      TestingUtil.blockUntilViewsReceived(10000, cache(0), cache(1));
+      BaseDistFunctionalTest.RehashWaiter.waitForInitRehashToComplete(cache(0), cache(1));
+
+      cas = KeyAffinityServiceFactory.newKeyAffinityService(cache(0), new Executor() {
+         public void execute(Runnable command) {
+            new Thread(command).start();
+         }
+      }, new RndKeyGenerator(), 2, true);
+      k0 = cas.getKeyForAddress(address(0));
+      k1 = cas.getKeyForAddress(address(1));
+      cas.stop();
+   }
+
+   public void testSymmetricDeadlock() throws SystemException {
+      testSymmetricDld(k0, k1);
+   }
+}

Copied: branches/4.2.x/core/src/test/java/org/infinispan/tx/dld/DldEagerLockingReplicationTest.java (from rev 2340, branches/4.2.x/core/src/test/java/org/infinispan/tx/EagerTxDeadlockDetectionTest.java)
===================================================================
--- branches/4.2.x/core/src/test/java/org/infinispan/tx/dld/DldEagerLockingReplicationTest.java	                        (rev 0)
+++ branches/4.2.x/core/src/test/java/org/infinispan/tx/dld/DldEagerLockingReplicationTest.java	2010-09-15 00:16:18 UTC (rev 2372)
@@ -0,0 +1,63 @@
+package org.infinispan.tx.dld;
+
+import org.infinispan.config.Configuration;
+import org.infinispan.context.Flag;
+import org.infinispan.test.PerCacheExecutorThread;
+import org.infinispan.test.TestingUtil;
+import org.infinispan.util.concurrent.TimeoutException;
+import org.testng.annotations.Test;
+
+import javax.transaction.TransactionManager;
+
+/**
+ * @author Mircea.Markus at jboss.com
+ * @since 4.1
+ */
+ at Test(groups = "functional", testName = "tx.EagerTxDeadlockDetectionTest")
+public class DldEagerLockingReplicationTest extends BaseDldEagerLockingTest {
+
+   @Override
+   protected void createCacheManagers() throws Throwable {
+      Configuration configuration = getConfiguration();
+      createClusteredCaches(2, configuration);
+      TestingUtil.blockUntilViewsReceived(1000, cache(0), cache(1));
+   }
+
+   protected Configuration getConfiguration() throws Exception {
+      Configuration configuration = getDefaultClusteredConfig(Configuration.CacheMode.REPL_SYNC, true);
+      configuration.setUseEagerLocking(true);
+      configuration.setEnableDeadlockDetection(true);
+      configuration.setUseLockStriping(false);
+      return configuration;
+   }
+
+   public void testDeadlock() throws Exception {
+      testSymmetricDld("k1", "k2");
+   }
+
+   /**
+    * On eager locking, remote locks are being acquired at first, and then local locks. This is for specifying the
+    * behavior whe remote acquisition succeeds and local fails.
+    */
+   public void testDeadlockFailedToAcquireLocalLocks() throws Exception {
+      //first acquire a local lock on k1
+      TransactionManager tm = TestingUtil.getTransactionManager(cache(0));
+      tm.begin();
+      cache(0).getAdvancedCache().withFlags(Flag.CACHE_MODE_LOCAL).put("k1","v1");
+      assert lm0.isLocked("k1");
+      assert !lm1.isLocked("k1");
+      try {
+         ex0.execute(PerCacheExecutorThread.Operations.BEGGIN_TX);
+         ex0.setKeyValue("k1", "v1_1");
+         ex0.execute(PerCacheExecutorThread.Operations.PUT_KEY_VALUE);
+         assert ex0.lastResponse() instanceof TimeoutException;
+         eventually(new Condition() {
+            public boolean isSatisfied() throws Exception {
+               return !lm1.isLocked("k1");
+            }
+         });
+      } finally {
+         tm.rollback();
+      }
+   }
+}

Added: branches/4.2.x/core/src/test/java/org/infinispan/tx/dld/DldLazyLockingDistributionTest.java
===================================================================
--- branches/4.2.x/core/src/test/java/org/infinispan/tx/dld/DldLazyLockingDistributionTest.java	                        (rev 0)
+++ branches/4.2.x/core/src/test/java/org/infinispan/tx/dld/DldLazyLockingDistributionTest.java	2010-09-15 00:16:18 UTC (rev 2372)
@@ -0,0 +1,61 @@
+package org.infinispan.tx.dld;
+
+import org.infinispan.affinity.KeyAffinityService;
+import org.infinispan.affinity.KeyAffinityServiceFactory;
+import org.infinispan.affinity.RndKeyGenerator;
+import org.infinispan.config.Configuration;
+import org.infinispan.distribution.BaseDistFunctionalTest;
+import org.infinispan.manager.EmbeddedCacheManager;
+import org.infinispan.test.TestingUtil;
+import org.infinispan.test.fwk.TestCacheManagerFactory;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.Test;
+
+import java.util.concurrent.Executor;
+
+/**
+ * Tests deadlock detection when t1 acquire (k1, k2) and te acquires (k2, k1).
+ *
+ * @author Mircea.Markus at jboss.com
+ * @since 4.2
+ */
+ at Test(groups = "functional", testName = "tx.DistSymmetricDldTest")
+public class DldLazyLockingDistributionTest extends BaseDldLazyLockingTest {
+
+   private KeyAffinityService cas;
+
+   @Override
+   protected void createCacheManagers() throws Throwable {
+      Configuration config = getDefaultClusteredConfig(Configuration.CacheMode.DIST_SYNC);
+      config.setUnsafeUnreliableReturnValues(true);
+      config.setNumOwners(1);
+      config.setEnableDeadlockDetection(true);
+      EmbeddedCacheManager cm1 = TestCacheManagerFactory.createCacheManager(config, true);
+      EmbeddedCacheManager cm2 = TestCacheManagerFactory.createCacheManager(config, true);
+      registerCacheManager(cm1);
+      registerCacheManager(cm2);
+      TestingUtil.blockUntilViewsReceived(10000, cache(0), cache(1));
+      BaseDistFunctionalTest.RehashWaiter.waitForInitRehashToComplete(cache(0), cache(1));
+
+      cas = KeyAffinityServiceFactory.newKeyAffinityService(cache(0), new Executor() {
+         public void execute(Runnable command) {
+            new Thread(command).start();
+         }
+      }, new RndKeyGenerator(), 2, true);
+
+      rpcManager0 = DldLazyLockingReplicationTest.replaceRpcManager(cache(0));
+      rpcManager1 = DldLazyLockingReplicationTest.replaceRpcManager(cache(1));
+   }
+
+   public void testSymmetricDeadlock() {
+      Object k0 = cas.getKeyForAddress(address(0));
+      Object k1 = cas.getKeyForAddress(address(1));
+      testSymmetricDeadlock(k0, k1);
+   }
+
+   @AfterClass
+   public void destroyKeyService() {
+      cas.stop();
+   }
+
+}

Copied: branches/4.2.x/core/src/test/java/org/infinispan/tx/dld/DldLazyLockingReplicationTest.java (from rev 2340, branches/4.2.x/core/src/test/java/org/infinispan/tx/ReplDeadlockDetectionTest.java)
===================================================================
--- branches/4.2.x/core/src/test/java/org/infinispan/tx/dld/DldLazyLockingReplicationTest.java	                        (rev 0)
+++ branches/4.2.x/core/src/test/java/org/infinispan/tx/dld/DldLazyLockingReplicationTest.java	2010-09-15 00:16:18 UTC (rev 2372)
@@ -0,0 +1,212 @@
+package org.infinispan.tx.dld;
+
+import org.infinispan.api.mvcc.LockAssert;
+import org.infinispan.config.Configuration;
+import org.infinispan.context.impl.NonTxInvocationContext;
+import org.infinispan.interceptors.DeadlockDetectingInterceptor;
+import org.infinispan.interceptors.InterceptorChain;
+import org.infinispan.remoting.rpc.RpcManager;
+import org.infinispan.test.PerCacheExecutorThread;
+import org.infinispan.test.TestingUtil;
+import org.infinispan.util.concurrent.locks.DeadlockDetectingLockManager;
+import org.infinispan.util.concurrent.locks.LockManager;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import java.util.concurrent.CountDownLatch;
+
+/**
+ * Functional test for deadlock detection.
+ *
+ * @author Mircea.Markus at jboss.com
+ */
+ at Test(testName = "tx.ReplDeadlockDetectionTest", groups = "functional")
+public class DldLazyLockingReplicationTest extends BaseDldLazyLockingTest {
+
+   protected CountDownLatch replicationLatch;
+   protected PerCacheExecutorThread t1;
+   protected PerCacheExecutorThread t2;
+   protected DeadlockDetectingLockManager ddLm1;
+   protected DeadlockDetectingLockManager ddLm2;
+
+   protected void createCacheManagers() throws Throwable {
+      Configuration config = getDefaultClusteredConfig(Configuration.CacheMode.REPL_SYNC, true);
+      config.setEnableDeadlockDetection(true);
+      config.setSyncCommitPhase(true);
+      config.setSyncRollbackPhase(true);
+      config.setUseLockStriping(false);
+      assert config.isEnableDeadlockDetection();
+      createClusteredCaches(2, config);
+      assert config.isEnableDeadlockDetection();
+
+      assert cache(0).getConfiguration().isEnableDeadlockDetection();
+      assert cache(1).getConfiguration().isEnableDeadlockDetection();
+      assert !cache(0).getConfiguration().isExposeJmxStatistics();
+      assert !cache(1).getConfiguration().isExposeJmxStatistics();
+
+      ((DeadlockDetectingLockManager) TestingUtil.extractLockManager(cache(0))).setExposeJmxStats(true);
+      ((DeadlockDetectingLockManager) TestingUtil.extractLockManager(cache(1))).setExposeJmxStats(true);
+
+      rpcManager0 = replaceRpcManager(cache(0));
+      rpcManager1 = replaceRpcManager(cache(1));
+
+      assert TestingUtil.extractComponent(cache(0), RpcManager.class) instanceof ControlledRpcManager;
+      assert TestingUtil.extractComponent(cache(1), RpcManager.class) instanceof ControlledRpcManager;
+
+      ddLm1 = (DeadlockDetectingLockManager) TestingUtil.extractLockManager(cache(0));
+      ddLm2 = (DeadlockDetectingLockManager) TestingUtil.extractLockManager(cache(1));
+   }
+
+
+   @BeforeMethod
+   public void beforeMethod() {
+      t1 = new PerCacheExecutorThread(cache(0), 1);
+      t2 = new PerCacheExecutorThread(cache(1), 2);
+      replicationLatch = new CountDownLatch(1);
+      rpcManager0.setReplicationLatch(replicationLatch);
+      rpcManager1.setReplicationLatch(replicationLatch);
+      log.trace("_________________________ Here it begins");
+   }
+
+   @AfterMethod
+   public void afterMethod() {
+      t1.stopThread();
+      t2.stopThread();
+      ((DeadlockDetectingLockManager) TestingUtil.extractLockManager(cache(0))).resetStatistics();
+      ((DeadlockDetectingLockManager) TestingUtil.extractLockManager(cache(1))).resetStatistics();
+   }
+
+   public void testSymmetricDeadlock() {
+      super.testSymmetricDeadlock("k0", "k1");
+   }
+
+   public void testExpectedInnerStructure() {
+      LockManager lockManager = TestingUtil.extractComponent(cache(0), LockManager.class);
+      assert lockManager instanceof DeadlockDetectingLockManager;
+
+      InterceptorChain ic = TestingUtil.extractComponent(cache(0), InterceptorChain.class);
+      assert ic.containsInterceptorType(DeadlockDetectingInterceptor.class);
+   }
+
+   public void testSameKeyDeadlock() throws Exception {
+      t1.setKeyValue("key", "value1");
+      t2.setKeyValue("key", "value2");
+      assert PerCacheExecutorThread.OperationsResult.BEGGIN_TX_OK == t1.execute(PerCacheExecutorThread.Operations.BEGGIN_TX);
+      assert PerCacheExecutorThread.OperationsResult.BEGGIN_TX_OK == t2.execute(PerCacheExecutorThread.Operations.BEGGIN_TX);
+      System.out.println("After begin");
+
+      t1.execute(PerCacheExecutorThread.Operations.PUT_KEY_VALUE);
+      t2.execute(PerCacheExecutorThread.Operations.PUT_KEY_VALUE);
+      System.out.println("After put key value");
+
+      t1.clearResponse();
+      t2.clearResponse();
+
+      t1.executeNoResponse(PerCacheExecutorThread.Operations.COMMIT_TX);
+      t2.executeNoResponse(PerCacheExecutorThread.Operations.COMMIT_TX);
+
+      System.out.println("Now replication is triggered");
+      replicationLatch.countDown();
+
+
+      Object t1Commit = t1.waitForResponse();
+      Object t2Commit = t2.waitForResponse();
+      System.out.println("After commit: " + t1Commit + ", " + t2Commit);
+
+      assert xor(t1Commit instanceof Exception, t2Commit instanceof Exception) : "only one thread must be failing " + t1Commit + "," + t2Commit;
+      System.out.println("t2Commit = " + t2Commit);
+      System.out.println("t1Commit = " + t1Commit);
+
+      if (t1Commit instanceof Exception) {
+         System.out.println("t1 rolled back");
+         Object o = cache(0).get("key");
+         assert o != null;
+         assert o.equals("value2");
+      } else {
+         System.out.println("t2 rolled back");
+         Object o = cache(0).get("key");
+         assert o != null;
+         assert o.equals("value1");
+         o = cache(1).get("key");
+         assert o != null;
+         assert o.equals("value1");
+      }
+
+      assert ddLm1.getDetectedRemoteDeadlocks() + ddLm2.getDetectedRemoteDeadlocks() >= 1;
+
+      LockManager lm1 = TestingUtil.extractComponent(cache(0), LockManager.class);
+      assert !lm1.isLocked("key") : "It is locked by " + lm1.getOwner("key");
+      LockManager lm2 = TestingUtil.extractComponent(cache(1), LockManager.class);
+      assert !lm2.isLocked("key") : "It is locked by " + lm2.getOwner("key");
+      LockAssert.assertNoLocks(cache(0));
+   }
+
+   public void testDeadlockDetectedOneTx() throws Exception {
+      t1.setKeyValue("key", "value1");
+
+      LockManager lm2 = TestingUtil.extractComponent(cache(1), LockManager.class);
+      NonTxInvocationContext ctx = cache(1).getAdvancedCache().getInvocationContextContainer().createNonTxInvocationContext();
+      lm2.lockAndRecord("key", ctx);
+      assert lm2.isLocked("key");
+
+
+      assert PerCacheExecutorThread.OperationsResult.BEGGIN_TX_OK == t1.execute(PerCacheExecutorThread.Operations.BEGGIN_TX) : "but received " + t1.lastResponse();
+      t1.execute(PerCacheExecutorThread.Operations.PUT_KEY_VALUE);
+
+      t1.clearResponse();
+      t1.executeNoResponse(PerCacheExecutorThread.Operations.COMMIT_TX);
+
+      replicationLatch.countDown();
+      System.out.println("Now replication is triggered");
+
+      t1.waitForResponse();
+
+
+      Object t1CommitRsp = t1.lastResponse();
+
+      assert t1CommitRsp instanceof Exception : "expected exception, received " + t1.lastResponse();
+
+      LockManager lm1 = TestingUtil.extractComponent(cache(0), LockManager.class);
+      assert !lm1.isLocked("key") : "It is locked by " + lm1.getOwner("key");
+
+      lm2.unlock("key");
+      assert !lm2.isLocked("key");
+      assert !lm1.isLocked("key");
+   }
+
+   public void testLockReleasedWhileTryingToAcquire() throws Exception {
+      t1.setKeyValue("key", "value1");
+
+      LockManager lm2 = TestingUtil.extractComponent(cache(1), LockManager.class);
+      NonTxInvocationContext ctx = cache(1).getAdvancedCache().getInvocationContextContainer().createNonTxInvocationContext();
+      lm2.lockAndRecord("key", ctx);
+      assert lm2.isLocked("key");
+
+
+      assert PerCacheExecutorThread.OperationsResult.BEGGIN_TX_OK == t1.execute(PerCacheExecutorThread.Operations.BEGGIN_TX) : "but received " + t1.lastResponse();
+      t1.execute(PerCacheExecutorThread.Operations.PUT_KEY_VALUE);
+
+      t1.clearResponse();
+      t1.executeNoResponse(PerCacheExecutorThread.Operations.COMMIT_TX);
+
+      replicationLatch.countDown();
+
+      Thread.sleep(3000); //just to make sure the remote tx thread managed to spin around for some times.
+      lm2.unlock("key");
+
+      t1.waitForResponse();
+
+
+      Object t1CommitRsp = t1.lastResponse();
+
+      assert t1CommitRsp == PerCacheExecutorThread.OperationsResult.COMMIT_TX_OK : "expected true, received " + t1.lastResponse();
+
+      LockManager lm1 = TestingUtil.extractComponent(cache(0), LockManager.class);
+      assert !lm1.isLocked("key") : "It is locked by " + lm1.getOwner("key");
+
+      assert !lm2.isLocked("key");
+      assert !lm1.isLocked("key");
+   }
+
+}


Property changes on: branches/4.2.x/core/src/test/java/org/infinispan/tx/dld/DldLazyLockingReplicationTest.java
___________________________________________________________________
Name: svn:keywords
   + Id Revision
Name: svn:eol-style
   + LF

Copied: branches/4.2.x/core/src/test/java/org/infinispan/tx/dld/LocalDeadlockDetectionTest.java (from rev 2340, branches/4.2.x/core/src/test/java/org/infinispan/tx/LocalDeadlockDetectionTest.java)
===================================================================
--- branches/4.2.x/core/src/test/java/org/infinispan/tx/dld/LocalDeadlockDetectionTest.java	                        (rev 0)
+++ branches/4.2.x/core/src/test/java/org/infinispan/tx/dld/LocalDeadlockDetectionTest.java	2010-09-15 00:16:18 UTC (rev 2372)
@@ -0,0 +1,190 @@
+package org.infinispan.tx.dld;
+
+import org.infinispan.config.Configuration;
+import org.infinispan.manager.EmbeddedCacheManager;
+import org.infinispan.test.PerCacheExecutorThread;
+import org.infinispan.test.SingleCacheManagerTest;
+import org.infinispan.test.TestingUtil;
+import org.infinispan.test.fwk.TestCacheManagerFactory;
+import org.infinispan.util.concurrent.locks.DeadlockDetectedException;
+import org.infinispan.util.concurrent.locks.DeadlockDetectingLockManager;
+import static org.testng.Assert.assertEquals;
+
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import javax.transaction.RollbackException;
+
+/**
+ * Tests deadlock detection functionality for local caches.
+ *
+ * @author Mircea.Markus at jboss.com
+ */
+ at Test(groups = "functional", testName = "tx.LocalDeadlockDetectionTest")
+public class LocalDeadlockDetectionTest extends SingleCacheManagerTest {
+
+   private PerCacheExecutorThread t1;
+   private PerCacheExecutorThread t2;
+   private DeadlockDetectingLockManager lockManager;
+   private Object response1;
+   private Object response2;
+
+   protected EmbeddedCacheManager createCacheManager() throws Exception {
+      cacheManager = TestCacheManagerFactory.createLocalCacheManager();
+      Configuration configuration = getDefaultStandaloneConfig(true);
+      configuration.setEnableDeadlockDetection(true);
+      configuration.setUseLockStriping(false);
+      configuration.setExposeJmxStatistics(true);
+      cacheManager.defineConfiguration("test", configuration);
+      cache = cacheManager.getCache("test");
+      lockManager = (DeadlockDetectingLockManager) TestingUtil.extractLockManager(cache);
+      return cacheManager;
+   }
+
+   @BeforeMethod
+   public void startExecutors() {
+      t1 = new PerCacheExecutorThread(cache, 0);
+      t2 = new PerCacheExecutorThread(cache, 1);
+      lockManager.resetStatistics();
+   }
+
+
+   @AfterMethod
+   public void stopExecutors() {
+      t1.stopThread();
+      t2.stopThread();
+   }
+
+   public void testDldPutAndPut() {
+      testLocalVsLocalTxDeadlock(PerCacheExecutorThread.Operations.PUT_KEY_VALUE,
+                                 PerCacheExecutorThread.Operations.PUT_KEY_VALUE);
+      if (response1 instanceof Exception) {
+         assertEquals("value_1_t2", cache.get("k1"));
+         assertEquals("value_2_t2", cache.get("k2"));
+      } else {
+         assertEquals("value_1_t1", cache.get("k1"));
+         assertEquals("value_2_t1", cache.get("k2"));
+      }
+   }
+
+   public void testDldPutAndRemove() {
+      testLocalVsLocalTxDeadlock(PerCacheExecutorThread.Operations.PUT_KEY_VALUE,
+                                 PerCacheExecutorThread.Operations.REMOVE_KEY);
+      if (response1 instanceof Exception) {
+         assertEquals(cache.get("k1"), null);
+         assertEquals("value_2_t2", cache.get("k2"));
+      } else {
+         assertEquals("value_1_t1", cache.get("k1"));
+         assertEquals(null, cache.get("k2"));
+      }
+   }
+
+   public void testDldRemoveAndPut() {
+      testLocalVsLocalTxDeadlock(PerCacheExecutorThread.Operations.REMOVE_KEY,
+                                 PerCacheExecutorThread.Operations.PUT_KEY_VALUE);
+      if (response1 instanceof Exception) {
+         System.out.println("t1 failure");
+         assertEquals(cache.get("k1"), "value_1_t2");
+         assertEquals(cache.get("k2"), null);
+      } else {
+         System.out.println("t2 failure");
+         assertEquals(cache.get("k1"), null);
+         assertEquals(cache.get("k2"), "value_2_t1");
+      }
+   }
+
+   public void testDldRemoveAndRemove() {
+      testLocalVsLocalTxDeadlock(PerCacheExecutorThread.Operations.REMOVE_KEY,
+                                 PerCacheExecutorThread.Operations.REMOVE_KEY);
+      if (response1 instanceof Exception) {
+         System.out.println("t1 failure");
+         assertEquals(cache.get("k1"), null);
+         assertEquals(cache.get("k2"), null);
+      } else {
+         System.out.println("t2 failure");
+         assertEquals(cache.get("k1"), null);
+         assertEquals(cache.get("k2"), null);
+      }
+   }
+
+   public void testDldPutAndReplace() {
+
+      cache.put("k1", "initial_1");
+      cache.put("k2", "initial_2");
+
+      testLocalVsLocalTxDeadlock(PerCacheExecutorThread.Operations.PUT_KEY_VALUE,
+                                 PerCacheExecutorThread.Operations.REPLACE_KEY_VALUE);
+      if (response1 instanceof Exception) {
+         System.out.println("t1 failure");
+         assertEquals(cache.get("k1"), "value_1_t2");
+         assertEquals(cache.get("k2"), "value_2_t2");
+      } else {
+         System.out.println("t2 failure");
+         assertEquals(cache.get("k1"), "value_1_t1");
+         assertEquals(cache.get("k2"), "value_2_t1");
+      }
+   }
+
+   public void testDldReplaceAndPut() {
+
+      cache.put("k1", "initial_1");
+      cache.put("k2", "initial_2");
+
+      testLocalVsLocalTxDeadlock(PerCacheExecutorThread.Operations.REPLACE_KEY_VALUE,
+                                 PerCacheExecutorThread.Operations.PUT_KEY_VALUE);
+      if (response1 instanceof Exception) {
+         System.out.println("t1 failure");
+         assertEquals(cache.get("k1"), "value_1_t2");
+         assertEquals(cache.get("k2"), "value_2_t2");
+      } else {
+         System.out.println("t2 failure");
+         assertEquals(cache.get("k1"), "value_1_t1");
+         assertEquals(cache.get("k2"), "value_2_t1");
+      }
+   }
+
+
+   private void testLocalVsLocalTxDeadlock(PerCacheExecutorThread.Operations firstOperation, PerCacheExecutorThread.Operations secondOperation) {
+
+      assert PerCacheExecutorThread.OperationsResult.BEGGIN_TX_OK == t1.execute(PerCacheExecutorThread.Operations.BEGGIN_TX);
+      assert PerCacheExecutorThread.OperationsResult.BEGGIN_TX_OK == t2.execute(PerCacheExecutorThread.Operations.BEGGIN_TX);
+      System.out.println("After begin");
+
+      t1.setKeyValue("k1", "value_1_t1");
+      t2.setKeyValue("k2", "value_2_t2");
+
+      assertEquals(t1.execute(firstOperation), firstOperation.getCorrespondingOkResult());
+      assertEquals(t2.execute(firstOperation), firstOperation.getCorrespondingOkResult());
+
+      assert lockManager.isLocked("k1");
+      assert lockManager.isLocked("k2");
+
+
+      t1.setKeyValue("k2", "value_2_t1");
+      t2.setKeyValue("k1", "value_1_t2");
+      t1.executeNoResponse(secondOperation);
+      t2.executeNoResponse(secondOperation);
+
+      response1 = t1.waitForResponse();
+      response2 = t2.waitForResponse();
+
+      assert xor(response1 instanceof DeadlockDetectedException, response2 instanceof DeadlockDetectedException) : "expected one and only one exception: " + response1 + ", " + response2;
+      assert xor(response1 == secondOperation.getCorrespondingOkResult(), response2 == secondOperation.getCorrespondingOkResult()) : "expected one and only one exception: " + response1 + ", " + response2;
+
+      assert lockManager.isLocked("k1");
+      assert lockManager.isLocked("k2");
+      assert lockManager.getOwner("k1") == lockManager.getOwner("k2");
+
+      if (response1 instanceof Exception) {
+         assert PerCacheExecutorThread.OperationsResult.COMMIT_TX_OK == t2.execute(PerCacheExecutorThread.Operations.COMMIT_TX);
+         assert t1.execute(PerCacheExecutorThread.Operations.COMMIT_TX) instanceof RollbackException;
+      } else {
+         assert PerCacheExecutorThread.OperationsResult.COMMIT_TX_OK == t1.execute(PerCacheExecutorThread.Operations.COMMIT_TX);
+         assert t2.execute(PerCacheExecutorThread.Operations.COMMIT_TX) instanceof RollbackException;
+      }
+      assert lockManager.getNumberOfLocksHeld() == 0;
+      assertEquals(lockManager.getDetectedLocalDeadlocks(), 1);
+   }
+
+}


Property changes on: branches/4.2.x/core/src/test/java/org/infinispan/tx/dld/LocalDeadlockDetectionTest.java
___________________________________________________________________
Name: svn:keywords
   + Id Revision
Name: svn:eol-style
   + LF

Modified: branches/4.2.x/core/src/test/java/org/infinispan/util/DeadlockDetectingLockManagerTest.java
===================================================================
--- branches/4.2.x/core/src/test/java/org/infinispan/util/DeadlockDetectingLockManagerTest.java	2010-09-14 17:11:35 UTC (rev 2371)
+++ branches/4.2.x/core/src/test/java/org/infinispan/util/DeadlockDetectingLockManagerTest.java	2010-09-15 00:16:18 UTC (rev 2372)
@@ -88,7 +88,7 @@
       Lock mockLock = createNiceMock(Lock.class);
       expect(lc.acquireLock("k", SPIN_DURATION, TimeUnit.MILLISECONDS)).andReturn(mockLock);
       lockOwner.setRemote(false);
-      lockOwner.setLockLocalLockIntention("k");
+      lockOwner.setLockIntention("k");
       lockManager.setOwner(lockOwner);
       lockManager.setOwnsLock(true);
       replay(lc);

Modified: branches/4.2.x/pom.xml
===================================================================
--- branches/4.2.x/pom.xml	2010-09-14 17:11:35 UTC (rev 2371)
+++ branches/4.2.x/pom.xml	2010-09-15 00:16:18 UTC (rev 2372)
@@ -1,7 +1,5 @@
-<?xml version="1.0"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
 
    <parent>
@@ -45,6 +43,7 @@
       <module>demos/lucene-directory-demo</module>
       <module>demos/gridfs-webdav</module>
       <module>tools</module>
+      <module>continuous-query</module>
    </modules>
 
    <profiles>
@@ -298,4 +297,4 @@
       </profile>
 
    </profiles>
-</project>
+</project>
\ No newline at end of file



More information about the infinispan-commits mailing list