[infinispan-commits] Infinispan SVN: r2386 - in trunk: cachestore/remote/src/test/java/org/infinispan/loaders/remote and 40 other directories.

infinispan-commits at lists.jboss.org infinispan-commits at lists.jboss.org
Wed Sep 15 15:09:41 EDT 2010


Author: mircea.markus
Date: 2010-09-15 15:09:38 -0400 (Wed, 15 Sep 2010)
New Revision: 2386

Added:
   trunk/core/src/main/java/org/infinispan/transaction/xa/DldGlobalTransaction.java
   trunk/core/src/test/java/org/infinispan/lock/EagerLockingSingleLockTest.java
   trunk/core/src/test/java/org/infinispan/tx/dld/
   trunk/core/src/test/java/org/infinispan/tx/dld/AsyncDeadlockDetectionTest.java
   trunk/core/src/test/java/org/infinispan/tx/dld/BaseDldEagerLockingTest.java
   trunk/core/src/test/java/org/infinispan/tx/dld/BaseDldLazyLockingTest.java
   trunk/core/src/test/java/org/infinispan/tx/dld/BaseDldTest.java
   trunk/core/src/test/java/org/infinispan/tx/dld/ControlledRpcManager.java
   trunk/core/src/test/java/org/infinispan/tx/dld/DldEagerLockingDistributedTest.java
   trunk/core/src/test/java/org/infinispan/tx/dld/DldEagerLockingReplicationTest.java
   trunk/core/src/test/java/org/infinispan/tx/dld/DldLazyLockingDistributionTest.java
   trunk/core/src/test/java/org/infinispan/tx/dld/DldLazyLockingReplicationTest.java
   trunk/core/src/test/java/org/infinispan/tx/dld/LocalDeadlockDetectionTest.java
   trunk/core/src/test/java/org/infinispan/tx/exception/
   trunk/core/src/test/java/org/infinispan/tx/exception/CustomInterceptorException.java
   trunk/core/src/test/java/org/infinispan/tx/exception/ExplicitLockingAndTimeoutTest.java
   trunk/core/src/test/java/org/infinispan/tx/exception/ReplicationExceptionTest.java
   trunk/core/src/test/java/org/infinispan/tx/exception/TxAndInvalidationTimeoutTest.java
   trunk/core/src/test/java/org/infinispan/tx/exception/TxAndRemoteTimeoutExceptionTest.java
   trunk/core/src/test/java/org/infinispan/tx/exception/TxAndTimeoutExceptionTest.java
   trunk/core/src/test/java/org/infinispan/tx/timeout/
Removed:
   trunk/core/src/main/java/org/infinispan/factories/context/
   trunk/core/src/main/java/org/infinispan/transaction/xa/DeadlockDetectingGlobalTransaction.java
   trunk/core/src/test/java/org/infinispan/distribution/DeadlockDetectionDistributionTest.java
   trunk/core/src/test/java/org/infinispan/lock/EagerLockingDisabledTest.java
   trunk/core/src/test/java/org/infinispan/tx/AsyncDeadlockDetectionTest.java
   trunk/core/src/test/java/org/infinispan/tx/LocalDeadlockDetectionTest.java
   trunk/core/src/test/java/org/infinispan/tx/ReplDeadlockDetectionTest.java
   trunk/core/src/test/java/org/infinispan/tx/dld/AsyncDeadlockDetectionTest.java
   trunk/core/src/test/java/org/infinispan/tx/dld/BaseDldEagerLockingTest.java
   trunk/core/src/test/java/org/infinispan/tx/dld/BaseDldLazyLockingTest.java
   trunk/core/src/test/java/org/infinispan/tx/dld/BaseDldTest.java
   trunk/core/src/test/java/org/infinispan/tx/dld/ControlledRpcManager.java
   trunk/core/src/test/java/org/infinispan/tx/dld/DldEagerLockingDistributedTest.java
   trunk/core/src/test/java/org/infinispan/tx/dld/DldEagerLockingReplicationTest.java
   trunk/core/src/test/java/org/infinispan/tx/dld/DldLazyLockingDistributionTest.java
   trunk/core/src/test/java/org/infinispan/tx/dld/DldLazyLockingReplicationTest.java
   trunk/core/src/test/java/org/infinispan/tx/dld/LocalDeadlockDetectionTest.java
   trunk/core/src/test/java/org/infinispan/tx/exception/CustomInterceptorException.java
   trunk/core/src/test/java/org/infinispan/tx/exception/ExplicitLockingAndTimeoutTest.java
   trunk/core/src/test/java/org/infinispan/tx/exception/ReplicationExceptionTest.java
   trunk/core/src/test/java/org/infinispan/tx/exception/TxAndInvalidationTimeoutTest.java
   trunk/core/src/test/java/org/infinispan/tx/exception/TxAndRemoteTimeoutExceptionTest.java
   trunk/core/src/test/java/org/infinispan/tx/exception/TxAndTimeoutExceptionTest.java
   trunk/query/src/main/java/org/infinispan/query/config/
   trunk/server/websocket/src/main/java/org/infinispan/websocket/
Modified:
   trunk/cachestore/jdbc/src/main/java/org/infinispan/loaders/jdbc/stringbased/JdbcStringBasedCacheStore.java
   trunk/cachestore/remote/src/test/java/org/infinispan/loaders/remote/RemoteCacheStoreFunctionalTest.java
   trunk/cachestore/remote/src/test/java/org/infinispan/loaders/remote/RemoteCacheStoreTest.java
   trunk/core/
   trunk/core/src/main/java/org/infinispan/CacheDelegate.java
   trunk/core/src/main/java/org/infinispan/CacheException.java
   trunk/core/src/main/java/org/infinispan/affinity/KeyAffinityServiceImpl.java
   trunk/core/src/main/java/org/infinispan/commands/CommandsFactory.java
   trunk/core/src/main/java/org/infinispan/commands/CommandsFactoryImpl.java
   trunk/core/src/main/java/org/infinispan/commands/RemoteCommandsFactory.java
   trunk/core/src/main/java/org/infinispan/commands/control/LockControlCommand.java
   trunk/core/src/main/java/org/infinispan/commands/control/RehashControlCommand.java
   trunk/core/src/main/java/org/infinispan/commands/tx/AbstractTransactionBoundaryCommand.java
   trunk/core/src/main/java/org/infinispan/commands/tx/PrepareCommand.java
   trunk/core/src/main/java/org/infinispan/commands/tx/TransactionBoundaryCommand.java
   trunk/core/src/main/java/org/infinispan/config/Configuration.java
   trunk/core/src/main/java/org/infinispan/config/ConfigurationValidatingVisitor.java
   trunk/core/src/main/java/org/infinispan/context/InvocationContext.java
   trunk/core/src/main/java/org/infinispan/context/impl/AbstractInvocationContext.java
   trunk/core/src/main/java/org/infinispan/context/impl/AbstractTxInvocationContext.java
   trunk/core/src/main/java/org/infinispan/context/impl/LocalTxInvocationContext.java
   trunk/core/src/main/java/org/infinispan/context/impl/NonTxInvocationContext.java
   trunk/core/src/main/java/org/infinispan/context/impl/RemoteTxInvocationContext.java
   trunk/core/src/main/java/org/infinispan/context/impl/TxInvocationContext.java
   trunk/core/src/main/java/org/infinispan/distribution/DistributionManager.java
   trunk/core/src/main/java/org/infinispan/distribution/DistributionManagerImpl.java
   trunk/core/src/main/java/org/infinispan/interceptors/CallInterceptor.java
   trunk/core/src/main/java/org/infinispan/interceptors/DeadlockDetectingInterceptor.java
   trunk/core/src/main/java/org/infinispan/interceptors/DistributionInterceptor.java
   trunk/core/src/main/java/org/infinispan/interceptors/ImplicitEagerLockingInterceptor.java
   trunk/core/src/main/java/org/infinispan/interceptors/InvalidationInterceptor.java
   trunk/core/src/main/java/org/infinispan/interceptors/InvocationContextInterceptor.java
   trunk/core/src/main/java/org/infinispan/interceptors/LockingInterceptor.java
   trunk/core/src/main/java/org/infinispan/interceptors/TxInterceptor.java
   trunk/core/src/main/java/org/infinispan/interceptors/base/BaseRpcInterceptor.java
   trunk/core/src/main/java/org/infinispan/marshall/Ids.java
   trunk/core/src/main/java/org/infinispan/marshall/jboss/ConstantObjectTable.java
   trunk/core/src/main/java/org/infinispan/remoting/InboundInvocationHandlerImpl.java
   trunk/core/src/main/java/org/infinispan/statetransfer/StateTransferManagerImpl.java
   trunk/core/src/main/java/org/infinispan/transaction/xa/GlobalTransaction.java
   trunk/core/src/main/java/org/infinispan/transaction/xa/GlobalTransactionFactory.java
   trunk/core/src/main/java/org/infinispan/transaction/xa/RemoteTransaction.java
   trunk/core/src/main/java/org/infinispan/transaction/xa/TransactionTable.java
   trunk/core/src/main/java/org/infinispan/transaction/xa/TransactionXaAdapter.java
   trunk/core/src/main/java/org/infinispan/util/concurrent/TimeoutException.java
   trunk/core/src/main/java/org/infinispan/util/concurrent/locks/DeadlockDetectedException.java
   trunk/core/src/main/java/org/infinispan/util/concurrent/locks/DeadlockDetectingLockManager.java
   trunk/core/src/main/resources/config-samples/all.xml
   trunk/core/src/test/java/org/infinispan/api/mvcc/LockTestBase.java
   trunk/core/src/test/java/org/infinispan/config/parsing/XmlFileParsingTest.java
   trunk/core/src/test/java/org/infinispan/loaders/dummy/DummyInMemoryCacheStore.java
   trunk/core/src/test/java/org/infinispan/notifications/cachelistener/CacheNotifierTest.java
   trunk/core/src/test/java/org/infinispan/statetransfer/StateTransferReplicationQueueTest.java
   trunk/core/src/test/java/org/infinispan/test/AbstractInfinispanTest.java
   trunk/core/src/test/java/org/infinispan/test/MultipleCacheManagersTest.java
   trunk/core/src/test/java/org/infinispan/test/PerCacheExecutorThread.java
   trunk/core/src/test/java/org/infinispan/test/TestingUtil.java
   trunk/core/src/test/java/org/infinispan/test/fwk/TestCacheManagerFactory.java
   trunk/core/src/test/java/org/infinispan/util/DeadlockDetectingLockManagerTest.java
   trunk/core/src/test/resources/configs/named-cache-test.xml
   trunk/core/src/test/resources/log4j.xml
   trunk/lucene-directory/src/main/java/org/infinispan/lucene/readlocks/DistributedSegmentReadLocker.java
   trunk/tree/
Log:
r2274 through r2385 from 4.2.x to trunk

Modified: trunk/cachestore/jdbc/src/main/java/org/infinispan/loaders/jdbc/stringbased/JdbcStringBasedCacheStore.java
===================================================================
--- trunk/cachestore/jdbc/src/main/java/org/infinispan/loaders/jdbc/stringbased/JdbcStringBasedCacheStore.java	2010-09-15 16:19:59 UTC (rev 2385)
+++ trunk/cachestore/jdbc/src/main/java/org/infinispan/loaders/jdbc/stringbased/JdbcStringBasedCacheStore.java	2010-09-15 19:09:38 UTC (rev 2386)
@@ -195,16 +195,16 @@
          log.trace("Running sql '" + sql + "' on " + ed + ". Key string is '" + lockingKey + "'");
       Connection connection = null;
       PreparedStatement ps = null;
+      ByteBuffer byteBuffer = JdbcUtil.marshall(getMarshaller(), ed.toInternalCacheValue());
       try {
          connection = connectionFactory.getConnection();
          ps = connection.prepareStatement(sql);
-         ByteBuffer byteBuffer = JdbcUtil.marshall(getMarshaller(), ed.toInternalCacheValue());
          ps.setBinaryStream(1, byteBuffer.getStream(), byteBuffer.getLength());
          ps.setLong(2, ed.getExpiryTime());
          ps.setString(3, lockingKey);
          ps.executeUpdate();
       } catch (SQLException ex) {
-         logAndThrow(ex, "Error while storing string keys to database");
+         logAndThrow(ex, "Error while storing string key to database; key: '"+lockingKey+"', buffer size of value: " + byteBuffer.getLength() + " bytes");
       } finally {
          JdbcUtil.safeClose(ps);
          connectionFactory.releaseConnection(connection);

Modified: trunk/cachestore/remote/src/test/java/org/infinispan/loaders/remote/RemoteCacheStoreFunctionalTest.java
===================================================================
--- trunk/cachestore/remote/src/test/java/org/infinispan/loaders/remote/RemoteCacheStoreFunctionalTest.java	2010-09-15 16:19:59 UTC (rev 2385)
+++ trunk/cachestore/remote/src/test/java/org/infinispan/loaders/remote/RemoteCacheStoreFunctionalTest.java	2010-09-15 19:09:38 UTC (rev 2386)
@@ -6,7 +6,10 @@
 import org.infinispan.manager.CacheContainer;
 import org.infinispan.manager.EmbeddedCacheManager;
 import org.infinispan.server.hotrod.HotRodServer;
+import org.infinispan.test.TestingUtil;
 import org.infinispan.test.fwk.TestCacheManagerFactory;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.AfterMethod;
 import org.testng.annotations.AfterTest;
 import org.testng.annotations.Test;
 
@@ -35,10 +38,10 @@
       return remoteCacheStoreConfig;
    }
 
-   @AfterTest
+   @AfterMethod(alwaysRun = true)
    public void tearDown() {
       hrServer.stop();
-      localCacheManager.stop();
+      TestingUtil.killCacheManagers(localCacheManager);
    }
 
    @Override

Modified: trunk/cachestore/remote/src/test/java/org/infinispan/loaders/remote/RemoteCacheStoreTest.java
===================================================================
--- trunk/cachestore/remote/src/test/java/org/infinispan/loaders/remote/RemoteCacheStoreTest.java	2010-09-15 16:19:59 UTC (rev 2385)
+++ trunk/cachestore/remote/src/test/java/org/infinispan/loaders/remote/RemoteCacheStoreTest.java	2010-09-15 19:09:38 UTC (rev 2386)
@@ -9,6 +9,7 @@
 import org.infinispan.manager.EmbeddedCacheManager;
 import org.infinispan.server.hotrod.HotRodServer;
 import org.infinispan.test.fwk.TestCacheManagerFactory;
+import org.testng.annotations.AfterMethod;
 import org.testng.annotations.AfterTest;
 import org.testng.annotations.Test;
 
@@ -45,7 +46,7 @@
       return remoteCacheStore;
    }
 
-   @AfterTest(alwaysRun = true)
+   @AfterMethod(alwaysRun = true)
    public void tearDown() {
       hrServer.stop();
       localCacheManager.stop();
@@ -77,3 +78,5 @@
    public void testLoadKeys() throws CacheLoaderException {
    }
 }
+
+


Property changes on: trunk/core
___________________________________________________________________
Name: svn:ignore
   - target
.settings
eclipse-output
test-output
output
.classpath
.project
temp-testng-customsuite.xml
Infinispan-FileCacheStore
*.iml
*.log

   + target
.settings
eclipse-output
test-output
output
.classpath
.project
temp-testng-customsuite.xml
Infinispan-FileCacheStore
*.iml
*.log
PutObjectStoreDirHere


Modified: trunk/core/src/main/java/org/infinispan/CacheDelegate.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/CacheDelegate.java	2010-09-15 16:19:59 UTC (rev 2385)
+++ trunk/core/src/main/java/org/infinispan/CacheDelegate.java	2010-09-15 19:09:38 UTC (rev 2386)
@@ -287,8 +287,6 @@
 
    public void lock(K key) {
       assertKeyNotNull(key);
-      //this will be removed with https://jira.jboss.org/browse/ISPN-598 
-      ConfigurationValidatingVisitor.checkEagerLockingAndDld(config, true);
       lock(Collections.singletonList(key));
    }
 

Modified: trunk/core/src/main/java/org/infinispan/CacheException.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/CacheException.java	2010-09-15 16:19:59 UTC (rev 2385)
+++ trunk/core/src/main/java/org/infinispan/CacheException.java	2010-09-15 19:09:38 UTC (rev 2386)
@@ -26,9 +26,13 @@
  * <p/>
  * Specific subclasses such as {@link org.infinispan.util.concurrent.TimeoutException} and {@link
  * org.infinispan.config.ConfigurationException} have more specific uses.
+ * <p/>
+ * Transactions: if a CacheException (including any subclasses) is thrown for an operation on a JTA transaction, then
+ * the transaction is marked for rollback. 
  *
  * @author <a href="mailto:bela at jboss.org">Bela Ban</a>
  * @author <a href="mailto:manik at jboss.org">Manik Surtani</a>
+ * @author Mircea.Markus at jboss.com
  * @since 4.0
  */
 public class CacheException extends RuntimeException {

Modified: trunk/core/src/main/java/org/infinispan/affinity/KeyAffinityServiceImpl.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/affinity/KeyAffinityServiceImpl.java	2010-09-15 16:19:59 UTC (rev 2385)
+++ trunk/core/src/main/java/org/infinispan/affinity/KeyAffinityServiceImpl.java	2010-09-15 19:09:38 UTC (rev 2386)
@@ -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: trunk/core/src/main/java/org/infinispan/commands/CommandsFactory.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/commands/CommandsFactory.java	2010-09-15 16:19:59 UTC (rev 2385)
+++ trunk/core/src/main/java/org/infinispan/commands/CommandsFactory.java	2010-09-15 19:09:38 UTC (rev 2386)
@@ -196,8 +196,9 @@
     * <p/>
     *
     * @param command command to initialize.  Cannot be null.
+    * @param isRemote
     */
-   void initializeReplicableCommand(ReplicableCommand command);
+   void initializeReplicableCommand(ReplicableCommand command, boolean isRemote);
 
    /**
     * Builds an RpcCommand "envelope" containing multiple ReplicableCommands
@@ -283,14 +284,6 @@
    /**
     * Builds a RehashControlCommand for coordinating a rehash event. This particular variation of RehashControlCommand
     * coordinates rehashing of nodes when a node join or leaves
-    * 
-    * @param subtype
-    * @param sender
-    * @param state
-    * @param oldCH
-    * @param leaversHandled
-    * @param newCH
-    * @return
     */
    RehashControlCommand buildRehashControlCommand(RehashControlCommand.Type subtype,
             Address sender, Map<Object, InternalCacheValue> state, ConsistentHash oldCH,

Modified: trunk/core/src/main/java/org/infinispan/commands/CommandsFactoryImpl.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/commands/CommandsFactoryImpl.java	2010-09-15 16:19:59 UTC (rev 2385)
+++ trunk/core/src/main/java/org/infinispan/commands/CommandsFactoryImpl.java	2010-09-15 19:09:38 UTC (rev 2386)
@@ -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
@@ -213,7 +216,10 @@
       return new ClusteredGetCommand(key, cacheName);
    }
 
-   public void initializeReplicableCommand(ReplicableCommand c) {
+   /**
+    * @param isRemote true if the command is deserialized and is executed remote.
+    */
+   public void initializeReplicableCommand(ReplicableCommand c, boolean isRemote) {
       if (c == null) return;
       switch (c.getCommandId()) {
          case PutKeyValueCommand.COMMAND_ID:
@@ -230,14 +236,14 @@
             rc.init(interceptorChain, icc);
             if (rc.getCommands() != null)
                for (ReplicableCommand nested : rc.getCommands()) {
-                  initializeReplicableCommand(nested);
+                  initializeReplicableCommand(nested, false);
                }
             break;
          case SingleRpcCommand.COMMAND_ID:
             SingleRpcCommand src = (SingleRpcCommand) c;
             src.init(interceptorChain, icc);
             if (src.getCommand() != null)
-               initializeReplicableCommand(src.getCommand());
+               initializeReplicableCommand(src.getCommand(), false);
 
             break;
          case InvalidateCommand.COMMAND_ID:
@@ -253,15 +259,24 @@
             pc.init(interceptorChain, icc, txTable);
             pc.initialize(notifier);
             if (pc.getModifications() != null)
-               for (ReplicableCommand nested : pc.getModifications()) initializeReplicableCommand(nested);
+               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;
             commitCommand.init(interceptorChain, icc, txTable);
+            commitCommand.markTransactionAsRemote(isRemote);
             break;
          case RollbackCommand.COMMAND_ID:
             RollbackCommand rollbackCommand = (RollbackCommand) c;
             rollbackCommand.init(interceptorChain, icc, txTable);
+            rollbackCommand.markTransactionAsRemote(isRemote);
             break;
          case ClearCommand.COMMAND_ID:
             ClearCommand cc = (ClearCommand) c;
@@ -274,6 +289,22 @@
          case LockControlCommand.COMMAND_ID:
             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: trunk/core/src/main/java/org/infinispan/commands/RemoteCommandsFactory.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/commands/RemoteCommandsFactory.java	2010-09-15 16:19:59 UTC (rev 2385)
+++ trunk/core/src/main/java/org/infinispan/commands/RemoteCommandsFactory.java	2010-09-15 19:09:38 UTC (rev 2386)
@@ -29,10 +29,11 @@
  * cache-specific components into it.
  * <p />
  * Usually a second step to unmarshalling a command from a byte stream (after
- * creating an un-initialized version using this factory) is to pass the command though {@link org.infinispan.commands.CommandsFactory#initializeReplicableCommand(ReplicableCommand)}.
+ * creating an un-initialized version using this factory) is to pass the command though {@link CommandsFactory#initializeReplicableCommand(ReplicableCommand,boolean)}.
  *
- * @see org.infinispan.commands.CommandsFactory#initializeReplicableCommand(ReplicableCommand)
+ * @see CommandsFactory#initializeReplicableCommand(ReplicableCommand,boolean)
  * @author Manik Surtani
+ * @author Mircea.Markus at jboss.com
  * @since 4.0
  */
 @Scope(Scopes.GLOBAL)
@@ -48,7 +49,7 @@
     * Creates an un-initialized command.  Un-initialized in the sense that parameters will be set, but any components
     * specific to the cache in question will not be set.
     * <p/>
-    * You would typically set these parameters using {@link org.infinispan.commands.CommandsFactory#initializeReplicableCommand(ReplicableCommand)}
+    * You would typically set these parameters using {@link CommandsFactory#initializeReplicableCommand(ReplicableCommand,boolean)}
     * <p/>
     *
     * @param id         id of the command

Modified: trunk/core/src/main/java/org/infinispan/commands/control/LockControlCommand.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/commands/control/LockControlCommand.java	2010-09-15 16:19:59 UTC (rev 2385)
+++ trunk/core/src/main/java/org/infinispan/commands/control/LockControlCommand.java	2010-09-15 19:09:38 UTC (rev 2386)
@@ -32,6 +32,8 @@
 import org.infinispan.transaction.xa.GlobalTransaction;
 import org.infinispan.transaction.xa.RemoteTransaction;
 import org.infinispan.util.Util;
+import org.infinispan.util.logging.Log;
+import org.infinispan.util.logging.LogFactory;
 
 import java.util.Collection;
 import java.util.Collections;
@@ -45,14 +47,19 @@
  * For more details refer to: https://jira.jboss.org/jira/browse/ISPN-70 https://jira.jboss.org/jira/browse/ISPN-48
  *
  * @author Vladimir Blagojevic (<a href="mailto:vblagoje at redhat.com">vblagoje at redhat.com</a>)
+ * @author Mircea.Markus at jboss.com
  * @since 4.0
  */
 @Marshallable(externalizer = ReplicableCommandExternalizer.class, id = Ids.LOCK_CONTROL_COMMAND)
 public class LockControlCommand extends AbstractTransactionBoundaryCommand {
+
+   private static Log log = LogFactory.getLog(LockControlCommand.class);
+
    public static final int COMMAND_ID = 3;
    private Set<Object> keys;
    private Object singleKey;
    private boolean implicit = false;
+   private boolean unlock = false;
 
    public LockControlCommand() {
    }
@@ -143,8 +150,13 @@
       RemoteTxInvocationContext ctxt = icc.createRemoteTxInvocationContext();
       RemoteTransaction transaction = txTable.getRemoteTransaction(globalTx);
 
-      boolean remoteTxinitiated = transaction != null;
-      if (!remoteTxinitiated) {
+      if (transaction == null) {
+         if (unlock) {
+            if (log.isTraceEnabled()) {
+               log.trace("Unlock for in-existing transaction: " + globalTx + ". Not doing anything.");
+            }
+            return null;
+         }
          //create a remote tx without any modifications (we do not know modifications ahead of time)
          transaction = txTable.createRemoteTransaction(globalTx);
       }
@@ -159,11 +171,11 @@
    public Object[] getParameters() {
       if (keys == null || keys.isEmpty()) {
          if (singleKey == null)
-            return new Object[]{globalTx, cacheName, (byte) 1};
+            return new Object[]{globalTx, cacheName, unlock, (byte) 1};
          else
-            return new Object[]{globalTx, cacheName, (byte) 2, singleKey};
+            return new Object[]{globalTx, cacheName, unlock, (byte) 2, singleKey};
       }
-      return new Object[]{globalTx, cacheName, (byte) 3, keys};
+      return new Object[]{globalTx, cacheName, unlock, (byte) 3, keys};
    }
 
    @SuppressWarnings("unchecked")
@@ -172,22 +184,31 @@
          throw new IllegalStateException("Unusupported command id:" + commandId);
       globalTx = (GlobalTransaction) args[0];
       cacheName = (String) args[1];
+      unlock = (Boolean)args[2];
 
       keys = null;
       singleKey = null;
-      byte mode = (Byte) args[2];
+      byte mode = (Byte) args[3];
       switch (mode) {
          case 1:
             break; // do nothing
          case 2:
-            singleKey = args[3];
+            singleKey = args[4];
             break;
          case 3:
-            keys = (Set<Object>) args[3];
+            keys = (Set<Object>) args[4];
             break;
       }
    }
 
+   public boolean isUnlock() {
+      return unlock;
+   }
+
+   public void setUnlock(boolean unlock) {
+      this.unlock = unlock;
+   }
+
    public boolean equals(Object o) {
       if (this == o)
          return true;
@@ -197,7 +218,7 @@
       LockControlCommand that = (LockControlCommand) o;
       if (!super.equals(that))
          return false;
-      return keys.equals(that.keys) && Util.safeEquals(singleKey, that.singleKey);
+      return keys.equals(that.keys) && Util.safeEquals(singleKey, that.singleKey) && (unlock == that.unlock);
    }
 
    public int hashCode() {
@@ -213,6 +234,7 @@
             ", cacheName='" + cacheName +
             ", implicit='" + implicit +
             ", keys=" + keys +
+            ", unlock=" + unlock +
             ", singleKey=" + singleKey + '}';
    }
 }

Modified: trunk/core/src/main/java/org/infinispan/commands/control/RehashControlCommand.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/commands/control/RehashControlCommand.java	2010-09-15 16:19:59 UTC (rev 2385)
+++ trunk/core/src/main/java/org/infinispan/commands/control/RehashControlCommand.java	2010-09-15 19:09:38 UTC (rev 2386)
@@ -105,7 +105,7 @@
       // we need to "fix" these command lists - essentially propagate the init.  TODO think of a nicer way to do this!!
       for (List<? extends ReplicableCommand> commandList : Arrays.asList(txLogCommands, pendingPrepares)) {
          if (commandList != null) {
-            for (ReplicableCommand cmd : commandList) commandsFactory.initializeReplicableCommand(cmd);
+            for (ReplicableCommand cmd : commandList) commandsFactory.initializeReplicableCommand(cmd, false);
          }
       }
    }

Modified: trunk/core/src/main/java/org/infinispan/commands/tx/AbstractTransactionBoundaryCommand.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/commands/tx/AbstractTransactionBoundaryCommand.java	2010-09-15 16:19:59 UTC (rev 2385)
+++ trunk/core/src/main/java/org/infinispan/commands/tx/AbstractTransactionBoundaryCommand.java	2010-09-15 19:09:38 UTC (rev 2386)
@@ -68,8 +68,13 @@
       return globalTx;
    }
 
+   public void markTransactionAsRemote(boolean isRemote) {
+      globalTx.setRemote(isRemote);
+   }
+
    public Object perform(InvocationContext ctx) throws Throwable {
       if (ctx != null) throw new IllegalStateException("Expected null context!");
+      markGtxAsRemote();
       RemoteTransaction transaction = txTable.getRemoteTransaction(globalTx);
       if (transaction == null) {
          if (trace) log.info("Not found RemoteTransaction for tx id: " + globalTx);
@@ -112,9 +117,12 @@
 
    @Override
    public String toString() {
-      return getClass().getSimpleName() + "{" +
-            "gtx=" + globalTx +
+      return ", gtx=" + globalTx +
             ", cacheName='" + cacheName + '\'' +
             '}';
    }
+
+   private void markGtxAsRemote() {
+      globalTx.setRemote(true);
+   }
 }

Modified: trunk/core/src/main/java/org/infinispan/commands/tx/PrepareCommand.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/commands/tx/PrepareCommand.java	2010-09-15 16:19:59 UTC (rev 2385)
+++ trunk/core/src/main/java/org/infinispan/commands/tx/PrepareCommand.java	2010-09-15 19:09:38 UTC (rev 2386)
@@ -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: trunk/core/src/main/java/org/infinispan/commands/tx/TransactionBoundaryCommand.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/commands/tx/TransactionBoundaryCommand.java	2010-09-15 16:19:59 UTC (rev 2385)
+++ trunk/core/src/main/java/org/infinispan/commands/tx/TransactionBoundaryCommand.java	2010-09-15 19:09:38 UTC (rev 2386)
@@ -30,9 +30,12 @@
  * {@link org.infinispan.transaction.xa.GlobalTransaction}
  *
  * @author Manik Surtani (<a href="mailto:manik at jboss.org">manik at jboss.org</a>)
+ * @author Mircea.Markus at jboss.com
  * @since 4.0
  */
 public interface TransactionBoundaryCommand extends VisitableCommand, CacheRpcCommand {
 
    GlobalTransaction getGlobalTransaction();
+
+   void markTransactionAsRemote(boolean remote);
 }

Modified: trunk/core/src/main/java/org/infinispan/config/Configuration.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/config/Configuration.java	2010-09-15 16:19:59 UTC (rev 2385)
+++ trunk/core/src/main/java/org/infinispan/config/Configuration.java	2010-09-15 19:09:38 UTC (rev 2386)
@@ -438,6 +438,10 @@
       this.transaction.setUseEagerLocking(useEagerLocking);
    }
 
+   public void setEagerLockSingleNode(boolean eagerLockSingleNode) {
+      this.transaction.setEagerLockSingleNode(eagerLockSingleNode);
+   }
+
    public void setUseReplQueue(boolean useReplQueue) {
       this.clustering.async.setUseReplQueue(useReplQueue);
    }
@@ -616,6 +620,10 @@
       return transaction.useEagerLocking;
    }
 
+   public boolean isEagerLockSingleNode() {
+      return transaction.eagerLockSingleNode;
+   }
+
    public long getStateRetrievalTimeout() {
       return clustering.stateRetrieval.timeout;
    }
@@ -847,6 +855,17 @@
        * */
       @Dynamic
       protected Boolean useEagerLocking = false;
+
+      /**
+       * @configRef desc="Only has effect for DIST mode and when useEagerLocking is set to true. When this is enabled, then only one node
+       * is locked in the cluster, disregarding numOwners config. On the opposite, if this is false, then on all cache.lock() calls
+       * numOwners RPCs are being performed. The node that gets locked is the main data owner, i.e. the node where data
+       * would reside if numOwners==1. If the node where the lock resides crashes, then the transaction is marked for rollback -
+       * data is in a consistent state, no fault tolerance."
+       */
+      @Dynamic
+      protected Boolean eagerLockSingleNode = false;
+
       
       public TransactionType(String transactionManagerLookupClass) {
          this.transactionManagerLookupClass = transactionManagerLookupClass;
@@ -882,8 +901,15 @@
       public void setUseEagerLocking(Boolean useEagerLocking) {
          testImmutability("useEagerLocking");
          this.useEagerLocking = useEagerLocking;
+
       }
 
+      @XmlAttribute
+      public void setEagerLockSingleNode(Boolean eagerLockSingleNode) {
+         testImmutability("useEagerLocking");
+         this.eagerLockSingleNode = eagerLockSingleNode;
+      }
+
       @Override
       public boolean equals(Object o) {
          if (this == o) return true;

Modified: trunk/core/src/main/java/org/infinispan/config/ConfigurationValidatingVisitor.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/config/ConfigurationValidatingVisitor.java	2010-09-15 16:19:59 UTC (rev 2385)
+++ trunk/core/src/main/java/org/infinispan/config/ConfigurationValidatingVisitor.java	2010-09-15 19:09:38 UTC (rev 2386)
@@ -48,18 +48,5 @@
 
    @Override
    public void visitConfiguration(Configuration bean) {
-      checkEagerLockingAndDld(bean);
    }
-
-   private void checkEagerLockingAndDld(Configuration bean) {
-      boolean isEagerLocking = bean.isUseEagerLocking();
-      checkEagerLockingAndDld(bean, isEagerLocking);
-   }
-
-   public static void checkEagerLockingAndDld(Configuration bean, boolean eagerLocking) {
-      boolean isDealLockDetection = bean.isEnableDeadlockDetection();
-      if (isDealLockDetection && eagerLocking) {
-         throw new ConfigurationException("Deadlock detection cannot be used with eager locking until ISPN-596 is fixed. See https://jira.jboss.org/browse/ISPN-596");
-      }
-   }
 }

Modified: trunk/core/src/main/java/org/infinispan/context/InvocationContext.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/context/InvocationContext.java	2010-09-15 16:19:59 UTC (rev 2385)
+++ trunk/core/src/main/java/org/infinispan/context/InvocationContext.java	2010-09-15 19:09:38 UTC (rev 2386)
@@ -48,11 +48,6 @@
     */
    Object getLockOwner();
 
-   /**
-    * Returns true if the context has any locked entries associated with it.
-    */
-   boolean hasLockedEntries();
-
    boolean isUseFutureReturnType();
 
    void setUseFutureReturnType(boolean useFutureReturnType);
@@ -60,10 +55,8 @@
    InvocationContext clone();
 
    /**
-    * Retrieves a set of keys added to the context within the scope of the current invocation up to the current point
-    * in time.  This is usually all of the keys added to the context, unless transactions are used in which case it is
-    * a subset of all the keys added to the context.
-    * @return a Set of keys, which may be an empty set.
+    * Returns the set of keys that are locked for writing.
     */
-   Set<Object> getKeysAddedInCurrentInvocation();
+   public Set getLockedKeys();
+
 }

Modified: trunk/core/src/main/java/org/infinispan/context/impl/AbstractInvocationContext.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/context/impl/AbstractInvocationContext.java	2010-09-15 16:19:59 UTC (rev 2385)
+++ trunk/core/src/main/java/org/infinispan/context/impl/AbstractInvocationContext.java	2010-09-15 19:09:38 UTC (rev 2386)
@@ -3,11 +3,9 @@
 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.Collections;
 import java.util.EnumSet;
 import java.util.HashSet;
 import java.util.Set;
@@ -22,7 +20,6 @@
 public abstract class AbstractInvocationContext implements InvocationContext {
 
    protected volatile EnumSet<Flag> flags;
-   protected Set<Object> keysAddedInCurrentInvocation;
 
    // since this is finite, small, and strictly an internal API, it is cheaper/quicker to use bitmasking rather than
    // an EnumSet.
@@ -111,7 +108,6 @@
    public void reset() {
       flags = null;
       contextFlags = 0;
-      keysAddedInCurrentInvocation = null;
    }
 
    public boolean isFlagsUninitialized() {
@@ -127,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);
    }
@@ -147,34 +132,26 @@
       setContextFlag(ContextFlag.USE_FUTURE_RETURN_TYPE, useFutureReturnType);
    }
 
-   /**
-    * Records that a key has been added.  This method should be called by all implementations of {@link org.infinispan.context.InvocationContext#putLookedUpEntry(Object, org.infinispan.container.entries.CacheEntry)}
-    * and {@link org.infinispan.context.InvocationContext#putLookedUpEntries(java.util.Map)} for each key added.
-    *
-    * @param key key to record
-    */
-   protected void keyAddedInCurrentInvocation(Object key) {
-      if (keysAddedInCurrentInvocation == null) keysAddedInCurrentInvocation = new HashSet<Object>(4);
-      keysAddedInCurrentInvocation.add(key);
-   }
-
-   public Set<Object> getKeysAddedInCurrentInvocation() {
-      if (keysAddedInCurrentInvocation == null) return Collections.emptySet();
-      return keysAddedInCurrentInvocation;
-   }
-
    @Override
    public AbstractInvocationContext clone() {
       try {
          AbstractInvocationContext dolly = (AbstractInvocationContext) super.clone();
          if (flags != null) dolly.flags = flags.clone();
-         dolly.keysAddedInCurrentInvocation = null;
          return dolly;
       } catch (CloneNotSupportedException e) {
          throw new IllegalStateException("Impossible!");
       }
    }
 
+   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: trunk/core/src/main/java/org/infinispan/context/impl/AbstractTxInvocationContext.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/context/impl/AbstractTxInvocationContext.java	2010-09-15 16:19:59 UTC (rev 2385)
+++ trunk/core/src/main/java/org/infinispan/context/impl/AbstractTxInvocationContext.java	2010-09-15 19:09:38 UTC (rev 2386)
@@ -28,10 +28,6 @@
       return affectedKeys == null ? Collections.EMPTY_SET : affectedKeys;
    }
 
-   public boolean isValidRunningTx() {
-      return isValid(getRunningTransaction());
-   }
-
    public void addAffectedKeys(Object... keys) {
       if (affectedKeys == null) {
          affectedKeys = new HashSet<Object>();
@@ -39,60 +35,6 @@
       affectedKeys.addAll(Arrays.asList(keys));
    }
 
-
-   /**
-    * Return s true of tx's status is ACTIVE or PREPARING
-    *
-    * @param tx
-    * @return true if the tx is active or preparing
-    */
-   public static boolean isValid(Transaction tx) {
-      return isActive(tx) || isPreparing(tx);
-   }
-
-   /**
-    * Returns true if transaction is ACTIVE, false otherwise
-    */
-   public static boolean isActive(Transaction tx) {
-      if (tx == null) return false;
-      int status;
-      try {
-         status = tx.getStatus();
-         return status == Status.STATUS_ACTIVE;
-      }
-      catch (SystemException e) {
-         return false;
-      }
-   }
-
-   /**
-    * Returns true if transaction is PREPARING, false otherwise
-    */
-   public static boolean isPreparing(Transaction tx) {
-      if (tx == null) return false;
-      int status;
-      try {
-         status = tx.getStatus();
-         return status == Status.STATUS_PREPARING;
-      }
-      catch (SystemException e) {
-         return false;
-      }
-   }
-
-   /**
-    * Tests whether the caller is in a valid transaction.  If not, will throw a CacheException.
-    */
-   public static void assertTransactionValid(TxInvocationContext ctx) {
-      Transaction tx = ctx.getRunningTransaction();
-      if (!isValid(tx)) try {
-         throw new CacheException("Invalid transaction " + tx + ", status = " + (tx == null ? null : tx.getStatus()));
-      }
-      catch (SystemException e) {
-         throw new CacheException("Exception trying to analyse status of transaction " + tx, e);
-      }
-   }
-
    @Override
    public AbstractTxInvocationContext clone() {
       AbstractTxInvocationContext dolly = (AbstractTxInvocationContext) super.clone();

Modified: trunk/core/src/main/java/org/infinispan/context/impl/LocalTxInvocationContext.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/context/impl/LocalTxInvocationContext.java	2010-09-15 16:19:59 UTC (rev 2385)
+++ trunk/core/src/main/java/org/infinispan/context/impl/LocalTxInvocationContext.java	2010-09-15 19:09:38 UTC (rev 2386)
@@ -2,11 +2,13 @@
 
 import org.infinispan.commands.write.WriteCommand;
 import org.infinispan.container.entries.CacheEntry;
+import org.infinispan.remoting.transport.Address;
 import org.infinispan.transaction.xa.GlobalTransaction;
 import org.infinispan.transaction.xa.TransactionXaAdapter;
 import org.infinispan.util.BidirectionalMap;
 
 import javax.transaction.Transaction;
+import java.util.Collection;
 import java.util.List;
 import java.util.Map;
 
@@ -57,13 +59,11 @@
    }
 
    public void putLookedUpEntry(Object key, CacheEntry e) {
-      keyAddedInCurrentInvocation(key);
       xaAdapter.putLookedUpEntry(key, e);
    }
 
    public void putLookedUpEntries(Map<Object, CacheEntry> lookedUpEntries) {
       for (Map.Entry<Object, CacheEntry> ce: lookedUpEntries.entrySet()) {
-         keyAddedInCurrentInvocation(ce.getKey());
          xaAdapter.putLookedUpEntry(ce.getKey(), ce.getValue());
       }
    }
@@ -80,4 +80,8 @@
    public boolean hasLockedKey(Object key) {
       return xaAdapter != null && super.hasLockedKey(key);
    }
+
+   public void remoteLocksAcquired(Collection<Address> nodes) {
+      xaAdapter.locksAcquired(nodes);
+   }
 }

Modified: trunk/core/src/main/java/org/infinispan/context/impl/NonTxInvocationContext.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/context/impl/NonTxInvocationContext.java	2010-09-15 16:19:59 UTC (rev 2385)
+++ trunk/core/src/main/java/org/infinispan/context/impl/NonTxInvocationContext.java	2010-09-15 19:09:38 UTC (rev 2386)
@@ -27,14 +27,12 @@
 
    public void putLookedUpEntry(Object key, CacheEntry e) {
       initLookedUpEntries();
-      keyAddedInCurrentInvocation(key);
       lookedUpEntries.put(key, e);
    }
 
    public void putLookedUpEntries(Map<Object, CacheEntry> lookedUpEntries) {
       initLookedUpEntries();
       for (Map.Entry<Object, CacheEntry> ce: lookedUpEntries.entrySet()) {
-         keyAddedInCurrentInvocation(ce.getKey());
          lookedUpEntries.put(ce.getKey(), ce.getValue());
       }
    }

Modified: trunk/core/src/main/java/org/infinispan/context/impl/RemoteTxInvocationContext.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/context/impl/RemoteTxInvocationContext.java	2010-09-15 16:19:59 UTC (rev 2385)
+++ trunk/core/src/main/java/org/infinispan/context/impl/RemoteTxInvocationContext.java	2010-09-15 19:09:38 UTC (rev 2386)
@@ -62,7 +62,6 @@
    }
 
    public void putLookedUpEntry(Object key, CacheEntry e) {
-      keyAddedInCurrentInvocation(key);
       remoteTransaction.putLookedUpEntry(key, e);
    }
 
@@ -76,7 +75,6 @@
 
    public void putLookedUpEntries(Map<Object, CacheEntry> lookedUpEntries) {
       for (Map.Entry<Object, CacheEntry> ce: lookedUpEntries.entrySet()) {
-         keyAddedInCurrentInvocation(ce.getKey());
          remoteTransaction.putLookedUpEntry(ce.getKey(), ce.getValue());
       }
    }

Modified: trunk/core/src/main/java/org/infinispan/context/impl/TxInvocationContext.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/context/impl/TxInvocationContext.java	2010-09-15 16:19:59 UTC (rev 2385)
+++ trunk/core/src/main/java/org/infinispan/context/impl/TxInvocationContext.java	2010-09-15 19:09:38 UTC (rev 2386)
@@ -46,11 +46,6 @@
    Transaction getRunningTransaction();
 
    /**
-    * Returns true if the current tx is either ACTIVE or PREPARING, false otherwise.
-    */
-   boolean isValidRunningTx();
-
-   /**
     * Registers a new participant with the transaction.
     */
    void addAffectedKeys(Object... keys);

Modified: trunk/core/src/main/java/org/infinispan/distribution/DistributionManager.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/distribution/DistributionManager.java	2010-09-15 16:19:59 UTC (rev 2385)
+++ trunk/core/src/main/java/org/infinispan/distribution/DistributionManager.java	2010-09-15 19:09:38 UTC (rev 2386)
@@ -18,6 +18,7 @@
  * A component that manages the distribution of elements across a cache cluster
  *
  * @author Manik Surtani
+ * @author Mircea.Markus at jboss.com
  * @since 4.0
  */
 @Scope(Scopes.NAMED_CACHE)
@@ -46,6 +47,11 @@
    Map<Object, List<Address>> locateAll(Collection<Object> keys);
 
    /**
+    * Same as {@link #locateAll(java.util.Collection)}, but the list of addresses only contains numOwners owners.
+    */
+   Map<Object, List<Address>> locateAll(Collection<Object> keys, int numOwners);
+
+   /**
     * Transforms a cache entry so it is marked for L1 rather than the primary cache data structure.  This should be done
     * if it is deemed that the entry is targeted for L1 storage rather than storage in the primary data container.
     *

Modified: trunk/core/src/main/java/org/infinispan/distribution/DistributionManagerImpl.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/distribution/DistributionManagerImpl.java	2010-09-15 16:19:59 UTC (rev 2385)
+++ trunk/core/src/main/java/org/infinispan/distribution/DistributionManagerImpl.java	2010-09-15 19:09:38 UTC (rev 2386)
@@ -259,13 +259,17 @@
    }
 
    public Map<Object, List<Address>> locateAll(Collection<Object> keys) {
+      return locateAll(keys, replCount);
+   }
+
+   public Map<Object, List<Address>> locateAll(Collection<Object> keys, int numOwners) {
       if (consistentHash == null) {
          Map<Object, List<Address>> m = new HashMap<Object, List<Address>>(keys.size());
          List<Address> selfList = Collections.singletonList(self);
          for (Object k : keys) m.put(k, selfList);
          return m;
       }
-      return consistentHash.locateAll(keys, replCount);
+      return consistentHash.locateAll(keys, numOwners);
    }
 
    public void transformForL1(CacheEntry entry) {

Modified: trunk/core/src/main/java/org/infinispan/interceptors/CallInterceptor.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/interceptors/CallInterceptor.java	2010-09-15 16:19:59 UTC (rev 2385)
+++ trunk/core/src/main/java/org/infinispan/interceptors/CallInterceptor.java	2010-09-15 19:09:38 UTC (rev 2386)
@@ -37,6 +37,7 @@
  * transaction.
  *
  * @author Bela Ban
+ * @author Mircea.Markus at jboss.com
  * @since 4.0
  */
 public class CallInterceptor extends CommandInterceptor {
@@ -67,19 +68,6 @@
    @Override
    final public Object handleDefault(InvocationContext ctx, VisitableCommand command) throws Throwable {
       if (trace) log.trace("Executing command: " + command + ".");
-      Object retval;
-      try {
-         retval = command.perform(ctx);
-      }
-      catch (Throwable t) {
-         if (ctx.isInTxScope()) {
-            TxInvocationContext txContext = (TxInvocationContext) ctx;
-            if (txContext.isValidRunningTx()) {
-               txContext.getRunningTransaction().setRollbackOnly();
-            }
-         }
-         throw t;
-      }
-      return retval;
+      return command.perform(ctx);
    }
 }
\ No newline at end of file

Modified: trunk/core/src/main/java/org/infinispan/interceptors/DeadlockDetectingInterceptor.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/interceptors/DeadlockDetectingInterceptor.java	2010-09-15 16:19:59 UTC (rev 2385)
+++ trunk/core/src/main/java/org/infinispan/interceptors/DeadlockDetectingInterceptor.java	2010-09-15 19:09:38 UTC (rev 2386)
@@ -1,29 +1,26 @@
 package org.infinispan.interceptors;
 
-import org.infinispan.commands.DataCommand;
+import org.infinispan.commands.VisitableCommand;
+import org.infinispan.commands.control.LockControlCommand;
 import org.infinispan.commands.tx.PrepareCommand;
-import org.infinispan.commands.tx.RollbackCommand;
 import org.infinispan.commands.write.PutKeyValueCommand;
 import org.infinispan.commands.write.RemoveCommand;
 import org.infinispan.commands.write.ReplaceCommand;
 import org.infinispan.context.InvocationContext;
 import org.infinispan.context.impl.TxInvocationContext;
-import org.infinispan.distribution.DistributionManager;
 import org.infinispan.factories.annotations.Inject;
 import org.infinispan.factories.annotations.Start;
 import org.infinispan.interceptors.base.CommandInterceptor;
-import org.infinispan.remoting.transport.Address;
-import org.infinispan.transaction.xa.DeadlockDetectingGlobalTransaction;
+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.concurrent.locks.DeadlockDetectedException;
-import org.infinispan.util.concurrent.locks.LockManager;
 
-import javax.transaction.Transaction;
-import javax.transaction.TransactionManager;
-import java.util.HashSet;
+import java.util.Collections;
+import java.util.Set;
 
 /**
- * This interceptor populates the {@link org.infinispan.transaction.xa.DeadlockDetectingGlobalTransaction} with
+ * This interceptor populates the {@link org.infinispan.transaction.xa.DldGlobalTransaction} with
  * appropriate information needed in order to accomplish deadlock detection. It MUST process populate data before the
  * replication takes place, so it will do all the tasks before calling {@link org.infinispan.interceptors.base.CommandInterceptor#invokeNextInterceptor(org.infinispan.context.InvocationContext,
  * org.infinispan.commands.VisitableCommand)}.
@@ -35,21 +32,6 @@
  */
 public class DeadlockDetectingInterceptor extends CommandInterceptor {
 
-   private TransactionTable txTable;
-   private LockManager lockManager;
-   private TransactionManager txManager;
-   private DistributionManager distributionManager;
-
-   @Inject
-   public void init(TransactionTable txTable, LockManager lockManager, TransactionManager txManager,
-                    DistributionManager distributionManager) {
-      this.txTable = txTable;
-      this.lockManager = lockManager;
-      this.txManager = txManager;
-      this.distributionManager = distributionManager;
-   }
-
-
    /**
     * Only does a sanity check.
     */
@@ -60,43 +42,6 @@
       }
    }
 
-   private Object handleDataCommand(InvocationContext ctx, DataCommand command) throws Throwable {
-      if (ctx.isInTxScope()) {
-         DeadlockDetectingGlobalTransaction gtx = (DeadlockDetectingGlobalTransaction) ctx.getLockOwner();
-         gtx.setLockIntention(command.getKey());
-         gtx.setProcessingThread(Thread.currentThread());
-      }
-      try {
-         return invokeNextInterceptor(ctx, command);
-      } catch (InterruptedException ie) {
-         if (ctx.isInTxScope()) {
-            lockManager.releaseLocks(ctx);
-            if (ctx.isOriginLocal()) {
-               Transaction transaction = txManager.getTransaction();
-               if (trace)
-                  log.trace("Marking the transaction for rollback! : " + transaction);
-               if (transaction == null) {
-                  throw new IllegalStateException("We're running in a local transaction, there MUST be one " +
-                        "associated witht the local thread but none found! (null)");
-               }
-               transaction.setRollbackOnly();
-               txTable.removeLocalTransaction(transaction);
-               throw new DeadlockDetectedException("Deadlock request was detected for locally originated tx " + transaction +
-                     "; it was marked for rollback");
-            } else {
-               DeadlockDetectingGlobalTransaction gtx = (DeadlockDetectingGlobalTransaction) ctx.getLockOwner();
-               gtx.setMarkedForRollback(true);
-               throw new DeadlockDetectedException("Deadlock request was detected for remotely originated tx " + gtx +
-                     "; it was marked for rollback");
-            }
-         } else {
-            if (trace)
-               log.trace("Received an interrupt request, but we're not running within the scope of a transaction, so passing it up the stack", ie);
-            throw ie;
-         }
-      }
-   }
-
    @Override
    public Object visitPutKeyValueCommand(InvocationContext ctx, PutKeyValueCommand command) throws Throwable {
       return handleDataCommand(ctx, command);
@@ -113,46 +58,34 @@
    }
 
    @Override
-   public Object visitPrepareCommand(TxInvocationContext ctx, PrepareCommand command) throws Throwable {
-      DeadlockDetectingGlobalTransaction globalTransaction = (DeadlockDetectingGlobalTransaction) ctx.getGlobalTransaction();
-      globalTransaction.setProcessingThread(Thread.currentThread());
+   public Object visitLockControlCommand(TxInvocationContext ctx, LockControlCommand command) throws Throwable {
+      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()) {
-            globalTransaction.setReplicatingTo(new HashSet<Address>(distributionManager.getAffectedNodes(ctx.getAffectedKeys())));
-         } else {
-            globalTransaction.setReplicatingTo(null);
+            ((DldGlobalTransaction) ctx.getGlobalTransaction()).setLocksHeldAtOrigin(ctx.getLockedKeys());
          }
-         if (trace) log.trace("Deadlock detection information was added to " + globalTransaction);
       }
-      try {
-         return invokeNextInterceptor(ctx, command);
-      } catch (Throwable dde) {
-         if (ctx.isOriginLocal()) {
-            globalTransaction.setMarkedForRollback(true);
-            boolean wasInterrupted = Thread.interrupted();
-            if (trace)
-               log.trace("Deadlock was detected on the remote side, marking the tx for rollback. Was this thread interrupted? " + wasInterrupted);
-         }
-         throw dde;
-      } finally {
-         if (!ctx.isOriginLocal()) {
-            if (!txTable.containRemoteTx(ctx.getGlobalTransaction())) {
-               if (trace) {
-                  log.trace("While returning from prepare we determined that remote tx is no longer in the txTable. " +
-                        "This means that a rollback was executed in between; releasing locks");
-               }
-               lockManager.releaseLocks(ctx);
-            }
-         }
-      }
+      return handleDataCommand(ctx, command);
    }
 
    @Override
-   public Object visitRollbackCommand(TxInvocationContext ctx, RollbackCommand command) throws Throwable {
-      if (!ctx.isOriginLocal()) {
-         DeadlockDetectingGlobalTransaction globalTransaction = (DeadlockDetectingGlobalTransaction) ctx.getGlobalTransaction();
-         globalTransaction.interruptProcessingThread();
+   public Object visitPrepareCommand(TxInvocationContext ctx, PrepareCommand command) throws Throwable {
+      DldGlobalTransaction globalTransaction = (DldGlobalTransaction) ctx.getGlobalTransaction();
+      if (ctx.isOriginLocal()) {
+         globalTransaction.setRemoteLockIntention(command.getAffectedKeys());
       }
+      Object result = invokeNextInterceptor(ctx, command);
+      if (ctx.isOriginLocal()) {
+         globalTransaction.setRemoteLockIntention(Collections.EMPTY_SET);
+      }
+      return result;
+   }
+
+
+   private Object handleDataCommand(InvocationContext ctx, VisitableCommand command) throws Throwable {
       return invokeNextInterceptor(ctx, command);
    }
 }

Modified: trunk/core/src/main/java/org/infinispan/interceptors/DistributionInterceptor.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/interceptors/DistributionInterceptor.java	2010-09-15 16:19:59 UTC (rev 2385)
+++ trunk/core/src/main/java/org/infinispan/interceptors/DistributionInterceptor.java	2010-09-15 19:09:38 UTC (rev 2386)
@@ -19,6 +19,7 @@
 import org.infinispan.container.entries.InternalCacheEntry;
 import org.infinispan.context.Flag;
 import org.infinispan.context.InvocationContext;
+import org.infinispan.context.impl.LocalTxInvocationContext;
 import org.infinispan.context.impl.TxInvocationContext;
 import org.infinispan.distribution.DistributionManager;
 import org.infinispan.factories.annotations.Inject;
@@ -30,6 +31,7 @@
 import org.infinispan.util.concurrent.NotifyingFutureImpl;
 import org.infinispan.util.concurrent.NotifyingNotifiableFuture;
 
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashSet;
 import java.util.LinkedList;
@@ -41,6 +43,7 @@
  * The interceptor that handles distribution of entries across a cluster, as well as transparent lookup
  *
  * @author Manik Surtani
+ * @author Mircea.Markus at jboss.com
  * @since 4.0
  */
 public class DistributionInterceptor extends BaseRpcInterceptor {
@@ -189,8 +192,28 @@
 
    @Override
    public Object visitLockControlCommand(TxInvocationContext ctx, LockControlCommand command) throws Throwable {
-      if (ctx.isOriginLocal())
-         rpcManager.invokeRemotely(dm.getAffectedNodes(command.getKeys()), command, true, true);
+      if (ctx.isOriginLocal()) {
+         if (configuration.isEagerLockSingleNode()) {
+            //only main data owner is locked, see: https://jira.jboss.org/browse/ISPN-615
+            Map<Object, List<Address>> toMulticast = dm.locateAll(command.getKeys(), 1);
+
+            //now compile address reunion
+            List<Address> where;
+            if (toMulticast.size() == 1) {//avoid building an extra array, as most often this will be a single key
+               where = toMulticast.values().iterator().next();
+               rpcManager.invokeRemotely(where, command, true, true);
+            } else {
+               where = new ArrayList<Address>();
+               for (List<Address> values:  toMulticast.values()) {
+                  where.addAll(values);
+               }
+               rpcManager.invokeRemotely(where, command, true, true);
+            }
+            ((LocalTxInvocationContext)ctx).remoteLocksAcquired(where);
+         } else {
+            rpcManager.invokeRemotely(dm.getAffectedNodes(command.getKeys()), command, true, true);
+         }
+      }
       return invokeNextInterceptor(ctx, command);
    }
 

Modified: trunk/core/src/main/java/org/infinispan/interceptors/ImplicitEagerLockingInterceptor.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/interceptors/ImplicitEagerLockingInterceptor.java	2010-09-15 16:19:59 UTC (rev 2385)
+++ trunk/core/src/main/java/org/infinispan/interceptors/ImplicitEagerLockingInterceptor.java	2010-09-15 19:09:38 UTC (rev 2386)
@@ -8,6 +8,7 @@
 import org.infinispan.commands.write.PutMapCommand;
 import org.infinispan.commands.write.RemoveCommand;
 import org.infinispan.commands.write.ReplaceCommand;
+import org.infinispan.context.Flag;
 import org.infinispan.context.InvocationContext;
 import org.infinispan.factories.annotations.Inject;
 import org.infinispan.interceptors.base.CommandInterceptor;
@@ -23,6 +24,7 @@
  * For more details refer to: https://jira.jboss.org/jira/browse/ISPN-70 https://jira.jboss.org/jira/browse/ISPN-48
  *
  * @author <a href="mailto:vblagoje at redhat.com">Vladimir Blagojevic (vblagoje at redhat.com)</a>
+ * @author Mircea.Markus at jboss.com
  * @since 4.0
  */
 public class ImplicitEagerLockingInterceptor extends CommandInterceptor {
@@ -35,10 +37,8 @@
    }
 
    @Override
-   public Object visitPutKeyValueCommand(InvocationContext ctx, PutKeyValueCommand command)
-         throws Throwable {
-      boolean localTxScope = ctx.isInTxScope() & ctx.isOriginLocal();
-      if (localTxScope) {
+   public Object visitPutKeyValueCommand(InvocationContext ctx, PutKeyValueCommand command) throws Throwable {
+      if (shouldAcquireRemoteLock(ctx)) {
          lockEagerly(ctx, Collections.singleton(command.getKey()));
       }
       return invokeNextInterceptor(ctx, command);
@@ -46,8 +46,7 @@
 
    @Override
    public Object visitRemoveCommand(InvocationContext ctx, RemoveCommand command) throws Throwable {
-      boolean localTxScope = ctx.isInTxScope() & ctx.isOriginLocal();
-      if (localTxScope) {
+      if (shouldAcquireRemoteLock(ctx)) {
          lockEagerly(ctx, Collections.singleton(command.getKey()));
       }
       return invokeNextInterceptor(ctx, command);
@@ -56,8 +55,7 @@
    @Override
    public Object visitReplaceCommand(InvocationContext ctx, ReplaceCommand command)
          throws Throwable {
-      boolean localTxScope = ctx.isInTxScope() & ctx.isOriginLocal();
-      if (localTxScope) {
+      if (shouldAcquireRemoteLock(ctx)) {
          lockEagerly(ctx, Collections.singleton(command.getKey()));
       }
       return invokeNextInterceptor(ctx, command);
@@ -65,8 +63,7 @@
 
    @Override
    public Object visitPutMapCommand(InvocationContext ctx, PutMapCommand command) throws Throwable {
-      boolean localTxScope = ctx.isInTxScope() & ctx.isOriginLocal();
-      if (localTxScope) {
+      if (shouldAcquireRemoteLock(ctx)) {
          lockEagerly(ctx, new HashSet<Object>(command.getMap().keySet()));
       }
       return invokeNextInterceptor(ctx, command);
@@ -74,8 +71,7 @@
 
    @Override
    public Object visitEvictCommand(InvocationContext ctx, EvictCommand command) throws Throwable {
-      boolean localTxScope = ctx.isInTxScope() & ctx.isOriginLocal();
-      if (localTxScope) {
+      if (shouldAcquireRemoteLock(ctx)) {
          lockEagerly(ctx, Collections.singleton(command.getKey()));
       }
       return invokeNextInterceptor(ctx, command);
@@ -84,8 +80,7 @@
    @Override
    public Object visitInvalidateCommand(InvocationContext ctx, InvalidateCommand command)
          throws Throwable {
-      boolean localTxScope = ctx.isInTxScope() & ctx.isOriginLocal();
-      if (localTxScope) {
+      if (shouldAcquireRemoteLock(ctx)) {
          lockEagerly(ctx, Collections.singleton(command.getKey()));
       }
       return invokeNextInterceptor(ctx, command);
@@ -95,4 +90,8 @@
       LockControlCommand lcc = cf.buildLockControlCommand(keys, true);
       return invokeNextInterceptor(ctx, lcc);
    }
+
+   private boolean shouldAcquireRemoteLock(InvocationContext ctx) {
+      return ctx.isInTxScope() & ctx.isOriginLocal() && !ctx.hasFlag(Flag.CACHE_MODE_LOCAL);
+   }
 }

Modified: trunk/core/src/main/java/org/infinispan/interceptors/InvalidationInterceptor.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/interceptors/InvalidationInterceptor.java	2010-09-15 16:19:59 UTC (rev 2385)
+++ trunk/core/src/main/java/org/infinispan/interceptors/InvalidationInterceptor.java	2010-09-15 19:09:38 UTC (rev 2386)
@@ -52,6 +52,7 @@
 
 import javax.transaction.SystemException;
 import javax.transaction.Transaction;
+import java.sql.ResultSet;
 import java.util.Arrays;
 import java.util.HashSet;
 import java.util.List;
@@ -70,6 +71,7 @@
  *
  * @author Manik Surtani
  * @author Galder Zamarreño
+ * @author Mircea.Markus at jboss.com
  * @since 4.0
  */
 @MBean(objectName = "Invalidation", description = "Component responsible for invalidating entries on remote caches when entries are written to locally.")
@@ -164,12 +166,6 @@
             }
             catch (Throwable t) {
                log.warn("Unable to broadcast evicts as a part of the prepare phase.  Rolling back.", t);
-               try {
-                  tx.setRollbackOnly();
-               }
-               catch (SystemException se) {
-                  throw new RuntimeException("setting tx rollback failed ", se);
-               }
                if (t instanceof RuntimeException)
                   throw (RuntimeException) t;
                else
@@ -198,6 +194,12 @@
          result.add(command.getKey());
          return null;
       }
+
+      @Override
+      public Object visitPutMapCommand(InvocationContext ctx, PutMapCommand command) throws Throwable {
+         result.addAll(command.getAffectedKeys());
+         return null;
+      }
    }
 
 

Modified: trunk/core/src/main/java/org/infinispan/interceptors/InvocationContextInterceptor.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/interceptors/InvocationContextInterceptor.java	2010-09-15 16:19:59 UTC (rev 2385)
+++ trunk/core/src/main/java/org/infinispan/interceptors/InvocationContextInterceptor.java	2010-09-15 19:09:38 UTC (rev 2386)
@@ -22,27 +22,35 @@
 package org.infinispan.interceptors;
 
 
+import org.infinispan.CacheException;
 import org.infinispan.commands.VisitableCommand;
 import org.infinispan.context.Flag;
 import org.infinispan.context.InvocationContext;
 import org.infinispan.factories.annotations.Inject;
 import org.infinispan.interceptors.base.CommandInterceptor;
-import org.infinispan.util.concurrent.locks.LockManager;
 
+import javax.transaction.Status;
+import javax.transaction.SystemException;
+import javax.transaction.Transaction;
+import javax.transaction.TransactionManager;
+
+/**
+ * @author Mircea.Markus at jboss.com
+ */
 public class InvocationContextInterceptor extends CommandInterceptor {
 
-   LockManager lockManager;
+   private TransactionManager tm;
 
+   @Inject
+   public void init(TransactionManager tm) {
+      this.tm = tm;
+   }
+
    @Override
    public Object handleDefault(InvocationContext ctx, VisitableCommand command) throws Throwable {
       return handleAll(ctx, command);
    }
 
-   @Inject
-   public void injectLockManager(LockManager lockManager) {
-      this.lockManager = lockManager;
-   }
-
    private Object handleAll(InvocationContext ctx, VisitableCommand command) throws Throwable {
       boolean suppressExceptions = false;
 
@@ -57,30 +65,41 @@
          return invokeNextInterceptor(ctx, command);
       }
       catch (Throwable th) {
-         // make sure we release locks for all keys locked in this invocation!
-         for (Object key: ctx.getKeysAddedInCurrentInvocation()) {
-            if (ctx.hasLockedKey(key)) {
-               if (suppressExceptions) {
-                  if (log.isDebugEnabled()) log.debug("Caught exception, Releasing lock on key " + key + " acquired during the current invocation!");
-               } else {
-                  if (log.isInfoEnabled()) log.info("Caught exception, Releasing lock on key " + key + " acquired during the current invocation!");
-               }
-               // unlock key!
-               lockManager.unlock(key);
-               ctx.removeLookedUpEntry(key);
-            }
-         }
-
          if (suppressExceptions) {
             log.trace("Exception while executing code, failing silently...", th);
             return null;
          } else {
+            if (ctx.isInTxScope() && ctx.isOriginLocal()) {
+               if (trace) log.trace("Transaction marked for rollback as exception was received.");
+               markTxForRollbackAndRethrow(ctx, th);
+               throw new IllegalStateException("This should not be reached");
+            }
             log.error("Execution error: ", th);
-
             throw th;
          }
       } finally {
          ctx.reset();
       }
    }
+
+   private Object markTxForRollbackAndRethrow(InvocationContext ctx, Throwable te) throws Throwable {
+      if (ctx.isOriginLocal() && ctx.isInTxScope()) {
+         Transaction transaction = tm.getTransaction();
+         if (transaction != null && isValidRunningTx(transaction)) {
+            transaction.setRollbackOnly();
+         }
+      }
+      throw te;
+   }   
+
+   public boolean isValidRunningTx(Transaction tx) throws Exception {
+      int status;
+      try {
+         status = tx.getStatus();
+      }
+      catch (SystemException e) {
+         throw new CacheException("Unexpected!", e);
+      }
+      return status == Status.STATUS_ACTIVE || status == Status.STATUS_PREPARING;
+   }
 }
\ No newline at end of file

Modified: trunk/core/src/main/java/org/infinispan/interceptors/LockingInterceptor.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/interceptors/LockingInterceptor.java	2010-09-15 16:19:59 UTC (rev 2385)
+++ trunk/core/src/main/java/org/infinispan/interceptors/LockingInterceptor.java	2010-09-15 19:09:38 UTC (rev 2386)
@@ -58,6 +58,7 @@
  * Interceptor to implement <a href="http://wiki.jboss.org/wiki/JBossCacheMVCC">MVCC</a> functionality.
  *
  * @author Manik Surtani (<a href="mailto:manik at jboss.org">manik at jboss.org</a>)
+ * @author Mircea.Markus at jboss.com
  * @see <a href="http://wiki.jboss.org/wiki/JBossCacheMVCC">MVCC designs</a>
  * @since 4.0
  */
@@ -138,17 +139,41 @@
          if (localTxScope) {
             c.attachGlobalTransaction((GlobalTransaction) ctx.getLockOwner());
          }
+
+         if (c.isUnlock()) {
+            lockManager.releaseLocks(ctx);
+            if (log.isTraceEnabled()) log.trace("Lock released for: " + ctx.getLockOwner());
+            return null;
+         }
+
          for (Object key : c.getKeys()) {
             if (c.isImplicit() && localTxScope && !lockManager.ownsLock(key, ctx.getLockOwner())) {
-               //if even one key is unlocked we need to invoke this lock command cluster wide... 
+               //if even one key is unlocked we need to invoke this lock command cluster wide...
                shouldInvokeOnCluster = true;
+               break;
             }
-            entryFactory.wrapEntryForWriting(ctx, key, true, false, false, false, false);
          }
-         if (shouldInvokeOnCluster || c.isExplicit())
-            return invokeNextInterceptor(ctx, c);
-         else
-            return null;
+         boolean goRemoteFirst = configuration.isEnableDeadlockDetection() && localTxScope;
+         if (goRemoteFirst) {
+            Object result = invokeNextInterceptor(ctx, c);
+            try {
+               lockKeysForRemoteTx(ctx, c);
+            } catch (Throwable e) {
+               //if anything happen during locking then unlock remote
+               c.setUnlock(true);
+               invokeNextInterceptor(ctx, c);
+               throw e;
+            }
+            return result;
+         } else {
+            lockKeysForRemoteTx(ctx, c);
+            if (shouldInvokeOnCluster || c.isExplicit())
+               return invokeNextInterceptor(ctx, c);
+            else
+               return null;
+         }
+      } catch (Throwable te) {
+            return cleanLocksAndRethrow(ctx, te);
       } finally {
          if (ctx.isInTxScope()) {
             doAfterCall(ctx);
@@ -158,6 +183,12 @@
       }
    }
 
+   private void lockKeysForRemoteTx(TxInvocationContext ctx, LockControlCommand c) throws InterruptedException {
+      for (Object key : c.getKeys()) {
+         entryFactory.wrapEntryForWriting(ctx, key, true, false, false, false, false);
+      }
+   }
+
    // write commands
 
    @Override
@@ -167,6 +198,8 @@
          for (InternalCacheEntry entry : dataContainer.entrySet())
             entryFactory.wrapEntryForWriting(ctx, entry, false, false, false, false, false);
          return invokeNextInterceptor(ctx, command);
+      } catch (Throwable te) {
+         return cleanLocksAndRethrow(ctx, te);
       } finally {
          doAfterCall(ctx);
       }
@@ -183,10 +216,14 @@
    public Object visitInvalidateCommand(InvocationContext ctx, InvalidateCommand command) throws Throwable {
       try {
          if (command.getKeys() != null) {
-            for (Object key : command.getKeys()) entryFactory.wrapEntryForWriting(ctx, key, false, true, false, false, false);
+            for (Object key : command.getKeys())
+               entryFactory.wrapEntryForWriting(ctx, key, false, true, false, false, false);
          }
          return invokeNextInterceptor(ctx, command);
-      } finally {
+      } catch (Throwable te) {
+         return cleanLocksAndRethrow(ctx, te);
+      }
+      finally {
          doAfterCall(ctx);
       }
    }
@@ -196,7 +233,10 @@
       try {
          entryFactory.wrapEntryForWriting(ctx, command.getKey(), true, false, false, false, !command.isPutIfAbsent());
          return invokeNextInterceptor(ctx, command);
-      } finally {
+      } catch (Throwable te) {
+         return cleanLocksAndRethrow(ctx, te);
+      }
+      finally {
          doAfterCall(ctx);
       }
    }
@@ -208,6 +248,8 @@
             entryFactory.wrapEntryForWriting(ctx, key, true, false, false, false, true);
          }
          return invokeNextInterceptor(ctx, command);
+      } catch (Throwable te) {
+         return cleanLocksAndRethrow(ctx, te);
       }
       finally {
          doAfterCall(ctx);
@@ -219,6 +261,8 @@
       try {
          entryFactory.wrapEntryForWriting(ctx, command.getKey(), false, true, false, true, false);
          return invokeNextInterceptor(ctx, command);
+      } catch (Throwable te) {
+         return cleanLocksAndRethrow(ctx, te);
       }
       finally {
          doAfterCall(ctx);
@@ -230,6 +274,8 @@
       try {
          entryFactory.wrapEntryForWriting(ctx, command.getKey(), false, true, false, false, false);
          return invokeNextInterceptor(ctx, command);
+      } catch (Throwable te) {
+         return cleanLocksAndRethrow(ctx, te);
       }
       finally {
          doAfterCall(ctx);
@@ -294,6 +340,11 @@
       }
    }
 
+   private Object cleanLocksAndRethrow(InvocationContext ctx, Throwable te) throws Throwable {
+      cleanupLocks(ctx, false);
+      throw te;
+   }
+
    protected void commitEntry(CacheEntry entry) {
       entry.commit(dataContainer);
    }

Modified: trunk/core/src/main/java/org/infinispan/interceptors/TxInterceptor.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/interceptors/TxInterceptor.java	2010-09-15 16:19:59 UTC (rev 2385)
+++ trunk/core/src/main/java/org/infinispan/interceptors/TxInterceptor.java	2010-09-15 19:09:38 UTC (rev 2386)
@@ -112,21 +112,9 @@
 
    @Override
    public Object visitLockControlCommand(TxInvocationContext ctx, LockControlCommand command) throws Throwable {
-      return enlistReadAndInvokeNext(ctx, command);
+       return enlistReadAndInvokeNext(ctx, command);
    }
 
-   /**
-    * Designed to be overridden.  Returns a VisitableCommand fit for replaying locally, based on the modification passed
-    * in.  If a null value is returned, this means that the command should not be replayed.
-    *
-    * @param modification modification in a prepare call
-    * @return a VisitableCommand representing this modification, fit for replaying, or null if the command should not be
-    *         replayed.
-    */
-   protected VisitableCommand getCommandToReplay(VisitableCommand modification) {
-      return modification;
-   }
-
    @Override
    public Object visitPutKeyValueCommand(InvocationContext ctx, PutKeyValueCommand command) throws Throwable {
       return enlistWriteAndInvokeNext(ctx, command);
@@ -180,7 +168,8 @@
          if (localModeNotForced(ctx)) shouldAddMod = true;
          localTxContext.setXaCache(xaAdapter);
       }
-      Object rv = invokeNextInterceptor(ctx, command);
+      Object rv;
+      rv = invokeNextInterceptor(ctx, command);
       if (!ctx.isInTxScope())
          transactionLog.logNoTxWrite(command);
       if (command.isSuccessful() && shouldAddMod) xaAdapter.addModification(command);
@@ -247,4 +236,16 @@
    public long getRollbacks() {
       return rollbacks.get();
    }
+
+   /**
+    * Designed to be overridden.  Returns a VisitableCommand fit for replaying locally, based on the modification passed
+    * in.  If a null value is returned, this means that the command should not be replayed.
+    *
+    * @param modification modification in a prepare call
+    * @return a VisitableCommand representing this modification, fit for replaying, or null if the command should not be
+    *         replayed.
+    */
+   protected VisitableCommand getCommandToReplay(VisitableCommand modification) {
+      return modification;
+   }
 }

Modified: trunk/core/src/main/java/org/infinispan/interceptors/base/BaseRpcInterceptor.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/interceptors/base/BaseRpcInterceptor.java	2010-09-15 16:19:59 UTC (rev 2385)
+++ trunk/core/src/main/java/org/infinispan/interceptors/base/BaseRpcInterceptor.java	2010-09-15 19:09:38 UTC (rev 2386)
@@ -56,12 +56,13 @@
    public Object visitLockControlCommand(TxInvocationContext ctx, LockControlCommand command) throws Throwable {
       Object retVal = invokeNextInterceptor(ctx, command);
       if (ctx.isOriginLocal()) {
-         rpcManager.broadcastRpcCommand(command, true, false);
+         //unlock will happen async as it is a best effort
+         boolean sync = !command.isUnlock();
+         rpcManager.broadcastRpcCommand(command, sync, false);
       }
       return retVal;
    }
 
-
    protected final boolean isSynchronous(InvocationContext ctx) {
       if (ctx.hasFlag(Flag.FORCE_SYNCHRONOUS))
          return true;

Modified: trunk/core/src/main/java/org/infinispan/marshall/Ids.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/marshall/Ids.java	2010-09-15 16:19:59 UTC (rev 2385)
+++ trunk/core/src/main/java/org/infinispan/marshall/Ids.java	2010-09-15 19:09:38 UTC (rev 2386)
@@ -83,39 +83,38 @@
    static final byte INVALIDATE_L1_COMMAND = 35;
    static final byte LOCK_CONTROL_COMMAND = 36;
    static final byte EVICT_COMMAND = 37;
-
    // others
+
    static final byte GLOBAL_TRANSACTION = 38;
    static final byte JGROUPS_ADDRESS = 39;
    static final byte MARSHALLED_VALUE = 40;
    static final byte TRANSACTION_LOG_ENTRY = 41;
    static final byte BUCKET = 42;
    static final byte DEADLOCK_DETECTING_GLOBAL_TRANSACTION = 43;
-
    /**
     * ids for infinispan tree classes *
     */
 
    static final byte NODE_KEY = 44;
-   static final byte FQN = 45;
 
+   static final byte FQN = 45;
    static final byte ATOMIC_HASH_MAP_DELTA = 46;
+
    static final byte ATOMIC_PUT_OPERATION = 47;
    static final byte ATOMIC_REMOVE_OPERATION = 48;
    static final byte ATOMIC_CLEAR_OPERATION = 49;
-
    static final byte REHASH_CONTROL_COMMAND = 50;
+
    static final byte DEFAULT_CONSISTENT_HASH = 51;
    static final byte UNION_CONSISTENT_HASH = 52;
    static final byte JOIN_COMPLETE_COMMAND = 53;
-
    /*
     * ids for server modules
     */
+
    static final byte SERVER_CACHE_VALUE = 55;
    static final byte MEMCACHED_CACHE_VALUE = 56;
    static final byte BYTE_ARRAY_KEY = 57;
    static final byte TOPOLOGY_ADDRESS = 58;
    static final byte TOPOLOGY_VIEW = 59;
-
 }

Modified: trunk/core/src/main/java/org/infinispan/marshall/jboss/ConstantObjectTable.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/marshall/jboss/ConstantObjectTable.java	2010-09-15 16:19:59 UTC (rev 2385)
+++ trunk/core/src/main/java/org/infinispan/marshall/jboss/ConstantObjectTable.java	2010-09-15 19:09:38 UTC (rev 2386)
@@ -73,7 +73,7 @@
 import org.infinispan.remoting.responses.UnsuccessfulResponse;
 import org.infinispan.remoting.responses.UnsureResponse;
 import org.infinispan.remoting.transport.jgroups.JGroupsAddress;
-import org.infinispan.transaction.xa.DeadlockDetectingGlobalTransaction;
+import org.infinispan.transaction.xa.DldGlobalTransaction;
 import org.infinispan.transaction.xa.GlobalTransaction;
 import org.infinispan.util.ByteArrayKey;
 import org.infinispan.util.FastCopyHashMap;
@@ -119,7 +119,7 @@
       JDK_EXTERNALIZERS.put("java.util.Collections$SingletonList", SingletonListExternalizer.class.getName());
 
       MARSHALLABLES.add(GlobalTransaction.class.getName());
-      MARSHALLABLES.add(DeadlockDetectingGlobalTransaction.class.getName());
+      MARSHALLABLES.add(DldGlobalTransaction.class.getName());
       MARSHALLABLES.add(JGroupsAddress.class.getName());
       MARSHALLABLES.add("org.infinispan.util.Immutables$ImmutableMapWrapper");
       MARSHALLABLES.add(MarshalledValue.class.getName());

Modified: trunk/core/src/main/java/org/infinispan/remoting/InboundInvocationHandlerImpl.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/remoting/InboundInvocationHandlerImpl.java	2010-09-15 16:19:59 UTC (rev 2385)
+++ trunk/core/src/main/java/org/infinispan/remoting/InboundInvocationHandlerImpl.java	2010-09-15 19:09:38 UTC (rev 2386)
@@ -86,7 +86,7 @@
       CommandsFactory commandsFactory = cr.getLocalComponent(CommandsFactory.class);
 
       // initialize this command with components specific to the intended cache instance
-      commandsFactory.initializeReplicableCommand(cmd);
+      commandsFactory.initializeReplicableCommand(cmd, true);
 
       try {
          log.trace("Calling perform() on {0}", cmd);

Modified: trunk/core/src/main/java/org/infinispan/statetransfer/StateTransferManagerImpl.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/statetransfer/StateTransferManagerImpl.java	2010-09-15 16:19:59 UTC (rev 2385)
+++ trunk/core/src/main/java/org/infinispan/statetransfer/StateTransferManagerImpl.java	2010-09-15 19:09:38 UTC (rev 2386)
@@ -232,7 +232,7 @@
          WriteCommand[] mods = logEntry.getModifications();
          if (trace) log.trace("Mods = {0}", Arrays.toString(mods));
          for (WriteCommand mod : mods) {
-            commandsFactory.initializeReplicableCommand(mod);
+            commandsFactory.initializeReplicableCommand(mod, false);
             ctx.setFlags(CACHE_MODE_LOCAL, Flag.SKIP_CACHE_STATUS_CHECK);
             interceptorChain.invoke(ctx, mod);
          }
@@ -265,7 +265,7 @@
 
             if (!transactionLog.hasPendingPrepare(command)) {
                if (trace) log.trace("Applying pending prepare {0}", command);
-               commandsFactory.initializeReplicableCommand(command);
+               commandsFactory.initializeReplicableCommand(command, false);
                RemoteTxInvocationContext ctx = invocationContextContainer.createRemoteTxInvocationContext();
                RemoteTransaction transaction = txTable.createRemoteTransaction(command.getGlobalTransaction(), command.getModifications());
                ctx.setRemoteTransaction(transaction);

Deleted: trunk/core/src/main/java/org/infinispan/transaction/xa/DeadlockDetectingGlobalTransaction.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/transaction/xa/DeadlockDetectingGlobalTransaction.java	2010-09-15 16:19:59 UTC (rev 2385)
+++ trunk/core/src/main/java/org/infinispan/transaction/xa/DeadlockDetectingGlobalTransaction.java	2010-09-15 19:09:38 UTC (rev 2386)
@@ -1,191 +0,0 @@
-package org.infinispan.transaction.xa;
-
-import org.infinispan.marshall.Ids;
-import org.infinispan.marshall.Marshallable;
-import org.infinispan.remoting.transport.Address;
-import org.infinispan.util.logging.Log;
-import org.infinispan.util.logging.LogFactory;
-
-import java.io.IOException;
-import java.io.ObjectInput;
-import java.io.ObjectOutput;
-import java.util.Collections;
-import java.util.Set;
-
-/**
- * This class is used when deadlock detection is enabled.
- *
- * @author Mircea.Markus at jboss.com
- */
- at Marshallable(externalizer = DeadlockDetectingGlobalTransaction.Externalizer.class, id = Ids.DEADLOCK_DETECTING_GLOBAL_TRANSACTION)
-public class DeadlockDetectingGlobalTransaction extends GlobalTransaction {
-
-   private static final Log log = LogFactory.getLog(DeadlockDetectingGlobalTransaction.class);
-
-   public static final boolean trace = log.isTraceEnabled();
-
-   private Set<Address> replicatingTo = Collections.EMPTY_SET;
-
-   private volatile transient Thread processingThread;
-
-   private volatile long coinToss;
-
-   private volatile boolean isMarkedForRollback;
-
-   private transient volatile Object lockIntention;
-
-
-   public DeadlockDetectingGlobalTransaction() {
-   }
-
-   DeadlockDetectingGlobalTransaction(Address addr, boolean remote) {
-      super(addr, remote);
-   }
-
-   DeadlockDetectingGlobalTransaction(boolean remote) {
-      super(null, remote);
-   }
-
-   /**
-    * Is this global transaction replicating to the given address?
-    */
-   public boolean isReplicatingTo(Address address) {
-      if (this.replicatingTo == null) {
-         return true;
-      } else {
-         return this.replicatingTo.contains(address);
-      }
-   }
-
-   /**
-    * On a node, this will set the thread that handles replicatin on the given node.
-    */
-   public void setProcessingThread(Thread replicationThread) {
-      if (trace) log.trace("Setting thread " +  Thread.currentThread() + "on tx ["  + this + "]");
-      this.processingThread = replicationThread;
-   }
-
-   /**
-    * Tries to interrupt the processing thread.
-    */
-   public synchronized void interruptProcessingThread() {
-      if (isMarkedForRollback) {
-         if (trace) log.trace("Not interrupting as tx is marked for rollback");
-         return;
-      }
-      if (processingThread == null) {
-         if(trace) log.trace("Processing thread is null, nothing to interrupt");
-         return;
-      }
-      if (trace) {
-         StackTraceElement[] stackTraceElements = processingThread.getStackTrace();
-         StringBuilder builder = new StringBuilder();
-         for (StackTraceElement stackTraceElement : stackTraceElements) {
-            builder.append("            ").append(stackTraceElement).append('\n');
-         }
-         log.trace("About to interrupt thread: " + processingThread + ". Thread's stack trace is: \n" + builder.toString());
-      }
-      this.processingThread.interrupt();
-   }
-
-   /**
-    * Sets the set og <b>Address</b> objects this node is replicating to.
-    */
-   public void setReplicatingTo(Set<Address> targets) {
-      this.replicatingTo = targets;
-   }
-
-   /**
-    * Based on the coin toss, determine whether this tx will continue working or this thread will be stopped.  
-    */
-   public boolean thisWillInterrupt(DeadlockDetectingGlobalTransaction globalTransaction) {
-      return this.coinToss > globalTransaction.coinToss;
-   }
-
-   /**
-    * Sets the reandom number that defines the coin toss.
-    */
-   public void setCoinToss(long coinToss) {
-      this.coinToss = coinToss;
-   }
-
-   public long getCoinToss() {
-      return coinToss;
-   }
-
-   @Override
-   public boolean equals(Object o) {
-      if (this == o) return true;
-      if (!(o instanceof DeadlockDetectingGlobalTransaction)) return false;
-      if (!super.equals(o)) return false;
-
-      DeadlockDetectingGlobalTransaction that = (DeadlockDetectingGlobalTransaction) o;
-
-      if (coinToss != that.coinToss) return false;
-      if (replicatingTo != null ? !replicatingTo.equals(that.replicatingTo) : that.replicatingTo != null) return false;
-
-      return true;
-   }
-
-   @Override
-   public int hashCode() {
-      int result = super.hashCode();
-      result = 31 * result + (replicatingTo != null ? replicatingTo.hashCode() : 0);
-      result = 31 * result + (int) (coinToss ^ (coinToss >>> 32));
-      return result;
-   }
-
-   @Override
-   public String toString() {
-      return "DeadlockDetectingGlobalTransaction{" +
-            "replicatingTo=" + replicatingTo +
-            ", replicationThread=" + processingThread +
-            ", coinToss=" + coinToss +
-            "} " + super.toString();
-   }
-
-   /**
-    * Once marked for rollback, the call to {@link #interruptProcessingThread()} will be ignored.
-    */
-   public synchronized boolean isMarkedForRollback() {
-      return isMarkedForRollback;
-   }
-
-   public synchronized void setMarkedForRollback(boolean markedForRollback) {
-      isMarkedForRollback = markedForRollback;
-   }
-
-   /**
-    * Returns the key this transaction intends to lock. 
-    */
-   public Object getLockIntention() {
-      return lockIntention;
-   }
-
-   /**
-    * Sets the lock this transaction intends to lock.
-    */
-   public void setLockIntention(Object lockIntention) {
-      this.lockIntention = lockIntention;
-   }
-
-   public static class Externalizer extends GlobalTransaction.Externalizer {
-      public Externalizer() {
-         gtxFactory = new GlobalTransactionFactory(true);
-      }
-
-      @Override
-      public void writeObject(ObjectOutput output, Object subject) throws IOException {
-         super.writeObject(output, subject);
-         DeadlockDetectingGlobalTransaction ddGt = (DeadlockDetectingGlobalTransaction) subject;
-         output.writeLong(ddGt.getCoinToss());
-      }
-
-      @Override
-      public Object readObject(ObjectInput input) throws IOException, ClassNotFoundException {
-         DeadlockDetectingGlobalTransaction ddGt = (DeadlockDetectingGlobalTransaction) super.readObject(input);
-         ddGt.setCoinToss(input.readLong());
-         return ddGt;
-      }
-   }
-}

Copied: trunk/core/src/main/java/org/infinispan/transaction/xa/DldGlobalTransaction.java (from rev 2385, branches/4.2.x/core/src/main/java/org/infinispan/transaction/xa/DldGlobalTransaction.java)
===================================================================
--- trunk/core/src/main/java/org/infinispan/transaction/xa/DldGlobalTransaction.java	                        (rev 0)
+++ trunk/core/src/main/java/org/infinispan/transaction/xa/DldGlobalTransaction.java	2010-09-15 19:09:38 UTC (rev 2386)
@@ -0,0 +1,175 @@
+package org.infinispan.transaction.xa;
+
+import org.infinispan.marshall.Ids;
+import org.infinispan.marshall.Marshallable;
+import org.infinispan.remoting.transport.Address;
+import org.infinispan.util.logging.Log;
+import org.infinispan.util.logging.LogFactory;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.util.Collections;
+import java.util.Set;
+
+/**
+ * This class is used when deadlock detection is enabled.
+ *
+ * @author Mircea.Markus at jboss.com
+ */
+ at Marshallable(externalizer = DldGlobalTransaction.Externalizer.class, id = Ids.DEADLOCK_DETECTING_GLOBAL_TRANSACTION)
+public class DldGlobalTransaction extends GlobalTransaction {
+
+   private static Log log = LogFactory.getLog(DldGlobalTransaction.class);
+
+   public static final boolean trace = log.isTraceEnabled();
+
+   private volatile long coinToss;
+
+   private volatile boolean isMarkedForRollback;
+
+   private transient volatile Object localLockIntention;
+
+   protected volatile Set<Object> remoteLockIntention = Collections.EMPTY_SET;
+
+   private volatile Set<Object> locksAtOrigin = Collections.EMPTY_SET;
+
+   public DldGlobalTransaction() {
+   }
+
+   DldGlobalTransaction(Address addr, boolean remote) {
+      super(addr, remote);
+   }
+
+
+   /**
+    * Sets the reandom number that defines the coin toss.
+    */
+   public void setCoinToss(long coinToss) {
+      this.coinToss = coinToss;
+   }
+
+   public long getCoinToss() {
+      return coinToss;
+   }
+
+   @Override
+   public boolean equals(Object o) {
+      if (this == o) return true;
+      if (!(o instanceof DldGlobalTransaction)) return false;
+      if (!super.equals(o)) return false;
+
+      DldGlobalTransaction that = (DldGlobalTransaction) o;
+
+      if (coinToss != that.coinToss) return false;
+      return true;
+   }
+
+   @Override
+   public int hashCode() {
+      int result = super.hashCode();
+      result = 31 * result + (int) (coinToss ^ (coinToss >>> 32));
+      return result;
+   }
+
+   @Override
+   public String toString() {
+      return "DldGlobalTransaction{" +
+            "coinToss=" + coinToss +
+            ", isMarkedForRollback=" + isMarkedForRollback +
+            ", lockIntention=" + localLockIntention +
+            ", affectedKeys=" + remoteLockIntention +
+            ", locksAtOrigin=" + locksAtOrigin +
+            "} " + super.toString();
+   }
+
+   public synchronized boolean isMarkedForRollback() {
+      return isMarkedForRollback;
+   }
+
+   public synchronized void setMarkedForRollback(boolean markedForRollback) {
+      isMarkedForRollback = markedForRollback;
+   }
+
+   /**
+    * Returns the key this transaction intends to lock. 
+    */
+   public Object getLockIntention() {
+      return localLockIntention;
+   }
+
+   public void setLockIntention(Object lockIntention) {                                                                                                       
+      this.localLockIntention = lockIntention;
+   }
+
+   public boolean wouldLose(DldGlobalTransaction other) {
+      return this.coinToss < other.coinToss;
+   }
+
+   public boolean isAcquiringRemoteLock(Object key, Address address) {
+      boolean contains = remoteLockIntention.contains(key);
+      if (trace) log.trace("Intention check: does " + remoteLockIntention + " contain " + key + "? " + contains);
+      return contains; //this works for replication
+   }
+
+   public void setRemoteLockIntention(Set<Object> remoteLockIntention) {
+      if (trace) {
+         log.trace("Setting the remote lock intention: " + remoteLockIntention);
+      }
+      this.remoteLockIntention = remoteLockIntention;
+   }
+
+   public Set<Object> getRemoteLockIntention() {
+      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);
+      }
+
+      @Override
+      public void writeObject(ObjectOutput output, Object subject) throws IOException {
+         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: trunk/core/src/main/java/org/infinispan/transaction/xa/GlobalTransaction.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/transaction/xa/GlobalTransaction.java	2010-09-15 16:19:59 UTC (rev 2385)
+++ trunk/core/src/main/java/org/infinispan/transaction/xa/GlobalTransaction.java	2010-09-15 19:09:38 UTC (rev 2386)
@@ -106,7 +106,7 @@
    @Override
    public String toString() {
       StringBuilder sb = new StringBuilder();
-      sb.append("GlobalTransaction:<").append(addr).append(">:").append(id);
+      sb.append("GlobalTransaction:<").append(addr).append(">:").append(id).append(isRemote() ? ":remote" : ":local");
       return sb.toString();
    }
 

Modified: trunk/core/src/main/java/org/infinispan/transaction/xa/GlobalTransactionFactory.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/transaction/xa/GlobalTransactionFactory.java	2010-09-15 16:19:59 UTC (rev 2385)
+++ trunk/core/src/main/java/org/infinispan/transaction/xa/GlobalTransactionFactory.java	2010-09-15 19:09:38 UTC (rev 2386)
@@ -1,6 +1,7 @@
 package org.infinispan.transaction.xa;
 
 import org.infinispan.config.Configuration;
+import org.infinispan.distribution.DistributionManager;
 import org.infinispan.factories.annotations.Inject;
 import org.infinispan.factories.annotations.Start;
 import org.infinispan.remoting.transport.Address;
@@ -8,7 +9,7 @@
 import java.util.Random;
 
 /**
- * Factory for GlobalTransaction/DadlockDetectingGlobalTransaction.
+ * Factory for GlobalTransaction/DeadlockDetectingGlobalTransaction.
  *
  * @author Mircea.Markus at jboss.com
  */
@@ -16,6 +17,16 @@
 
    private boolean isEddEnabled = false;
 
+   private DistributionManager distributionManager;
+
+   private Configuration configuration;
+
+   @Inject
+   public void init(DistributionManager distributionManager, Configuration configuration) {
+      this.distributionManager = distributionManager;
+      this.configuration = configuration;
+   }
+
    /** this class is internally synchronized, so it can be shared between instances */
    private final Random rnd = new Random();
 
@@ -43,7 +54,7 @@
 
    public GlobalTransaction instantiateGlobalTransaction() {
       if (isEddEnabled) {
-         return new DeadlockDetectingGlobalTransaction();
+         return new DldGlobalTransaction();
       } else {
          return new GlobalTransaction();
       }
@@ -52,13 +63,13 @@
    public GlobalTransaction newGlobalTransaction(Address addr, boolean remote) {
       GlobalTransaction gtx;
       if (isEddEnabled) {
-         DeadlockDetectingGlobalTransaction globalTransaction = new DeadlockDetectingGlobalTransaction(addr, remote);
+         DldGlobalTransaction globalTransaction;
+         globalTransaction = new DldGlobalTransaction(addr, remote);
          globalTransaction.setCoinToss(generateRandomId());
          gtx = globalTransaction;
       } else {
          gtx = new GlobalTransaction(addr, remote);
       }
-
       return gtx;
    }
 }

Modified: trunk/core/src/main/java/org/infinispan/transaction/xa/RemoteTransaction.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/transaction/xa/RemoteTransaction.java	2010-09-15 16:19:59 UTC (rev 2385)
+++ trunk/core/src/main/java/org/infinispan/transaction/xa/RemoteTransaction.java	2010-09-15 19:09:38 UTC (rev 2386)
@@ -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: trunk/core/src/main/java/org/infinispan/transaction/xa/TransactionTable.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/transaction/xa/TransactionTable.java	2010-09-15 16:19:59 UTC (rev 2385)
+++ trunk/core/src/main/java/org/infinispan/transaction/xa/TransactionTable.java	2010-09-15 19:09:38 UTC (rev 2386)
@@ -23,11 +23,12 @@
 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;
 import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 import java.util.concurrent.RejectedExecutionException;
@@ -44,9 +45,9 @@
    private static final Log log = LogFactory.getLog(TransactionTable.class);
    private static boolean trace = log.isTraceEnabled();
 
-   private final Map<Transaction, TransactionXaAdapter> localTransactions = new HashMap<Transaction, TransactionXaAdapter>();
+   private final Map<Transaction, TransactionXaAdapter> localTransactions = new ConcurrentHashMap<Transaction, TransactionXaAdapter>();
 
-   private final Map<GlobalTransaction, RemoteTransaction> remoteTransactions = new HashMap<GlobalTransaction, RemoteTransaction>();
+   private final Map<GlobalTransaction, RemoteTransaction> remoteTransactions = new ConcurrentHashMap<GlobalTransaction, RemoteTransaction>();
 
    private CommandsFactory commandsFactory;
    private Configuration configuration;
@@ -82,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
@@ -89,35 +96,47 @@
          final List<Address> leavers = MembershipArithmetic.getMembersLeft(vce.getOldMembers(), vce.getNewMembers());
          if (!leavers.isEmpty()) {
             if (trace) log.trace("Saw {0} leavers - kicking off a lock breaking task", leavers.size());
-            try {
-               lockBreakingService.submit(new Runnable() {
-                  public void run() {
-                     Set<GlobalTransaction> toKill = new HashSet<GlobalTransaction>();
-                     for (GlobalTransaction gt : remoteTransactions.keySet()) {
-                        if (leavers.contains(gt.getAddress())) toKill.add(gt);
-                     }
+            cleanTxForWhichTheOwnerLeft(leavers);
+            if (configuration.isUseEagerLocking() && configuration.isEagerLockSingleNode() && configuration.getCacheMode().isDistributed()) {
+               for (TransactionXaAdapter xaAdapter : localTransactions.values()) {
+                  if (xaAdapter.hasRemoteLocksAcquired(leavers)) {
+                     xaAdapter.markForRollback();
+                  }
+               }
+            }
+         }
+      }
 
-                     if (trace)
-                        log.trace("Global transactions {0} pertain to leavers list {1} and need to be killed", toKill, leavers);
+      private void cleanTxForWhichTheOwnerLeft(final List<Address> leavers) {
+         try {
+            lockBreakingService.submit(new Runnable() {
+               public void run() {
+                  Set<GlobalTransaction> toKill = new HashSet<GlobalTransaction>();
+                  for (GlobalTransaction gt : remoteTransactions.keySet()) {
+                     if (leavers.contains(gt.getAddress())) toKill.add(gt);
+                  }
 
-                     for (GlobalTransaction gtx : toKill) {
-                        if (trace) log.trace("Killing {0}", gtx);
-                        RollbackCommand rc = new RollbackCommand(gtx);
-                        rc.init(invoker, icc, TransactionTable.this);
-                        try {
-                           rc.perform(null);
-                        } catch (Throwable e) {
-                           log.warn("Unable to roll back gtx " + gtx, e);
-                        } finally {
-                           removeRemoteTransaction(gtx);
-                        }
+                  if (trace)
+                     log.trace("Global transactions {0} pertain to leavers list {1} and need to be killed", toKill, leavers);
+
+                  for (GlobalTransaction gtx : toKill) {
+                     if (trace) log.trace("Killing {0}", gtx);
+                     RollbackCommand rc = new RollbackCommand(gtx);
+                     rc.init(invoker, icc, TransactionTable.this);
+                     try {
+                        rc.perform(null);
+                     } catch (Throwable e) {
+                        log.warn("Unable to roll back gtx " + gtx, e);
+                     } finally {
+                        removeRemoteTransaction(gtx);
                      }
                   }
-               });
-            } catch (RejectedExecutionException ree) {
-               log.debug("Unable to submit task to executor", ree);
-            }
+               }
+            });
+         } catch (RejectedExecutionException ree) {
+            log.debug("Unable to submit task to executor", ree);
          }
+
       }
    }
 

Modified: trunk/core/src/main/java/org/infinispan/transaction/xa/TransactionXaAdapter.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/transaction/xa/TransactionXaAdapter.java	2010-09-15 16:19:59 UTC (rev 2385)
+++ trunk/core/src/main/java/org/infinispan/transaction/xa/TransactionXaAdapter.java	2010-09-15 19:09:38 UTC (rev 2386)
@@ -10,6 +10,7 @@
 import org.infinispan.context.InvocationContextContainer;
 import org.infinispan.context.impl.LocalTxInvocationContext;
 import org.infinispan.interceptors.InterceptorChain;
+import org.infinispan.remoting.transport.Address;
 import org.infinispan.util.BidirectionalLinkedHashMap;
 import org.infinispan.util.BidirectionalMap;
 import org.infinispan.util.InfinispanCollections;
@@ -21,7 +22,11 @@
 import javax.transaction.xa.XAResource;
 import javax.transaction.xa.Xid;
 import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
 
 /**
  * This acts both as an local {@link org.infinispan.transaction.xa.CacheTransaction} and implementor of an {@link
@@ -50,6 +55,10 @@
    private TransactionTable txTable;
    private Transaction transaction;
 
+   private Set<Address> remoteLockedNodes;
+   private boolean isMarkedForRollback;
+
+
    public TransactionXaAdapter(GlobalTransaction globalTx, InvocationContextContainer icc, InterceptorChain invoker,
                                CommandsFactory commandsFactory, Configuration configuration, TransactionTable txTable,
                                Transaction transaction) {
@@ -71,6 +80,7 @@
    }
 
    public int prepare(Xid xid) throws XAException {
+      checkMarkedForRollback();
       if (configuration.isOnePhaseCommit()) {
          if (trace)
             log.trace("Received prepare for tx: " + xid + " . Skipping call as 1PC will be used.");
@@ -99,6 +109,7 @@
          LocalTxInvocationContext ctx = icc.createTxInvocationContext();
          ctx.setXaCache(this);
          if (configuration.isOnePhaseCommit()) {
+            checkMarkedForRollback();
             if (trace) log.trace("Doing an 1PC prepare call on the interceptor chain");
             PrepareCommand command = commandsFactory.buildPrepareCommand(globalTx, modifications, true);
             try {
@@ -243,4 +254,24 @@
             ", txTimeout=" + txTimeout +
             '}';
    }
+
+   public boolean hasRemoteLocksAcquired(List<Address> leavers) {
+      if (log.isTraceEnabled()) {
+         log.trace("My remote locks: " + remoteLockedNodes + ", leavers are:" + leavers);
+      }
+      return (remoteLockedNodes != null) && !Collections.disjoint(remoteLockedNodes, leavers);
+   }
+
+   public void locksAcquired(Collection<Address> nodes) {
+      if (remoteLockedNodes == null) remoteLockedNodes = new HashSet<Address>();
+      remoteLockedNodes.addAll(nodes);
+   }
+
+   public void markForRollback() {
+      isMarkedForRollback = true;
+   }
+
+   private void checkMarkedForRollback() throws XAException {
+      if (isMarkedForRollback) throw new XAException(XAException.XA_RBOTHER);
+   }   
 }

Modified: trunk/core/src/main/java/org/infinispan/util/concurrent/TimeoutException.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/util/concurrent/TimeoutException.java	2010-09-15 16:19:59 UTC (rev 2385)
+++ trunk/core/src/main/java/org/infinispan/util/concurrent/TimeoutException.java	2010-09-15 19:09:38 UTC (rev 2386)
@@ -29,11 +29,7 @@
  * from all members.
  *
  * @author <a href="mailto:bela at jboss.org">Bela Ban</a>.
- *         <p/>
- *         <p/>
- *         <p><b>Revisions:</b>
- *         <p/>
- *         <p>Dec 28 2002 Bela Ban: first implementation
+ * @author Mircea.Markus at jboss.com
  * @since 4.0
  */
 public class TimeoutException extends CacheException {

Modified: trunk/core/src/main/java/org/infinispan/util/concurrent/locks/DeadlockDetectedException.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/util/concurrent/locks/DeadlockDetectedException.java	2010-09-15 16:19:59 UTC (rev 2385)
+++ trunk/core/src/main/java/org/infinispan/util/concurrent/locks/DeadlockDetectedException.java	2010-09-15 19:09:38 UTC (rev 2386)
@@ -1,6 +1,7 @@
 package org.infinispan.util.concurrent.locks;
 
 import org.infinispan.CacheException;
+import org.infinispan.util.concurrent.TimeoutException;
 
 /**
  * Exception signaling detected deadlocks.

Modified: trunk/core/src/main/java/org/infinispan/util/concurrent/locks/DeadlockDetectingLockManager.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/util/concurrent/locks/DeadlockDetectingLockManager.java	2010-09-15 16:19:59 UTC (rev 2385)
+++ trunk/core/src/main/java/org/infinispan/util/concurrent/locks/DeadlockDetectingLockManager.java	2010-09-15 19:09:38 UTC (rev 2386)
@@ -1,13 +1,11 @@
 package org.infinispan.util.concurrent.locks;
 
 import org.infinispan.context.InvocationContext;
-import org.infinispan.context.impl.TxInvocationContext;
 import org.infinispan.factories.annotations.Start;
 import org.infinispan.jmx.annotations.MBean;
 import org.infinispan.jmx.annotations.ManagedAttribute;
 import org.infinispan.jmx.annotations.ManagedOperation;
-import org.infinispan.remoting.transport.Address;
-import org.infinispan.transaction.xa.DeadlockDetectingGlobalTransaction;
+import org.infinispan.transaction.xa.DldGlobalTransaction;
 import org.infinispan.util.logging.Log;
 import org.infinispan.util.logging.LogFactory;
 import org.rhq.helpers.pluginAnnotations.agent.MeasurementType;
@@ -15,10 +13,21 @@
 import org.rhq.helpers.pluginAnnotations.agent.Operation;
 
 import static java.util.concurrent.TimeUnit.MILLISECONDS;
+
 import java.util.concurrent.atomic.AtomicLong;
 
 /**
  * Lock manager in charge with processing deadlock detections.
+ * Implementation notes: if a deadlock is detected, then one of the transactions has to rollback. The transaction that
+ * rollbacks is determined by comparing the coin toss from {@link org.infinispan.transaction.xa.DldGlobalTransaction}.
+ * A thread calling {@link DeadlockDetectingLockManager#lockAndRecord(Object, org.infinispan.context.InvocationContext)}
+ * would run the deadlock detection algorithm only if all of the following take place:
+ * - the call is made in the scope of a transaction (either locally originated or remotely originated)
+ * - it cannot acquire lock on the given key and the lock owner is another transaction
+ * - when comparing coin toss, this thread would loose against the other one - so it's always the potential loser that runs DLD.
+ * If deadlock is detected then {@link #lockAndRecord(Object, org.infinispan.context.InvocationContext)} would throw an
+ * {@link org.infinispan.util.concurrent.locks.DeadlockDetectedException}. This is subsequently handled in
+ * in the interceptor chain - locsk owned by this tx are released.
  *
  * @author Mircea.Markus at jboss.com
  */
@@ -31,52 +40,49 @@
 
    protected volatile boolean exposeJmxStats;
 
-   private volatile boolean isSync;
+   private AtomicLong localTxStopped = new AtomicLong(0);
 
-   private AtomicLong detectedRemoteDeadlocks = new AtomicLong(0);
+   private AtomicLong remoteTxStopped = new AtomicLong(0);
 
-   private AtomicLong detectedLocalDeadlocks = new AtomicLong(0);
+   private AtomicLong cannotRunDld = new AtomicLong(0);
 
-   private AtomicLong locallyInterruptedTransactions = new AtomicLong(0);
-
-   private AtomicLong overlapWithNotDeadlockAwareLockOwners = new AtomicLong(0);
-
    @Start
    public void init() {
       spinDuration = configuration.getDeadlockDetectionSpinDuration();
       exposeJmxStats = configuration.isExposeJmxStatistics();
-      isSync = configuration.getCacheMode().isSynchronous();
    }
 
    public boolean lockAndRecord(Object key, InvocationContext ctx) throws InterruptedException {
       long lockTimeout = getLockAcquisitionTimeout(ctx);
       if (trace) log.trace("Attempting to lock {0} with acquisition timeout of {1} millis", key, lockTimeout);
 
+
       if (ctx.isInTxScope()) {
          if (trace) log.trace("Using early dead lock detection");
          final long start = System.currentTimeMillis();
-         long now;
-         while ((now = System.currentTimeMillis()) < (start + lockTimeout)) {
+         DldGlobalTransaction thisTx = (DldGlobalTransaction) ctx.getLockOwner();
+         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.setLockIntention(null); //clear lock intention
                if (trace) log.trace("successfully acquired lock on " + key + ", returning ...");
                return true;
             } else {
-               if (trace)
-                  log.trace("Could not acquire lock on '" + key + "' as it is locked by '" + getOwner(key) + "', check for dead locks");
                Object owner = getOwner(key);
-               if (!(owner instanceof DeadlockDetectingGlobalTransaction)) {
-                  if (trace)
-                     log.trace("Owner is not instance of DeadlockDetectingGlobalTransaction: " + owner + ", continuing ...");
-                  if (exposeJmxStats) overlapWithNotDeadlockAwareLockOwners.incrementAndGet();
-                  continue; //try to acquire lock again, for the rest of the time
+               if (!(owner instanceof DldGlobalTransaction)) {
+                  if (trace) log.trace("Not running DLD as lock owner( " + owner + ") is not a transaction");
+                  cannotRunDld.incrementAndGet();
+                  continue;
                }
-               DeadlockDetectingGlobalTransaction lockOwnerTx = (DeadlockDetectingGlobalTransaction) owner;
-               if (isSync && !ctx.isOriginLocal() && !lockOwnerTx.isRemote()) {
-                  return remoteVsRemoteDld(key, ctx, lockTimeout, start, now, lockOwnerTx);
+               DldGlobalTransaction lockOwnerTx = (DldGlobalTransaction) owner;
+               if (isDeadlockAndIAmLoosing(lockOwnerTx, thisTx, key)) {
+                  updateStats(thisTx);
+                  String message = "Deadlock found and we " + thisTx + " shall not continue. Other tx is " + lockOwnerTx;
+                  if (trace) log.trace(message);
+                  throw new DeadlockDetectedException(message);
                }
-               if ((ctx.isOriginLocal() && !lockOwnerTx.isRemote()) || (!isSync && !ctx.isOriginLocal() && !lockOwnerTx.isRemote())) {
-                  localVsLocalDld(ctx, lockOwnerTx);
-               }
             }
          }
       } else {
@@ -88,100 +94,95 @@
       return false;
    }
 
-   private void localVsLocalDld(InvocationContext ctx, DeadlockDetectingGlobalTransaction lockOwnerTx) {
-      if (trace) log.trace("Looking for local vs local deadlocks");
-      DeadlockDetectingGlobalTransaction thisThreadsTx = (DeadlockDetectingGlobalTransaction) ctx.getLockOwner();
-      boolean weOwnLock = ownsLock(lockOwnerTx.getLockIntention(), thisThreadsTx);
-      if (trace) {
-         log.trace("Other owner's intention is " + lockOwnerTx.getLockIntention() + ". Do we(" + thisThreadsTx + ") own lock for it? " + weOwnLock + ". Lock owner is " + getOwner(lockOwnerTx.getLockIntention()));
+   private boolean isDeadlockAndIAmLoosing(DldGlobalTransaction lockOwnerTx, DldGlobalTransaction thisTx, Object key) {
+      //run the lose check first as it is cheaper
+      boolean wouldWeLoose = thisTx.wouldLose(lockOwnerTx);
+      if (!wouldWeLoose) {
+         if (trace) log.trace("We (" + thisTx + ") wouldn't lose against the other(" + lockOwnerTx + ") transaction, so no point running rest of DLD");
+         return false;
       }
-      if (weOwnLock) {
-         boolean iShouldInterrupt = thisThreadsTx.thisWillInterrupt(lockOwnerTx);
-         if (trace)
-            log.trace("deadlock situation detected. Shall I interrupt?" + iShouldInterrupt );
-         if (iShouldInterrupt) {
-            lockOwnerTx.interruptProcessingThread();
-            if (exposeJmxStats) detectedLocalDeadlocks.incrementAndGet();
-         }
-      }
+      //do we have lock on what other tx intends to acquire?
+      return ownsLocalIntention(thisTx, lockOwnerTx.getLockIntention()) || ownsRemoteIntention(lockOwnerTx, thisTx, key);
    }
 
-   private boolean remoteVsRemoteDld(Object key, InvocationContext ctx, long lockTimeout, long start, long now, DeadlockDetectingGlobalTransaction lockOwnerTx) throws InterruptedException {
-      TxInvocationContext remoteTxContext = (TxInvocationContext) ctx;
-      Address origin = remoteTxContext.getGlobalTransaction().getAddress();
-      DeadlockDetectingGlobalTransaction remoteGlobalTransaction = (DeadlockDetectingGlobalTransaction) ctx.getLockOwner();
-      boolean thisShouldInterrupt = remoteGlobalTransaction.thisWillInterrupt(lockOwnerTx);
-      if (trace) log.trace("Should I interrupt other transaction ? " + thisShouldInterrupt);
-      boolean isDeadLock = (configuration.getCacheMode().isReplicated() || lockOwnerTx.isReplicatingTo(origin)) && !lockOwnerTx.isRemote();
-      if (thisShouldInterrupt && isDeadLock) {
-         lockOwnerTx.interruptProcessingThread();
-         if (exposeJmxStats) {
-            detectedRemoteDeadlocks.incrementAndGet();
-            locallyInterruptedTransactions.incrementAndGet();
+   /**
+    * This happens with two nodes replicating same tx at the same time.
+    */
+   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. 
+         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;
          }
-         return lockForTheRemainingTime(key, lockTimeout, start, now);
-      } else if (!isDeadLock) {
-         return lockForTheRemainingTime(key, lockTimeout, start, now);
       } else {
-         if (trace)
-            log.trace("Not trying to acquire lock anymore, as we're in deadlock and this will be rollback at origin");
-         if (exposeJmxStats) {
-            detectedRemoteDeadlocks.incrementAndGet();
-         }
-         remoteGlobalTransaction.setMarkedForRollback(true);
-         throw new DeadlockDetectedException("Deadlock situation detected on tx: " + remoteTxContext.getLockOwner());
+         if (trace) log.trace("Lock owner is remote: " + lockOwnerTx);
       }
+      return false;
    }
 
-   private boolean lockForTheRemainingTime(Object key, long lockTimeout, long start, long now) throws InterruptedException {
-      long remainingLockingTime = (start + lockTimeout) - now;
-      if (remainingLockingTime < 0)
-         throw new IllegalStateException("No remaining time!!! The outer while condition MUST make sure this always stands true!");
-      if (trace) log.trace("trying to lock for the remaining time: " + remainingLockingTime + " millis ");
-      return lockContainer.acquireLock(key, remainingLockingTime, MILLISECONDS) != null;
+   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;
    }
 
    public void setExposeJmxStats(boolean exposeJmxStats) {
       this.exposeJmxStats = exposeJmxStats;
    }
 
-   @ManagedAttribute(description = "Number of situtations when we try to determine a deadlock and the other lock owner is e.g. a local tx. In this scenario we cannot run the deadlock detection mechanism")
-   @Metric(displayName = "Number of unsolvable deadlock situations", measurementType = MeasurementType.TRENDSUP)
-   public long getOverlapWithNotDeadlockAwareLockOwners() {
-      return overlapWithNotDeadlockAwareLockOwners.get();
+
+   @ManagedAttribute (description = "Total number of local detected deadlocks")
+   @Metric(displayName = "Number of total detected deadlocks", measurementType = MeasurementType.TRENDSUP)
+   public long getTotalNumberOfDetectedDeadlocks() {
+      return localTxStopped.get() + remoteTxStopped.get();
    }
 
-   @ManagedAttribute(description = "Number of locally originated transactions that were interrupted as a deadlock situation was detected")
-   @Metric(displayName = "Number of interrupted local transactions", measurementType = MeasurementType.TRENDSUP)
-   public long getLocallyInterruptedTransactions() {
-      return locallyInterruptedTransactions.get();
+   @ManagedOperation(description = "Resets statistics gathered by this component")
+   @Operation(displayName = "Reset statistics")
+   public void resetStatistics() {
+      localTxStopped.set(0);
+      remoteTxStopped.set(0);
+      cannotRunDld.set(0); 
    }
 
-   @ManagedAttribute(description = "Number of remote deadlocks detected")
-   @Metric(displayName = "Number of detected remote deadlocks", measurementType = MeasurementType.TRENDSUP)
+   @ManagedAttribute(description = "Number of remote transaction that were roll backed due to deadlocks")
+   @Metric(displayName = "Number of remote transaction that were roll backed due to deadlocks", measurementType = MeasurementType.TRENDSUP)
    public long getDetectedRemoteDeadlocks() {
-      return detectedRemoteDeadlocks.get();
+      return remoteTxStopped.get();
    }
 
-   @ManagedAttribute (description = "Number of local detected deadlocks")
-   @Metric(displayName = "Number of detected local deadlocks", measurementType = MeasurementType.TRENDSUP)
+   @ManagedAttribute (description = "Number of local transaction that were roll backed due to deadlocks")
+   @Metric(displayName = "Number of local transaction that were roll backed due to deadlocks", measurementType = MeasurementType.TRENDSUP)
    public long getDetectedLocalDeadlocks() {
-      return detectedLocalDeadlocks.get();
+      return localTxStopped.get();
    }
 
-   @ManagedAttribute (description = "Total number of local detected deadlocks")
-   @Metric(displayName = "Number of total detected deadlocks", measurementType = MeasurementType.TRENDSUP)
-   public long getTotalNumberOfDetectedDeadlocks() {
-      return detectedRemoteDeadlocks.get() + detectedLocalDeadlocks.get();
+   @ManagedAttribute(description = "Number of situtations when we try to determine a deadlock and the other lock owner is NOT a transaction. In this scenario we cannot run the deadlock detection mechanism")
+   @Metric(displayName = "Number of unsolvable deadlock situations", measurementType = MeasurementType.TRENDSUP)
+   public long getOverlapWithNotDeadlockAwareLockOwners() {
+      return cannotRunDld.get();
    }
 
-   @ManagedOperation(description = "Resets statistics gathered by this component")
-   @Operation(displayName = "Reset statistics")
-   public void resetStatistics() {
-      overlapWithNotDeadlockAwareLockOwners.set(0);
-      locallyInterruptedTransactions.set(0);
-      detectedRemoteDeadlocks.set(0);
-      detectedLocalDeadlocks.set(0);
+
+
+   private void updateStats(DldGlobalTransaction tx) {
+      if (exposeJmxStats) {
+         if (tx.isRemote())
+            remoteTxStopped.incrementAndGet();
+         else
+            localTxStopped.incrementAndGet();
+      }
    }
 
+
+   @ManagedAttribute(description = "Number of locally originated transactions that were interrupted as a deadlock situation was detected")
+   @Metric(displayName = "Number of interrupted local transactions", measurementType = MeasurementType.TRENDSUP)
+   @Deprecated
+   public long getLocallyInterruptedTransactions() {
+      return -1;
+   }
+
 }

Modified: trunk/core/src/main/resources/config-samples/all.xml
===================================================================
--- trunk/core/src/main/resources/config-samples/all.xml	2010-09-15 16:19:59 UTC (rev 2385)
+++ trunk/core/src/main/resources/config-samples/all.xml	2010-09-15 19:09:38 UTC (rev 2386)
@@ -81,7 +81,7 @@
             transactionManagerLookupClass="org.infinispan.transaction.lookup.GenericTransactionManagerLookup"
             syncRollbackPhase="false"
             syncCommitPhase="false"
-            useEagerLocking="false"/>
+            useEagerLocking="true" eagerLockSingleNode="true"/>
 
       <!--
       Used to register JMX statistics in any available MBean server

Modified: trunk/core/src/test/java/org/infinispan/api/mvcc/LockTestBase.java
===================================================================
--- trunk/core/src/test/java/org/infinispan/api/mvcc/LockTestBase.java	2010-09-15 16:19:59 UTC (rev 2385)
+++ trunk/core/src/test/java/org/infinispan/api/mvcc/LockTestBase.java	2010-09-15 19:09:38 UTC (rev 2386)
@@ -270,7 +270,7 @@
       catch (TimeoutException expected) {
 //         expected.printStackTrace();  // for debugging
       }
-      tm.commit();
+      tm.rollback();
       tm.resume(t1);
       tm.commit();
       assertNoLocks();

Modified: trunk/core/src/test/java/org/infinispan/config/parsing/XmlFileParsingTest.java
===================================================================
--- trunk/core/src/test/java/org/infinispan/config/parsing/XmlFileParsingTest.java	2010-09-15 16:19:59 UTC (rev 2385)
+++ trunk/core/src/test/java/org/infinispan/config/parsing/XmlFileParsingTest.java	2010-09-15 19:09:38 UTC (rev 2386)
@@ -18,6 +18,8 @@
 import org.testng.annotations.Test;
 
 import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileInputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.util.Map;
@@ -160,6 +162,7 @@
 
       assert c.getTransactionManagerLookupClass().equals("org.infinispan.transaction.lookup.GenericTransactionManagerLookup");
       assert c.isUseEagerLocking();
+      assert c.isEagerLockSingleNode();
       assert !c.isSyncRollbackPhase();
 
       c = namedCaches.get("syncRepl");

Deleted: trunk/core/src/test/java/org/infinispan/distribution/DeadlockDetectionDistributionTest.java
===================================================================
--- trunk/core/src/test/java/org/infinispan/distribution/DeadlockDetectionDistributionTest.java	2010-09-15 16:19:59 UTC (rev 2385)
+++ trunk/core/src/test/java/org/infinispan/distribution/DeadlockDetectionDistributionTest.java	2010-09-15 19:09:38 UTC (rev 2386)
@@ -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", enabled = false, 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!!!
-   }
-}

Modified: trunk/core/src/test/java/org/infinispan/loaders/dummy/DummyInMemoryCacheStore.java
===================================================================
--- trunk/core/src/test/java/org/infinispan/loaders/dummy/DummyInMemoryCacheStore.java	2010-09-15 16:19:59 UTC (rev 2385)
+++ trunk/core/src/test/java/org/infinispan/loaders/dummy/DummyInMemoryCacheStore.java	2010-09-15 19:09:38 UTC (rev 2386)
@@ -31,6 +31,7 @@
    public void store(InternalCacheEntry ed) {
       if (ed != null) {
          if (trace) log.trace("Store {0} in dummy map store@{1}", ed, Integer.toHexString(System.identityHashCode(store)));
+         config.failIfNeeded(ed.getKey());
          store.put(ed.getKey(), ed);
       }
    }
@@ -158,6 +159,7 @@
       boolean debug;
       String store = "__DEFAULT_STORE__";
       boolean cleanBetweenRestarts = true;
+      private Object failKey;
 
       public Cfg() {
          setCacheLoaderClassName(DummyInMemoryCacheStore.class.getName());
@@ -197,5 +199,13 @@
       public boolean isCleanBetweenRestarts() {
          return cleanBetweenRestarts;
       }
+
+      public void setFailKey(Object failKey) {
+         this.failKey = failKey;
+      }
+
+      public void failIfNeeded(Object key) {
+         if(failKey != null && failKey.equals(key)) throw new RuntimeException("Induced failure on key:" + key);
+      }
    }
 }

Deleted: trunk/core/src/test/java/org/infinispan/lock/EagerLockingDisabledTest.java
===================================================================
--- trunk/core/src/test/java/org/infinispan/lock/EagerLockingDisabledTest.java	2010-09-15 16:19:59 UTC (rev 2385)
+++ trunk/core/src/test/java/org/infinispan/lock/EagerLockingDisabledTest.java	2010-09-15 19:09:38 UTC (rev 2386)
@@ -1,50 +0,0 @@
-package org.infinispan.lock;
-
-import org.infinispan.Cache;
-import org.infinispan.config.Configuration;
-import org.infinispan.config.ConfigurationException;
-import org.infinispan.manager.EmbeddedCacheManager;
-import org.infinispan.test.TestingUtil;
-import org.infinispan.test.fwk.TestCacheManagerFactory;
-import org.testng.annotations.Test;
-
-/**
- * Tester for https://jira.jboss.org/browse/ISPN-596
- *
- * @author Mircea.Markus at jboss.com
- * @since 4.1
- */
- at Test (groups = "functional", testName = "lock.EagerLockingDisabledTest")
-public class EagerLockingDisabledTest {
-
-   public void testImplicitEagerLockingAndDld() {
-      Configuration configuration = TestCacheManagerFactory.getDefaultConfiguration(false);
-      configuration.setEnableDeadlockDetection(true);
-      configuration.setUseEagerLocking(true);
-      EmbeddedCacheManager cm = null;
-      try {
-         cm = TestCacheManagerFactory.createCacheManager(configuration);
-         assert false : "expecting configuration exception";
-      } catch (ConfigurationException ce) {
-         //expected
-      }
-      finally {
-         TestingUtil.killCacheManagers(cm);
-      }
-   }
-
-   public void testExplicitEagerLockingAndDld() {
-      Configuration configuration = TestCacheManagerFactory.getDefaultConfiguration(false);
-      configuration.setEnableDeadlockDetection(true);
-      EmbeddedCacheManager cm = TestCacheManagerFactory.createCacheManager(configuration);
-      Cache c = cm.getCache();
-      try {
-         c.getAdvancedCache().lock("k");
-      } catch (ConfigurationException ce) {
-         //expected
-      }
-      finally {
-         TestingUtil.killCacheManagers(cm);
-      }
-   }
-}

Copied: trunk/core/src/test/java/org/infinispan/lock/EagerLockingSingleLockTest.java (from rev 2385, branches/4.2.x/core/src/test/java/org/infinispan/lock/EagerLockingSingleLockTest.java)
===================================================================
--- trunk/core/src/test/java/org/infinispan/lock/EagerLockingSingleLockTest.java	                        (rev 0)
+++ trunk/core/src/test/java/org/infinispan/lock/EagerLockingSingleLockTest.java	2010-09-15 19:09:38 UTC (rev 2386)
@@ -0,0 +1,164 @@
+package org.infinispan.lock;
+
+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.test.MultipleCacheManagersTest;
+import org.infinispan.test.TestingUtil;
+import org.infinispan.util.concurrent.TimeoutException;
+import org.infinispan.util.logging.Log;
+import org.infinispan.util.logging.LogFactory;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.Test;
+
+import javax.transaction.RollbackException;
+import javax.transaction.Status;
+import javax.transaction.Transaction;
+import javax.transaction.TransactionManager;
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
+import static org.testng.Assert.assertEquals;
+
+/**
+ * Tester for https://jira.jboss.org/browse/ISPN-615.
+ *
+ * @author Mircea.Markus at jboss.com
+ * @since 4.2
+ */
+ at Test(groups = "functional", testName = "lock.EagerLockingSingleLockTest")
+public class EagerLockingSingleLockTest extends MultipleCacheManagersTest {
+   private KeyAffinityService kaf;
+   private ThreadPoolExecutor poolExecutor;
+
+   private static Log log = LogFactory.getLog(EagerLockingSingleLockTest.class);
+
+   @Override
+   protected void createCacheManagers() throws Throwable {
+      Configuration config = getDefaultClusteredConfig(Configuration.CacheMode.DIST_SYNC, true);
+      config.setEagerLockSingleNode(true);
+      config.setNumOwners(2);
+      config.setLockAcquisitionTimeout(2000);
+      config.setUseEagerLocking(true);
+      config.setL1CacheEnabled(false);
+      createClusteredCaches(4, config);
+      TestingUtil.blockUntilViewReceived(cache(0), 4, 10000);
+      BaseDistFunctionalTest.RehashWaiter.waitForInitRehashToComplete(cache(0), cache(1), cache(2), cache(3));
+      poolExecutor = new ThreadPoolExecutor(1, 1, 1000, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
+      kaf = KeyAffinityServiceFactory.newKeyAffinityService(cache(0), poolExecutor, new RndKeyGenerator(), 10, true);
+   }
+
+   @AfterClass
+   public void cleanUp() {
+      kaf.stop();
+      poolExecutor.shutdownNow();
+   }
+
+   public void testSingleLockAcquiredRemotely() throws Exception {
+      log.trace("0 -> " + address(0));
+      log.trace("1 -> " + address(1));
+      log.trace("2 -> " + address(2));
+      log.trace("3 -> " + address(3));
+
+      Object k = kaf.getKeyForAddress(address(3));
+      cache(1).put(k, "1stValue");
+      TransactionManager tm = cache(0).getAdvancedCache().getTransactionManager();
+      tm.begin();
+      cache(1).put(k, "2ndValue");
+      assert !TestingUtil.extractLockManager(cache(0)).isLocked(k);
+      assert TestingUtil.extractLockManager(cache(1)).isLocked(k);
+      assert !TestingUtil.extractLockManager(cache(2)).isLocked(k);
+      assert TestingUtil.extractLockManager(cache(3)).isLocked(k);
+
+      Transaction lockOwnerTx = tm.suspend();
+
+      //now make sure other transactions won't be able to acquire locks
+      tm.begin();
+      try {
+         cache(2).put(k, "3rdValue");
+         assert false;
+      } catch (TimeoutException e) {
+         assertEquals(tm.getStatus(), Status.STATUS_MARKED_ROLLBACK);
+      }
+      tm.rollback();
+
+      //now check that the only node that has a remote lock is cache(3)
+      assert !TestingUtil.extractLockManager(cache(0)).isLocked(k);
+      assert !TestingUtil.extractLockManager(cache(2)).isLocked(k);
+      assert TestingUtil.extractLockManager(cache(3)).isLocked(k);
+
+      tm.resume(lockOwnerTx);
+      tm.commit();
+
+      //no locks are being held now
+      assert !TestingUtil.extractLockManager(cache(0)).isLocked(k);
+      assert !TestingUtil.extractLockManager(cache(1)).isLocked(k);
+      assert !TestingUtil.extractLockManager(cache(2)).isLocked(k);
+      assert !TestingUtil.extractLockManager(cache(3)).isLocked(k);
+
+      assertEquals(cache(0).get(k), "2ndValue");
+   }
+
+   @Test(dependsOnMethods = "testSingleLockAcquiredRemotely")
+   public void testSingleLockAcquiredLocally() throws Exception {
+      Object k = kaf.getKeyForAddress(address(1));
+      cache(1).put(k, "1stValue");
+      TransactionManager tm = cache(0).getAdvancedCache().getTransactionManager();
+
+      tm.begin();
+      cache(1).put(k, "2ndValue");//this acquires a local cache only
+
+      //now check that the only node that has a remote lock is cache(3)
+      assert !TestingUtil.extractLockManager(cache(0)).isLocked(k);
+      assert TestingUtil.extractLockManager(cache(1)).isLocked(k);
+      assert !TestingUtil.extractLockManager(cache(2)).isLocked(k);
+      assert !TestingUtil.extractLockManager(cache(3)).isLocked(k);
+
+      tm.commit();
+
+      //no locks are being held now
+      assert !TestingUtil.extractLockManager(cache(0)).isLocked(k);
+      assert !TestingUtil.extractLockManager(cache(1)).isLocked(k);
+      assert !TestingUtil.extractLockManager(cache(2)).isLocked(k);
+      assert !TestingUtil.extractLockManager(cache(3)).isLocked(k);
+
+      assertEquals(cache(0).get(k), "2ndValue");
+   }
+
+   @Test(dependsOnMethods = "testSingleLockAcquiredLocally")
+   public void testLockOwnerFailure() throws Exception {
+      Object k = kaf.getKeyForAddress(address(3));
+      cache(1).put(k, "1stValue");
+      final TransactionManager tm = cache(0).getAdvancedCache().getTransactionManager();
+
+      tm.begin();
+      cache(1).put(k, "2ndValue");
+
+      //now check that the only node that has a remote lock is cache(3)
+      assert !TestingUtil.extractLockManager(cache(0)).isLocked(k);
+      assert !TestingUtil.extractLockManager(cache(2)).isLocked(k);
+      assert TestingUtil.extractLockManager(cache(3)).isLocked(k);
+
+      manager(3).stop();
+      TestingUtil.blockUntilViewReceived(cache(0), 3, 10000);
+      BaseDistFunctionalTest.RehashWaiter.waitForInitRehashToComplete(cache(0), cache(1), cache(2));
+
+      try {
+         log.trace("here it begins");
+         tm.commit();
+         assert false;
+      } catch (RollbackException re) {
+         //expected
+      }
+
+      //no locks are being held now
+      assert !TestingUtil.extractLockManager(cache(0)).isLocked(k);
+      assert !TestingUtil.extractLockManager(cache(1)).isLocked(k);
+      assert !TestingUtil.extractLockManager(cache(2)).isLocked(k);
+
+      assertEquals(cache(0).get(k), "1stValue");
+   }
+}

Modified: trunk/core/src/test/java/org/infinispan/notifications/cachelistener/CacheNotifierTest.java
===================================================================
--- trunk/core/src/test/java/org/infinispan/notifications/cachelistener/CacheNotifierTest.java	2010-09-15 16:19:59 UTC (rev 2385)
+++ trunk/core/src/test/java/org/infinispan/notifications/cachelistener/CacheNotifierTest.java	2010-09-15 19:09:38 UTC (rev 2386)
@@ -26,13 +26,14 @@
    private TransactionManager tm;
    private CacheNotifier mockNotifier;
    private CacheNotifier origNotifier;
+   private CacheContainer cm;
 
    @BeforeMethod(alwaysRun = true)
    public void setUp() throws Exception {
       Configuration c = new Configuration();
       c.setCacheMode(Configuration.CacheMode.LOCAL);
       c.setIsolationLevel(IsolationLevel.REPEATABLE_READ);
-      CacheContainer cm = TestCacheManagerFactory.createCacheManager(c, true);
+      cm = TestCacheManagerFactory.createCacheManager(c, true);
 
       cache = cm.getCache();
       tm = TestingUtil.getTransactionManager(cache);
@@ -44,6 +45,7 @@
    public void tearDown() throws Exception {
       TestingUtil.replaceComponent(cache, CacheNotifier.class, origNotifier, true);
       TestingUtil.killCaches(cache);
+      cm.stop();
    }
 
    @AfterClass

Modified: trunk/core/src/test/java/org/infinispan/statetransfer/StateTransferReplicationQueueTest.java
===================================================================
--- trunk/core/src/test/java/org/infinispan/statetransfer/StateTransferReplicationQueueTest.java	2010-09-15 16:19:59 UTC (rev 2385)
+++ trunk/core/src/test/java/org/infinispan/statetransfer/StateTransferReplicationQueueTest.java	2010-09-15 19:09:38 UTC (rev 2386)
@@ -17,13 +17,11 @@
 import java.io.ObjectOutput;
 import java.lang.reflect.Method;
 import java.util.Properties;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicBoolean;
 
 /**
- * State transfer and replication queue test veryfying that the interaction between them two works in fine.
+ * State transfer and replication queue test verifying that the interaction between them two works in fine.
  *
  * @author Galder Zamarre�o
  * @since 4.1

Modified: trunk/core/src/test/java/org/infinispan/test/AbstractInfinispanTest.java
===================================================================
--- trunk/core/src/test/java/org/infinispan/test/AbstractInfinispanTest.java	2010-09-15 16:19:59 UTC (rev 2385)
+++ trunk/core/src/test/java/org/infinispan/test/AbstractInfinispanTest.java	2010-09-15 19:09:38 UTC (rev 2386)
@@ -21,31 +21,57 @@
  */
 package org.infinispan.test;
 
+import org.testng.annotations.AfterTest;
+
 import java.lang.reflect.Field;
 import java.lang.reflect.Modifier;
 
-import org.testng.annotations.AfterTest;
+import static org.testng.Assert.assertEquals;
 
 /**
- * AbstractInfinispanTest is a superclass of all Infinispan tests. 
- * 
+ * AbstractInfinispanTest is a superclass of all Infinispan tests.
+ *
  * @author Vladimir Blagojevic
+ * @author Mircea.Markus at jboss.com
  * @since 4.0
  */
 public class AbstractInfinispanTest {
-   
-   @AfterTest(alwaysRun=true)
+
+   @AfterTest(alwaysRun = true)
    protected void nullifyInstanceFields() {
-      for(Class<?> current = this.getClass();current.getSuperclass() != null; current = current.getSuperclass()) {
+      for (Class<?> current = this.getClass(); current.getSuperclass() != null; current = current.getSuperclass()) {
          Field[] fields = current.getDeclaredFields();
-         for(Field f:fields) {
-            try {               
-               if(!Modifier.isStatic(f.getModifiers()) && !f.getDeclaringClass().isPrimitive()) {
+         for (Field f : fields) {
+            try {
+               if (!Modifier.isStatic(f.getModifiers()) && !f.getDeclaringClass().isPrimitive()) {
                   f.setAccessible(true);
                   f.set(this, null);
                }
-            } catch (Exception e) {} 
-         }         
-      }      
+            } catch (Exception e) {}
+         }
+      }
    }
+
+   public void eventually(Condition ec, long timeout) {
+      int loops = 10;
+      long sleepDuration = timeout / loops;
+      try {
+         for (int i = 0; i < loops; i++) {
+
+            if (ec.isSatisfied()) break;
+            Thread.sleep(sleepDuration);
+         }
+         assertEquals(true, ec.isSatisfied());
+      } catch (Exception e) {
+         throw new RuntimeException("Unexpected!", e);
+      }
+   }
+
+   public void eventually(Condition ec) {
+      eventually(ec, 10000);
+   }
+
+   public interface Condition {
+      public boolean isSatisfied() throws Exception;
+   }
 }

Modified: trunk/core/src/test/java/org/infinispan/test/MultipleCacheManagersTest.java
===================================================================
--- trunk/core/src/test/java/org/infinispan/test/MultipleCacheManagersTest.java	2010-09-15 16:19:59 UTC (rev 2385)
+++ trunk/core/src/test/java/org/infinispan/test/MultipleCacheManagersTest.java	2010-09-15 19:09:38 UTC (rev 2386)
@@ -4,6 +4,7 @@
 import org.infinispan.config.Configuration;
 import org.infinispan.manager.CacheContainer;
 import org.infinispan.manager.EmbeddedCacheManager;
+import org.infinispan.remoting.transport.Address;
 import org.infinispan.test.fwk.TestCacheManagerFactory;
 import org.testng.annotations.AfterClass;
 import org.testng.annotations.AfterMethod;
@@ -211,4 +212,8 @@
     * {@link #addClusterEnabledCacheManager()}
     */
    protected abstract void createCacheManagers() throws Throwable;
+
+   public Address address(int cacheIndex) {
+      return cache(cacheIndex).getAdvancedCache().getRpcManager().getAddress();
+   }
 }

Modified: trunk/core/src/test/java/org/infinispan/test/PerCacheExecutorThread.java
===================================================================
--- trunk/core/src/test/java/org/infinispan/test/PerCacheExecutorThread.java	2010-09-15 16:19:59 UTC (rev 2385)
+++ trunk/core/src/test/java/org/infinispan/test/PerCacheExecutorThread.java	2010-09-15 19:09:38 UTC (rev 2386)
@@ -4,6 +4,7 @@
 import org.infinispan.util.logging.Log;
 import org.infinispan.util.logging.LogFactory;
 
+import javax.transaction.Transaction;
 import javax.transaction.TransactionManager;
 import java.util.concurrent.ArrayBlockingQueue;
 import java.util.concurrent.BlockingQueue;
@@ -24,6 +25,7 @@
    private BlockingQueue<Object> toExecute = new ArrayBlockingQueue<Object>(1);
    private volatile Object response;
    private CountDownLatch responseLatch = new CountDownLatch(1);
+   private volatile Transaction ongoingTransaction;
 
    private volatile Object key, value;
 
@@ -75,6 +77,7 @@
                TransactionManager txManager = TestingUtil.getTransactionManager(cache);
                try {
                   txManager.begin();
+                  ongoingTransaction = txManager.getTransaction();
                   setResponse(OperationsResult.BEGGIN_TX_OK);
                } catch (Exception e) {
                   log.trace("Failure on beggining tx", e);
@@ -86,6 +89,7 @@
                TransactionManager txManager = TestingUtil.getTransactionManager(cache);
                try {
                   txManager.commit();
+                  ongoingTransaction = null;
                   setResponse(OperationsResult.COMMIT_TX_OK);
                } catch (Exception e) {
                   log.trace("Exception while committing tx", e);
@@ -210,6 +214,9 @@
     */
    public static enum OperationsResult {
       BEGGIN_TX_OK, COMMIT_TX_OK, PUT_KEY_VALUE_OK, REMOVE_KEY_OK, REPLACE_KEY_VALUE_OK, STOP_THREAD_OK
+   }
 
+   public Transaction getOngoingTransaction() {
+      return ongoingTransaction;
    }
 }

Modified: trunk/core/src/test/java/org/infinispan/test/TestingUtil.java
===================================================================
--- trunk/core/src/test/java/org/infinispan/test/TestingUtil.java	2010-09-15 16:19:59 UTC (rev 2385)
+++ trunk/core/src/test/java/org/infinispan/test/TestingUtil.java	2010-09-15 19:09:38 UTC (rev 2386)
@@ -30,6 +30,7 @@
 import org.infinispan.remoting.transport.Address;
 import org.infinispan.remoting.transport.Transport;
 import org.infinispan.remoting.transport.jgroups.JGroupsTransport;
+import org.infinispan.transaction.xa.TransactionTable;
 import org.infinispan.util.concurrent.locks.LockManager;
 import org.infinispan.util.logging.Log;
 import org.infinispan.util.logging.LogFactory;
@@ -837,4 +838,8 @@
    public static Object v(Method method) {
       return v(method, "");
    }
+
+   public static TransactionTable getTransactionTable(Cache<Object, Object> cache) {
+      return cache.getAdvancedCache().getComponentRegistry().getComponent(TransactionTable.class);
+   }
 }

Modified: trunk/core/src/test/java/org/infinispan/test/fwk/TestCacheManagerFactory.java
===================================================================
--- trunk/core/src/test/java/org/infinispan/test/fwk/TestCacheManagerFactory.java	2010-09-15 16:19:59 UTC (rev 2385)
+++ trunk/core/src/test/java/org/infinispan/test/fwk/TestCacheManagerFactory.java	2010-09-15 19:09:38 UTC (rev 2386)
@@ -16,13 +16,15 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Map;
 import java.util.Properties;
+import java.util.Set;
 import java.util.concurrent.atomic.AtomicInteger;
 
 /**
- * CacheManagers in unit tests should be created with this factory, in order to avoid resource clashes.
- * See http://community.jboss.org/wiki/ParallelTestSuite for more details.
+ * CacheManagers in unit tests should be created with this factory, in order to avoid resource clashes. See
+ * http://community.jboss.org/wiki/ParallelTestSuite for more details.
  *
  * @author Mircea.Markus at jboss.com
  * @author Galder Zamarreño
@@ -51,9 +53,9 @@
 
    public static EmbeddedCacheManager fromXml(String xmlFile, boolean allowDupeDomains) throws IOException {
       InfinispanConfiguration parser = InfinispanConfiguration.newInfinispanConfiguration(
-               xmlFile,
-               InfinispanConfiguration.resolveSchemaPath(),
-               new ConfigurationValidatingVisitor());
+            xmlFile,
+            InfinispanConfiguration.resolveSchemaPath(),
+            new ConfigurationValidatingVisitor());
       return fromConfigFileParser(parser, allowDupeDomains);
    }
 
@@ -67,8 +69,8 @@
 
    public static EmbeddedCacheManager fromStream(InputStream is, boolean allowDupeDomains) throws IOException {
       InfinispanConfiguration parser = InfinispanConfiguration.newInfinispanConfiguration(
-               is, InfinispanConfiguration.findSchemaInputStream(),
-               new ConfigurationValidatingVisitor());
+            is, InfinispanConfiguration.findSchemaInputStream(),
+            new ConfigurationValidatingVisitor());
       return fromConfigFileParser(parser, allowDupeDomains);
    }
 
@@ -81,7 +83,7 @@
       minimizeThreads(gc);
 
       EmbeddedCacheManager cm = newDefaultCacheManager(true, gc, c, false);
-      for (Map.Entry<String, Configuration> e: named.entrySet()) cm.defineConfiguration(e.getKey(), e.getValue());
+      for (Map.Entry<String, Configuration> e : named.entrySet()) cm.defineConfiguration(e.getKey(), e.getValue());
       cm.start();
       return cm;
    }
@@ -126,9 +128,7 @@
       globalConfiguration.setTransportNodeName(perThreadCacheManagers.get().getNextCacheName());
       amendMarshaller(globalConfiguration);
       minimizeThreads(globalConfiguration);
-      Properties newTransportProps = new Properties();
-      newTransportProps.put(JGroupsTransport.CONFIGURATION_STRING, JGroupsConfigBuilder.getJGroupsConfig());
-      globalConfiguration.setTransportProperties(newTransportProps);
+      amendTransport(globalConfiguration);
       return newDefaultCacheManager(true, globalConfiguration, defaultCacheConfig, false);
    }
 
@@ -145,9 +145,10 @@
    }
 
    /**
-    * Creates a cache manager that won't try to modify the configured jmx domain name: {@link org.infinispan.config.GlobalConfiguration#getJmxDomain()}}.
-    * This method must be used with care, and one should make sure that no domain name collision happens when the parallel suite executes.
-    * An approach to ensure this, is to set the domain name to the name of the test class that instantiates the CacheManager.
+    * Creates a cache manager that won't try to modify the configured jmx domain name: {@link
+    * org.infinispan.config.GlobalConfiguration#getJmxDomain()}}. This method must be used with care, and one should
+    * make sure that no domain name collision happens when the parallel suite executes. An approach to ensure this, is
+    * to set the domain name to the name of the test class that instantiates the CacheManager.
     */
    public static EmbeddedCacheManager createCacheManagerEnforceJmxDomain(GlobalConfiguration configuration) {
       return internalCreateJmxDomain(true, configuration, true);
@@ -183,10 +184,13 @@
 
    public static EmbeddedCacheManager createCacheManager(Configuration defaultCacheConfig, boolean transactional) {
       GlobalConfiguration globalConfiguration;
-      if (defaultCacheConfig.getCacheMode().isClustered())
+      if (defaultCacheConfig.getCacheMode().isClustered()) {
          globalConfiguration = GlobalConfiguration.getClusteredDefault();
-      else
+         amendTransport(globalConfiguration);
+      }
+      else {
          globalConfiguration = GlobalConfiguration.getNonClusteredDefault();
+      }
       amendMarshaller(globalConfiguration);
       minimizeThreads(globalConfiguration);
       if (transactional) amendJTA(defaultCacheConfig);
@@ -247,7 +251,7 @@
       if (configuration.getTransportClass() != null) { //this is local
          Properties newTransportProps = new Properties();
          Properties previousSettings = configuration.getTransportProperties();
-         if (previousSettings!=null) {
+         if (previousSettings != null) {
             newTransportProps.putAll(previousSettings);
          }
          newTransportProps.put(JGroupsTransport.CONFIGURATION_STRING, JGroupsConfigBuilder.getJGroupsConfig());
@@ -276,6 +280,7 @@
       DefaultCacheManager defaultCacheManager = new DefaultCacheManager(gc, c, start);
       PerThreadCacheManagers threadCacheManagers = perThreadCacheManagers.get();
       String methodName = extractMethodName();
+      log.trace("Adding DCM (" + defaultCacheManager.getAddress() + ") for method: '" + methodName + "'");
       threadCacheManagers.add(methodName, defaultCacheManager);
       return defaultCacheManager;
    }
@@ -283,8 +288,7 @@
    private static String extractMethodName() {
       StackTraceElement[] stack = Thread.currentThread().getStackTrace();
       if (stack.length == 0) return null;
-      for (int i = stack.length - 1; i > 0; i--)
-      {
+      for (int i = stack.length - 1; i > 0; i--) {
          StackTraceElement e = stack[i];
          String className = e.getClassName();
          if ((className.indexOf("org.infinispan") != -1) && className.indexOf("org.infinispan.test") < 0)
@@ -298,17 +302,16 @@
    }
 
    private static class PerThreadCacheManagers {
-      HashMap<String, EmbeddedCacheManager> cacheManagers = new HashMap<String, EmbeddedCacheManager>();
+      HashMap<EmbeddedCacheManager, String> cacheManagers = new HashMap<EmbeddedCacheManager, String>();
 
       public void checkManagersClosed(String testName) {
-         for (String cmName : cacheManagers.keySet()) {
-            EmbeddedCacheManager cm = cacheManagers.get(cmName);
-            if (cm.getStatus().allowInvocations()) {
+         for (Map.Entry<EmbeddedCacheManager, String> cmEntry : cacheManagers.entrySet()) {
+            if (cmEntry.getKey().getStatus().allowInvocations()) {
                String thName = Thread.currentThread().getName();
                String errorMessage = '\n' +
                      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" +
                      "!!!!!! (" + thName + ") Exiting because " + testName + " has NOT shut down all the cache managers it has started !!!!!!!\n" +
-                     "!!!!!! (" + thName + ") The still-running cacheManager was created here: " + cmName + " !!!!!!!\n" +
+                     "!!!!!! (" + thName + ") The still-running cacheManager was created here: " + cmEntry.getValue() + " !!!!!!!\n" +
                      "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n";
                log.error(errorMessage);
                System.err.println(errorMessage);
@@ -319,13 +322,13 @@
       }
 
       public String getNextCacheName() {
-         int index = cacheManagers.keySet().size();
-         char name = (char) ((int)'A' + index);
+         int index = cacheManagers.size();
+         char name = (char) ((int) 'A' + index);
          return "Node" + name;
       }
 
       public void add(String methodName, DefaultCacheManager cm) {
-         cacheManagers.put(methodName, cm);
+         cacheManagers.put(cm, methodName);
       }
    }
 }

Deleted: trunk/core/src/test/java/org/infinispan/tx/AsyncDeadlockDetectionTest.java
===================================================================
--- trunk/core/src/test/java/org/infinispan/tx/AsyncDeadlockDetectionTest.java	2010-09-15 16:19:59 UTC (rev 2385)
+++ trunk/core/src/test/java/org/infinispan/tx/AsyncDeadlockDetectionTest.java	2010-09-15 19:09:38 UTC (rev 2386)
@@ -1,183 +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);
-
-      LockManager lockManager = TestingUtil.extractLockManager(cache1);
-      while (!lockManager.isLocked("k1")) {
-         Thread.sleep(50);
-      }
-      System.out.println("successful replication !");
-
-
-      t1.setKeyValue("k1", "v1_t1");
-      t1.executeNoResponse(PerCacheExecutorThread.Operations.PUT_KEY_VALUE);
-
-
-      Object t1Response = t1.waitForResponse();
-      Object t0Response = remoteReplicationInterceptor.getResponse();
-
-      System.out.println("t0Response = " + t0Response);
-      System.out.println("t1Response = " + t1Response);
-
-      assert xor(t1Response instanceof DeadlockDetectedException, t0Response instanceof DeadlockDetectedException);
-
-      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();
-      }
-
-      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);
-
-      TransactionTable transactionTable1 = TestingUtil.extractComponent(cache1, TransactionTable.class);
-      assertEquals(transactionTable1.getLocalTxCount(), 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 thrownExceptionForRemoteTx 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: trunk/core/src/test/java/org/infinispan/tx/LocalDeadlockDetectionTest.java
===================================================================
--- trunk/core/src/test/java/org/infinispan/tx/LocalDeadlockDetectionTest.java	2010-09-15 16:19:59 UTC (rev 2385)
+++ trunk/core/src/test/java/org/infinispan/tx/LocalDeadlockDetectionTest.java	2010-09-15 19:09:38 UTC (rev 2386)
@@ -1,191 +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 beggin");
-
-      t1.setKeyValue("k1", "value_1_t1");
-      t2.setKeyValue("k2", "value_2_t2");
-
-      assert firstOperation.getCorrespondingOkResult() == t1.execute(firstOperation);
-      assert firstOperation.getCorrespondingOkResult() == t2.execute(firstOperation);
-
-      System.out.println("After first PUT");
-      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: trunk/core/src/test/java/org/infinispan/tx/ReplDeadlockDetectionTest.java
===================================================================
--- trunk/core/src/test/java/org/infinispan/tx/ReplDeadlockDetectionTest.java	2010-09-15 16:19:59 UTC (rev 2385)
+++ trunk/core/src/test/java/org/infinispan/tx/ReplDeadlockDetectionTest.java	2010-09-15 19:09:38 UTC (rev 2386)
@@ -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 beggin");
-
-      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: trunk/core/src/test/java/org/infinispan/tx/dld (from rev 2385, branches/4.2.x/core/src/test/java/org/infinispan/tx/dld)

Deleted: trunk/core/src/test/java/org/infinispan/tx/dld/AsyncDeadlockDetectionTest.java
===================================================================
--- branches/4.2.x/core/src/test/java/org/infinispan/tx/dld/AsyncDeadlockDetectionTest.java	2010-09-15 16:19:59 UTC (rev 2385)
+++ trunk/core/src/test/java/org/infinispan/tx/dld/AsyncDeadlockDetectionTest.java	2010-09-15 19:09:38 UTC (rev 2386)
@@ -1,186 +0,0 @@
-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;
-      }
-   }
-}

Copied: trunk/core/src/test/java/org/infinispan/tx/dld/AsyncDeadlockDetectionTest.java (from rev 2385, branches/4.2.x/core/src/test/java/org/infinispan/tx/dld/AsyncDeadlockDetectionTest.java)
===================================================================
--- trunk/core/src/test/java/org/infinispan/tx/dld/AsyncDeadlockDetectionTest.java	                        (rev 0)
+++ trunk/core/src/test/java/org/infinispan/tx/dld/AsyncDeadlockDetectionTest.java	2010-09-15 19:09:38 UTC (rev 2386)
@@ -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;
+      }
+   }
+}

Deleted: trunk/core/src/test/java/org/infinispan/tx/dld/BaseDldEagerLockingTest.java
===================================================================
--- branches/4.2.x/core/src/test/java/org/infinispan/tx/dld/BaseDldEagerLockingTest.java	2010-09-15 16:19:59 UTC (rev 2385)
+++ trunk/core/src/test/java/org/infinispan/tx/dld/BaseDldEagerLockingTest.java	2010-09-15 19:09:38 UTC (rev 2386)
@@ -1,104 +0,0 @@
-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.");
-   }
-
-
-}

Copied: trunk/core/src/test/java/org/infinispan/tx/dld/BaseDldEagerLockingTest.java (from rev 2385, branches/4.2.x/core/src/test/java/org/infinispan/tx/dld/BaseDldEagerLockingTest.java)
===================================================================
--- trunk/core/src/test/java/org/infinispan/tx/dld/BaseDldEagerLockingTest.java	                        (rev 0)
+++ trunk/core/src/test/java/org/infinispan/tx/dld/BaseDldEagerLockingTest.java	2010-09-15 19:09:38 UTC (rev 2386)
@@ -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.");
+   }
+
+
+}

Deleted: trunk/core/src/test/java/org/infinispan/tx/dld/BaseDldLazyLockingTest.java
===================================================================
--- branches/4.2.x/core/src/test/java/org/infinispan/tx/dld/BaseDldLazyLockingTest.java	2010-09-15 16:19:59 UTC (rev 2385)
+++ trunk/core/src/test/java/org/infinispan/tx/dld/BaseDldLazyLockingTest.java	2010-09-15 19:09:38 UTC (rev 2386)
@@ -1,125 +0,0 @@
-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");
-   }
-
-   protected void testLocalVsRemoteDeadlock(Object k0, Object k1) {
-
-      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");
-      t0.execute(PerCacheExecutorThread.Operations.PUT_KEY_VALUE);
-
-      t1.setKeyValue(k1, "k1_0");
-      assertEquals(t1.execute(PerCacheExecutorThread.Operations.PUT_KEY_VALUE), PerCacheExecutorThread.OperationsResult.PUT_KEY_VALUE_OK);
-      t1.setKeyValue(k0, "k0_1");
-      assertEquals(t1.execute(PerCacheExecutorThread.Operations.PUT_KEY_VALUE), PerCacheExecutorThread.OperationsResult.PUT_KEY_VALUE_OK);
-      t1.executeNoResponse(PerCacheExecutorThread.Operations.COMMIT_TX);
-
-      t0.setKeyValue(k1, "k1_0");
-      t0.executeNoResponse(PerCacheExecutorThread.Operations.PUT_KEY_VALUE);
-
-      Object t0Response = t0.waitForResponse();
-      Object t1Response = t1.waitForResponse();
-
-      boolean v0 = t0Response instanceof Exception;
-      boolean v1 = t1Response instanceof Exception;
-      assert xor(v0, v1) : "both exceptions? " + (v0 && v1);
-
-      if (!v1) {
-         System.out.println("V0" );
-         assertEquals(cache(0).get(k0), "k0_1");
-         assertEquals(cache(0).get(k1), "k1_1");
-         assertEquals(cache(1).get(k0), "k0_1");
-         assertEquals(cache(1).get(k1), "k1_1");
-      } else {
-         System.out.println("v1 = " + v1);
-         assertEquals(t0.execute(PerCacheExecutorThread.Operations.COMMIT_TX), PerCacheExecutorThread.OperationsResult.COMMIT_TX_OK);
-         assertEquals(cache(0).get(k0), "k0_0");
-         assertEquals(cache(0).get(k1), "k1_0");
-         assertEquals(cache(1).get(k0), "k0_0");
-         assertEquals(cache(1).get(k1), "k1_0");
-      }
-   }
-}

Copied: trunk/core/src/test/java/org/infinispan/tx/dld/BaseDldLazyLockingTest.java (from rev 2385, branches/4.2.x/core/src/test/java/org/infinispan/tx/dld/BaseDldLazyLockingTest.java)
===================================================================
--- trunk/core/src/test/java/org/infinispan/tx/dld/BaseDldLazyLockingTest.java	                        (rev 0)
+++ trunk/core/src/test/java/org/infinispan/tx/dld/BaseDldLazyLockingTest.java	2010-09-15 19:09:38 UTC (rev 2386)
@@ -0,0 +1,125 @@
+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");
+   }
+
+   protected void testLocalVsRemoteDeadlock(Object k0, Object k1) {
+
+      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");
+      t0.execute(PerCacheExecutorThread.Operations.PUT_KEY_VALUE);
+
+      t1.setKeyValue(k1, "k1_0");
+      assertEquals(t1.execute(PerCacheExecutorThread.Operations.PUT_KEY_VALUE), PerCacheExecutorThread.OperationsResult.PUT_KEY_VALUE_OK);
+      t1.setKeyValue(k0, "k0_1");
+      assertEquals(t1.execute(PerCacheExecutorThread.Operations.PUT_KEY_VALUE), PerCacheExecutorThread.OperationsResult.PUT_KEY_VALUE_OK);
+      t1.executeNoResponse(PerCacheExecutorThread.Operations.COMMIT_TX);
+
+      t0.setKeyValue(k1, "k1_0");
+      t0.executeNoResponse(PerCacheExecutorThread.Operations.PUT_KEY_VALUE);
+
+      Object t0Response = t0.waitForResponse();
+      Object t1Response = t1.waitForResponse();
+
+      boolean v0 = t0Response instanceof Exception;
+      boolean v1 = t1Response instanceof Exception;
+      assert xor(v0, v1) : "both exceptions? " + (v0 && v1);
+
+      if (!v1) {
+         System.out.println("V0" );
+         assertEquals(cache(0).get(k0), "k0_1");
+         assertEquals(cache(0).get(k1), "k1_1");
+         assertEquals(cache(1).get(k0), "k0_1");
+         assertEquals(cache(1).get(k1), "k1_1");
+      } else {
+         System.out.println("v1 = " + v1);
+         assertEquals(t0.execute(PerCacheExecutorThread.Operations.COMMIT_TX), PerCacheExecutorThread.OperationsResult.COMMIT_TX_OK);
+         assertEquals(cache(0).get(k0), "k0_0");
+         assertEquals(cache(0).get(k1), "k1_0");
+         assertEquals(cache(1).get(k0), "k0_0");
+         assertEquals(cache(1).get(k1), "k1_0");
+      }
+   }
+}

Deleted: trunk/core/src/test/java/org/infinispan/tx/dld/BaseDldTest.java
===================================================================
--- branches/4.2.x/core/src/test/java/org/infinispan/tx/dld/BaseDldTest.java	2010-09-15 16:19:59 UTC (rev 2385)
+++ trunk/core/src/test/java/org/infinispan/tx/dld/BaseDldTest.java	2010-09-15 19:09:38 UTC (rev 2386)
@@ -1,24 +0,0 @@
-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;
-
-/**
- * @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;
-   }
-
-}

Copied: trunk/core/src/test/java/org/infinispan/tx/dld/BaseDldTest.java (from rev 2385, branches/4.2.x/core/src/test/java/org/infinispan/tx/dld/BaseDldTest.java)
===================================================================
--- trunk/core/src/test/java/org/infinispan/tx/dld/BaseDldTest.java	                        (rev 0)
+++ trunk/core/src/test/java/org/infinispan/tx/dld/BaseDldTest.java	2010-09-15 19:09:38 UTC (rev 2386)
@@ -0,0 +1,24 @@
+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;
+
+/**
+ * @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;
+   }
+
+}

Deleted: trunk/core/src/test/java/org/infinispan/tx/dld/ControlledRpcManager.java
===================================================================
--- branches/4.2.x/core/src/test/java/org/infinispan/tx/dld/ControlledRpcManager.java	2010-09-15 16:19:59 UTC (rev 2385)
+++ trunk/core/src/test/java/org/infinispan/tx/dld/ControlledRpcManager.java	2010-09-15 19:09:38 UTC (rev 2386)
@@ -1,146 +0,0 @@
-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;
-
-   private boolean fail;
-
-   public ControlledRpcManager(RpcManager realOne) {
-      this.realOne = realOne;
-   }
-
-   private RpcManager realOne;
-
-   public boolean isFail() {
-      return fail;
-   }
-
-   public void setFail(boolean fail) {
-      this.fail = fail;
-   }
-
-   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) {
-      failIfNeeded();
-      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) {
-      failIfNeeded();
-      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 {
-      failIfNeeded();
-      waitFirst(rpcCommand);
-      return realOne.invokeRemotely(recipients, rpcCommand, mode, timeout);
-   }
-
-   public void retrieveState(String cacheName, long timeout) throws StateTransferException {
-      failIfNeeded();
-      realOne.retrieveState(cacheName, timeout);
-   }
-
-   public void broadcastRpcCommand(ReplicableCommand rpc, boolean sync) throws ReplicationException {
-      failIfNeeded();
-      waitFirst(rpc);
-      realOne.broadcastRpcCommand(rpc, sync);
-   }
-
-   public void broadcastRpcCommand(ReplicableCommand rpc, boolean sync, boolean usePriorityQueue) throws ReplicationException {
-      failIfNeeded();
-      waitFirst(rpc);
-      realOne.broadcastRpcCommand(rpc, sync, usePriorityQueue);
-   }
-
-   private void waitFirst(ReplicableCommand rpcCommand) {
-      failIfNeeded();
-      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) {
-      failIfNeeded();
-      realOne.broadcastRpcCommandInFuture(rpc, future);
-   }
-
-   public void broadcastRpcCommandInFuture(ReplicableCommand rpc, boolean usePriorityQueue, NotifyingNotifiableFuture<Object> future) {
-      failIfNeeded();
-      realOne.broadcastRpcCommandInFuture(rpc, usePriorityQueue, future);
-   }
-
-   public void invokeRemotely(Collection<Address> recipients, ReplicableCommand rpc, boolean sync) throws ReplicationException {
-      failIfNeeded();
-      realOne.invokeRemotely(recipients, rpc, sync);
-   }
-
-   public void invokeRemotely(Collection<Address> recipients, ReplicableCommand rpc, boolean sync, boolean usePriorityQueue) throws ReplicationException {
-      failIfNeeded();
-      realOne.invokeRemotely(recipients, rpc, sync, usePriorityQueue);
-   }
-
-   public void invokeRemotelyInFuture(Collection<Address> recipients, ReplicableCommand rpc, NotifyingNotifiableFuture<Object> future) {
-      failIfNeeded();
-      realOne.invokeRemotelyInFuture(recipients, rpc, future);
-   }
-
-   public void invokeRemotelyInFuture(Collection<Address> recipients, ReplicableCommand rpc, boolean usePriorityQueue, NotifyingNotifiableFuture<Object> future) {
-      failIfNeeded();
-      realOne.invokeRemotelyInFuture(recipients, rpc, usePriorityQueue, future);
-   }
-
-   public void invokeRemotelyInFuture(Collection<Address> recipients, ReplicableCommand rpc, boolean usePriorityQueue, NotifyingNotifiableFuture<Object> future, long timeout) {
-      failIfNeeded();
-      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();
-   }
-
-   public void failIfNeeded() {
-      if (fail) throw new IllegalStateException("Induced failure!");
-   }
-}

Copied: trunk/core/src/test/java/org/infinispan/tx/dld/ControlledRpcManager.java (from rev 2385, branches/4.2.x/core/src/test/java/org/infinispan/tx/dld/ControlledRpcManager.java)
===================================================================
--- trunk/core/src/test/java/org/infinispan/tx/dld/ControlledRpcManager.java	                        (rev 0)
+++ trunk/core/src/test/java/org/infinispan/tx/dld/ControlledRpcManager.java	2010-09-15 19:09:38 UTC (rev 2386)
@@ -0,0 +1,146 @@
+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;
+
+   private boolean fail;
+
+   public ControlledRpcManager(RpcManager realOne) {
+      this.realOne = realOne;
+   }
+
+   private RpcManager realOne;
+
+   public boolean isFail() {
+      return fail;
+   }
+
+   public void setFail(boolean fail) {
+      this.fail = fail;
+   }
+
+   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) {
+      failIfNeeded();
+      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) {
+      failIfNeeded();
+      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 {
+      failIfNeeded();
+      waitFirst(rpcCommand);
+      return realOne.invokeRemotely(recipients, rpcCommand, mode, timeout);
+   }
+
+   public void retrieveState(String cacheName, long timeout) throws StateTransferException {
+      failIfNeeded();
+      realOne.retrieveState(cacheName, timeout);
+   }
+
+   public void broadcastRpcCommand(ReplicableCommand rpc, boolean sync) throws ReplicationException {
+      failIfNeeded();
+      waitFirst(rpc);
+      realOne.broadcastRpcCommand(rpc, sync);
+   }
+
+   public void broadcastRpcCommand(ReplicableCommand rpc, boolean sync, boolean usePriorityQueue) throws ReplicationException {
+      failIfNeeded();
+      waitFirst(rpc);
+      realOne.broadcastRpcCommand(rpc, sync, usePriorityQueue);
+   }
+
+   private void waitFirst(ReplicableCommand rpcCommand) {
+      failIfNeeded();
+      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) {
+      failIfNeeded();
+      realOne.broadcastRpcCommandInFuture(rpc, future);
+   }
+
+   public void broadcastRpcCommandInFuture(ReplicableCommand rpc, boolean usePriorityQueue, NotifyingNotifiableFuture<Object> future) {
+      failIfNeeded();
+      realOne.broadcastRpcCommandInFuture(rpc, usePriorityQueue, future);
+   }
+
+   public void invokeRemotely(Collection<Address> recipients, ReplicableCommand rpc, boolean sync) throws ReplicationException {
+      failIfNeeded();
+      realOne.invokeRemotely(recipients, rpc, sync);
+   }
+
+   public void invokeRemotely(Collection<Address> recipients, ReplicableCommand rpc, boolean sync, boolean usePriorityQueue) throws ReplicationException {
+      failIfNeeded();
+      realOne.invokeRemotely(recipients, rpc, sync, usePriorityQueue);
+   }
+
+   public void invokeRemotelyInFuture(Collection<Address> recipients, ReplicableCommand rpc, NotifyingNotifiableFuture<Object> future) {
+      failIfNeeded();
+      realOne.invokeRemotelyInFuture(recipients, rpc, future);
+   }
+
+   public void invokeRemotelyInFuture(Collection<Address> recipients, ReplicableCommand rpc, boolean usePriorityQueue, NotifyingNotifiableFuture<Object> future) {
+      failIfNeeded();
+      realOne.invokeRemotelyInFuture(recipients, rpc, usePriorityQueue, future);
+   }
+
+   public void invokeRemotelyInFuture(Collection<Address> recipients, ReplicableCommand rpc, boolean usePriorityQueue, NotifyingNotifiableFuture<Object> future, long timeout) {
+      failIfNeeded();
+      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();
+   }
+
+   public void failIfNeeded() {
+      if (fail) throw new IllegalStateException("Induced failure!");
+   }
+}

Deleted: trunk/core/src/test/java/org/infinispan/tx/dld/DldEagerLockingDistributedTest.java
===================================================================
--- branches/4.2.x/core/src/test/java/org/infinispan/tx/dld/DldEagerLockingDistributedTest.java	2010-09-15 16:19:59 UTC (rev 2385)
+++ trunk/core/src/test/java/org/infinispan/tx/dld/DldEagerLockingDistributedTest.java	2010-09-15 19:09:38 UTC (rev 2386)
@@ -1,56 +0,0 @@
-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;
-
-/**
- * @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: trunk/core/src/test/java/org/infinispan/tx/dld/DldEagerLockingDistributedTest.java (from rev 2385, branches/4.2.x/core/src/test/java/org/infinispan/tx/dld/DldEagerLockingDistributedTest.java)
===================================================================
--- trunk/core/src/test/java/org/infinispan/tx/dld/DldEagerLockingDistributedTest.java	                        (rev 0)
+++ trunk/core/src/test/java/org/infinispan/tx/dld/DldEagerLockingDistributedTest.java	2010-09-15 19:09:38 UTC (rev 2386)
@@ -0,0 +1,56 @@
+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;
+
+/**
+ * @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);
+   }
+}

Deleted: trunk/core/src/test/java/org/infinispan/tx/dld/DldEagerLockingReplicationTest.java
===================================================================
--- branches/4.2.x/core/src/test/java/org/infinispan/tx/dld/DldEagerLockingReplicationTest.java	2010-09-15 16:19:59 UTC (rev 2385)
+++ trunk/core/src/test/java/org/infinispan/tx/dld/DldEagerLockingReplicationTest.java	2010-09-15 19:09:38 UTC (rev 2386)
@@ -1,63 +0,0 @@
-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.dld.DldEagerLockingReplicationTest")
-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();
-      }
-   }
-}

Copied: trunk/core/src/test/java/org/infinispan/tx/dld/DldEagerLockingReplicationTest.java (from rev 2385, branches/4.2.x/core/src/test/java/org/infinispan/tx/dld/DldEagerLockingReplicationTest.java)
===================================================================
--- trunk/core/src/test/java/org/infinispan/tx/dld/DldEagerLockingReplicationTest.java	                        (rev 0)
+++ trunk/core/src/test/java/org/infinispan/tx/dld/DldEagerLockingReplicationTest.java	2010-09-15 19:09:38 UTC (rev 2386)
@@ -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.dld.DldEagerLockingReplicationTest")
+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();
+      }
+   }
+}

Deleted: trunk/core/src/test/java/org/infinispan/tx/dld/DldLazyLockingDistributionTest.java
===================================================================
--- branches/4.2.x/core/src/test/java/org/infinispan/tx/dld/DldLazyLockingDistributionTest.java	2010-09-15 16:19:59 UTC (rev 2385)
+++ trunk/core/src/test/java/org/infinispan/tx/dld/DldLazyLockingDistributionTest.java	2010-09-15 19:09:38 UTC (rev 2386)
@@ -1,61 +0,0 @@
-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.dld.DldLazyLockingDistributionTest")
-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: trunk/core/src/test/java/org/infinispan/tx/dld/DldLazyLockingDistributionTest.java (from rev 2385, branches/4.2.x/core/src/test/java/org/infinispan/tx/dld/DldLazyLockingDistributionTest.java)
===================================================================
--- trunk/core/src/test/java/org/infinispan/tx/dld/DldLazyLockingDistributionTest.java	                        (rev 0)
+++ trunk/core/src/test/java/org/infinispan/tx/dld/DldLazyLockingDistributionTest.java	2010-09-15 19:09:38 UTC (rev 2386)
@@ -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.dld.DldLazyLockingDistributionTest")
+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();
+   }
+
+}

Deleted: trunk/core/src/test/java/org/infinispan/tx/dld/DldLazyLockingReplicationTest.java
===================================================================
--- branches/4.2.x/core/src/test/java/org/infinispan/tx/dld/DldLazyLockingReplicationTest.java	2010-09-15 16:19:59 UTC (rev 2385)
+++ trunk/core/src/test/java/org/infinispan/tx/dld/DldLazyLockingReplicationTest.java	2010-09-15 19:09:38 UTC (rev 2386)
@@ -1,217 +0,0 @@
-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.dld.DldLazyLockingReplicationTest", 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 testLocalVsRemoteDeadlock() {
-      replicationLatch.countDown();
-      testLocalVsRemoteDeadlock("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");
-   }
-
-}

Copied: trunk/core/src/test/java/org/infinispan/tx/dld/DldLazyLockingReplicationTest.java (from rev 2385, branches/4.2.x/core/src/test/java/org/infinispan/tx/dld/DldLazyLockingReplicationTest.java)
===================================================================
--- trunk/core/src/test/java/org/infinispan/tx/dld/DldLazyLockingReplicationTest.java	                        (rev 0)
+++ trunk/core/src/test/java/org/infinispan/tx/dld/DldLazyLockingReplicationTest.java	2010-09-15 19:09:38 UTC (rev 2386)
@@ -0,0 +1,217 @@
+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.dld.DldLazyLockingReplicationTest", 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 testLocalVsRemoteDeadlock() {
+      replicationLatch.countDown();
+      testLocalVsRemoteDeadlock("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");
+   }
+
+}

Deleted: trunk/core/src/test/java/org/infinispan/tx/dld/LocalDeadlockDetectionTest.java
===================================================================
--- branches/4.2.x/core/src/test/java/org/infinispan/tx/dld/LocalDeadlockDetectionTest.java	2010-09-15 16:19:59 UTC (rev 2385)
+++ trunk/core/src/test/java/org/infinispan/tx/dld/LocalDeadlockDetectionTest.java	2010-09-15 19:09:38 UTC (rev 2386)
@@ -1,190 +0,0 @@
-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.dld.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);
-   }
-
-}

Copied: trunk/core/src/test/java/org/infinispan/tx/dld/LocalDeadlockDetectionTest.java (from rev 2385, branches/4.2.x/core/src/test/java/org/infinispan/tx/dld/LocalDeadlockDetectionTest.java)
===================================================================
--- trunk/core/src/test/java/org/infinispan/tx/dld/LocalDeadlockDetectionTest.java	                        (rev 0)
+++ trunk/core/src/test/java/org/infinispan/tx/dld/LocalDeadlockDetectionTest.java	2010-09-15 19:09:38 UTC (rev 2386)
@@ -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.dld.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);
+   }
+
+}

Copied: trunk/core/src/test/java/org/infinispan/tx/exception (from rev 2385, branches/4.2.x/core/src/test/java/org/infinispan/tx/exception)

Deleted: trunk/core/src/test/java/org/infinispan/tx/exception/CustomInterceptorException.java
===================================================================
--- branches/4.2.x/core/src/test/java/org/infinispan/tx/exception/CustomInterceptorException.java	2010-09-15 16:19:59 UTC (rev 2385)
+++ trunk/core/src/test/java/org/infinispan/tx/exception/CustomInterceptorException.java	2010-09-15 19:09:38 UTC (rev 2386)
@@ -1,45 +0,0 @@
-package org.infinispan.tx.exception;
-
-import org.infinispan.commands.write.PutKeyValueCommand;
-import org.infinispan.config.Configuration;
-import org.infinispan.config.CustomInterceptorConfigTest;
-import org.infinispan.context.InvocationContext;
-import org.infinispan.manager.EmbeddedCacheManager;
-import org.infinispan.test.SingleCacheManagerTest;
-import org.infinispan.test.fwk.TestCacheManagerFactory;
-import org.testng.annotations.Test;
-
-import javax.transaction.Status;
-import javax.transaction.TransactionManager;
-
-/**
- * @author Mircea.Markus at jboss.com
- * @since 4.2
- */
- at Test(groups = "functional", testName = "CustomInterceptorException")
-public class CustomInterceptorException extends SingleCacheManagerTest {
-
-   @Override
-   protected EmbeddedCacheManager createCacheManager() throws Exception {
-      EmbeddedCacheManager eCm =
-            TestCacheManagerFactory.createCacheManager(getDefaultClusteredConfig(Configuration.CacheMode.LOCAL), true);
-      eCm.getCache().getAdvancedCache().addInterceptor(new CustomInterceptorConfigTest.DummyInterceptor() {
-         @Override
-         public Object visitPutKeyValueCommand(InvocationContext ctx, PutKeyValueCommand command) throws Throwable {
-            throw new IllegalStateException("Induce failure!");
-         }
-      }, 1);
-      return eCm;
-   }
-
-   public void testFailure() throws Exception {
-      TransactionManager transactionManager = cache.getAdvancedCache().getTransactionManager();
-      transactionManager.begin();
-      try {
-         cache.put("k", "v");
-         assert false;
-      } catch (Exception e) {
-         assert transactionManager.getTransaction().getStatus() == Status.STATUS_MARKED_ROLLBACK;
-      }
-   }
-}

Copied: trunk/core/src/test/java/org/infinispan/tx/exception/CustomInterceptorException.java (from rev 2385, branches/4.2.x/core/src/test/java/org/infinispan/tx/exception/CustomInterceptorException.java)
===================================================================
--- trunk/core/src/test/java/org/infinispan/tx/exception/CustomInterceptorException.java	                        (rev 0)
+++ trunk/core/src/test/java/org/infinispan/tx/exception/CustomInterceptorException.java	2010-09-15 19:09:38 UTC (rev 2386)
@@ -0,0 +1,45 @@
+package org.infinispan.tx.exception;
+
+import org.infinispan.commands.write.PutKeyValueCommand;
+import org.infinispan.config.Configuration;
+import org.infinispan.config.CustomInterceptorConfigTest;
+import org.infinispan.context.InvocationContext;
+import org.infinispan.manager.EmbeddedCacheManager;
+import org.infinispan.test.SingleCacheManagerTest;
+import org.infinispan.test.fwk.TestCacheManagerFactory;
+import org.testng.annotations.Test;
+
+import javax.transaction.Status;
+import javax.transaction.TransactionManager;
+
+/**
+ * @author Mircea.Markus at jboss.com
+ * @since 4.2
+ */
+ at Test(groups = "functional", testName = "CustomInterceptorException")
+public class CustomInterceptorException extends SingleCacheManagerTest {
+
+   @Override
+   protected EmbeddedCacheManager createCacheManager() throws Exception {
+      EmbeddedCacheManager eCm =
+            TestCacheManagerFactory.createCacheManager(getDefaultClusteredConfig(Configuration.CacheMode.LOCAL), true);
+      eCm.getCache().getAdvancedCache().addInterceptor(new CustomInterceptorConfigTest.DummyInterceptor() {
+         @Override
+         public Object visitPutKeyValueCommand(InvocationContext ctx, PutKeyValueCommand command) throws Throwable {
+            throw new IllegalStateException("Induce failure!");
+         }
+      }, 1);
+      return eCm;
+   }
+
+   public void testFailure() throws Exception {
+      TransactionManager transactionManager = cache.getAdvancedCache().getTransactionManager();
+      transactionManager.begin();
+      try {
+         cache.put("k", "v");
+         assert false;
+      } catch (Exception e) {
+         assert transactionManager.getTransaction().getStatus() == Status.STATUS_MARKED_ROLLBACK;
+      }
+   }
+}

Deleted: trunk/core/src/test/java/org/infinispan/tx/exception/ExplicitLockingAndTimeoutTest.java
===================================================================
--- branches/4.2.x/core/src/test/java/org/infinispan/tx/exception/ExplicitLockingAndTimeoutTest.java	2010-09-15 16:19:59 UTC (rev 2385)
+++ trunk/core/src/test/java/org/infinispan/tx/exception/ExplicitLockingAndTimeoutTest.java	2010-09-15 19:09:38 UTC (rev 2386)
@@ -1,139 +0,0 @@
-package org.infinispan.tx.exception;
-
-import org.infinispan.commands.VisitableCommand;
-import org.infinispan.commands.control.LockControlCommand;
-import org.infinispan.config.Configuration;
-import org.infinispan.context.InvocationContext;
-import org.infinispan.context.impl.TxInvocationContext;
-import org.infinispan.interceptors.base.CommandInterceptor;
-import org.infinispan.test.MultipleCacheManagersTest;
-import org.infinispan.test.TestingUtil;
-import org.infinispan.transaction.xa.TransactionTable;
-import org.infinispan.util.concurrent.TimeoutException;
-import org.infinispan.util.concurrent.locks.LockManager;
-import org.testng.annotations.Test;
-
-import javax.transaction.HeuristicMixedException;
-import javax.transaction.HeuristicRollbackException;
-import javax.transaction.InvalidTransactionException;
-import javax.transaction.NotSupportedException;
-import javax.transaction.RollbackException;
-import javax.transaction.Status;
-import javax.transaction.SystemException;
-import javax.transaction.Transaction;
-import javax.transaction.TransactionManager;
-
-import static org.testng.Assert.assertEquals;
-
-/**
- * @author Mircea.Markus at jboss.com
- * @since 4.2
- */
- at Test(groups = "functional", testName = "tx.timeout.EagerLockingAndTimeoutTest")
-public class ExplicitLockingAndTimeoutTest extends MultipleCacheManagersTest {
-
-   private LockManager lm1;
-   private LockManager lm0;
-   private TransactionTable txTable0;
-   private TransactionTable txTable1;
-   private TransactionManager tm;
-   private TxStatusInterceptor txStatus = new TxStatusInterceptor();
-
-   @Override
-   protected void createCacheManagers() throws Throwable {
-      Configuration defaultConfig = getDefaultConfig();
-      defaultConfig.setLockAcquisitionTimeout(500);
-      defaultConfig.setUseLockStriping(false);
-      addClusterEnabledCacheManager(defaultConfig);
-      addClusterEnabledCacheManager(defaultConfig);
-      lm0 = TestingUtil.extractLockManager(cache(0));
-      lm1 = TestingUtil.extractLockManager(cache(1));
-      txTable0 = TestingUtil.getTransactionTable(cache(0));
-      txTable1 = TestingUtil.getTransactionTable(cache(1));
-      tm = cache(0).getAdvancedCache().getTransactionManager();
-      cache(1).getAdvancedCache().addInterceptor(txStatus, 0);
-      TestingUtil.blockUntilViewReceived(cache(0), 2, 10000);
-   }
-
-   protected Configuration getDefaultConfig() {
-      return getDefaultClusteredConfig(Configuration.CacheMode.REPL_SYNC, true);
-   }
-
-   public void testExplicitLockingRemoteTimeout() throws NotSupportedException, SystemException, HeuristicMixedException, HeuristicRollbackException, InvalidTransactionException, RollbackException {
-      txStatus.reset();
-      tm.begin();
-      cache(1).put("k1", "v1");
-      Transaction k1LockOwner = tm.suspend();
-      assert lm1.isLocked("k1");
-
-      assertEquals(1, txTable1.getLocalTxCount());
-      tm.begin();
-      cache(0).getAdvancedCache().lock("k2");
-      assert lm0.isLocked("k2");
-      assert lm1.isLocked("k2");
-
-      try {
-         cache(0).getAdvancedCache().lock("k1");
-         assert false;
-      } catch (TimeoutException e) {
-         //expected
-      }
-
-      assert txStatus.teReceived;
-      assert txStatus.isTxInTableAfterTeOnEagerLocking;
-      //expect 1 as k1 is locked by the other tx
-      assertEquals(lm1.isLocked("k2"), false, "Even though rollback was not received yet lock on k2, which was acquired, is no longer held");
-      assert tm.getStatus() == Status.STATUS_MARKED_ROLLBACK;
-
-      assertEquals(1, txTable0.getLocalTxCount());
-      assertEquals(1, txTable1.getLocalTxCount());
-      assertEquals(1, txTable1.getRemoteTxCount());
-
-      tm.rollback();
-      assertEquals(0, txTable0.getLocalTxCount());
-      assertEquals(1, txTable1.getLocalTxCount());
-      assertEquals(0, txTable1.getRemoteTxCount());
-
-
-      tm.resume(k1LockOwner);
-      tm.commit();
-      assertEquals("v1", cache(0).get("k1"));
-      assertEquals("v1", cache(1).get("k1"));
-      assertEquals(0, txTable1.getLocalTxCount());
-      assertEquals(0, txTable0.getLocalTxCount());
-      assertEquals(0, lm0.getNumberOfLocksHeld());
-      assertEquals(0, lm1.getNumberOfLocksHeld());
-   }
-
-   private class TxStatusInterceptor extends CommandInterceptor {
-
-      private boolean teReceived;
-
-      private boolean isTxInTableAfterTeOnEagerLocking;
-
-      private int numLocksAfterTeOnEagerLocking;
-
-      @Override
-      public Object visitLockControlCommand(TxInvocationContext ctx, LockControlCommand command) throws Throwable {
-         try {
-            return invokeNextInterceptor(ctx, command);
-         } catch (TimeoutException te) {
-            teReceived = true;
-            isTxInTableAfterTeOnEagerLocking = txTable1.containRemoteTx(ctx.getGlobalTransaction());
-            numLocksAfterTeOnEagerLocking = lm1.getNumberOfLocksHeld();
-            throw te;
-         }
-      }
-
-      @Override
-      protected Object handleDefault(InvocationContext ctx, VisitableCommand command) throws Throwable {
-         return super.handleDefault(ctx, command);
-      }
-
-      public void reset() {
-         this.teReceived = false;
-         this.isTxInTableAfterTeOnEagerLocking = false;
-         this.numLocksAfterTeOnEagerLocking = -1;
-      }
-   }
-}
\ No newline at end of file

Copied: trunk/core/src/test/java/org/infinispan/tx/exception/ExplicitLockingAndTimeoutTest.java (from rev 2385, branches/4.2.x/core/src/test/java/org/infinispan/tx/exception/ExplicitLockingAndTimeoutTest.java)
===================================================================
--- trunk/core/src/test/java/org/infinispan/tx/exception/ExplicitLockingAndTimeoutTest.java	                        (rev 0)
+++ trunk/core/src/test/java/org/infinispan/tx/exception/ExplicitLockingAndTimeoutTest.java	2010-09-15 19:09:38 UTC (rev 2386)
@@ -0,0 +1,139 @@
+package org.infinispan.tx.exception;
+
+import org.infinispan.commands.VisitableCommand;
+import org.infinispan.commands.control.LockControlCommand;
+import org.infinispan.config.Configuration;
+import org.infinispan.context.InvocationContext;
+import org.infinispan.context.impl.TxInvocationContext;
+import org.infinispan.interceptors.base.CommandInterceptor;
+import org.infinispan.test.MultipleCacheManagersTest;
+import org.infinispan.test.TestingUtil;
+import org.infinispan.transaction.xa.TransactionTable;
+import org.infinispan.util.concurrent.TimeoutException;
+import org.infinispan.util.concurrent.locks.LockManager;
+import org.testng.annotations.Test;
+
+import javax.transaction.HeuristicMixedException;
+import javax.transaction.HeuristicRollbackException;
+import javax.transaction.InvalidTransactionException;
+import javax.transaction.NotSupportedException;
+import javax.transaction.RollbackException;
+import javax.transaction.Status;
+import javax.transaction.SystemException;
+import javax.transaction.Transaction;
+import javax.transaction.TransactionManager;
+
+import static org.testng.Assert.assertEquals;
+
+/**
+ * @author Mircea.Markus at jboss.com
+ * @since 4.2
+ */
+ at Test(groups = "functional", testName = "tx.timeout.EagerLockingAndTimeoutTest")
+public class ExplicitLockingAndTimeoutTest extends MultipleCacheManagersTest {
+
+   private LockManager lm1;
+   private LockManager lm0;
+   private TransactionTable txTable0;
+   private TransactionTable txTable1;
+   private TransactionManager tm;
+   private TxStatusInterceptor txStatus = new TxStatusInterceptor();
+
+   @Override
+   protected void createCacheManagers() throws Throwable {
+      Configuration defaultConfig = getDefaultConfig();
+      defaultConfig.setLockAcquisitionTimeout(500);
+      defaultConfig.setUseLockStriping(false);
+      addClusterEnabledCacheManager(defaultConfig);
+      addClusterEnabledCacheManager(defaultConfig);
+      lm0 = TestingUtil.extractLockManager(cache(0));
+      lm1 = TestingUtil.extractLockManager(cache(1));
+      txTable0 = TestingUtil.getTransactionTable(cache(0));
+      txTable1 = TestingUtil.getTransactionTable(cache(1));
+      tm = cache(0).getAdvancedCache().getTransactionManager();
+      cache(1).getAdvancedCache().addInterceptor(txStatus, 0);
+      TestingUtil.blockUntilViewReceived(cache(0), 2, 10000);
+   }
+
+   protected Configuration getDefaultConfig() {
+      return getDefaultClusteredConfig(Configuration.CacheMode.REPL_SYNC, true);
+   }
+
+   public void testExplicitLockingRemoteTimeout() throws NotSupportedException, SystemException, HeuristicMixedException, HeuristicRollbackException, InvalidTransactionException, RollbackException {
+      txStatus.reset();
+      tm.begin();
+      cache(1).put("k1", "v1");
+      Transaction k1LockOwner = tm.suspend();
+      assert lm1.isLocked("k1");
+
+      assertEquals(1, txTable1.getLocalTxCount());
+      tm.begin();
+      cache(0).getAdvancedCache().lock("k2");
+      assert lm0.isLocked("k2");
+      assert lm1.isLocked("k2");
+
+      try {
+         cache(0).getAdvancedCache().lock("k1");
+         assert false;
+      } catch (TimeoutException e) {
+         //expected
+      }
+
+      assert txStatus.teReceived;
+      assert txStatus.isTxInTableAfterTeOnEagerLocking;
+      //expect 1 as k1 is locked by the other tx
+      assertEquals(lm1.isLocked("k2"), false, "Even though rollback was not received yet lock on k2, which was acquired, is no longer held");
+      assert tm.getStatus() == Status.STATUS_MARKED_ROLLBACK;
+
+      assertEquals(1, txTable0.getLocalTxCount());
+      assertEquals(1, txTable1.getLocalTxCount());
+      assertEquals(1, txTable1.getRemoteTxCount());
+
+      tm.rollback();
+      assertEquals(0, txTable0.getLocalTxCount());
+      assertEquals(1, txTable1.getLocalTxCount());
+      assertEquals(0, txTable1.getRemoteTxCount());
+
+
+      tm.resume(k1LockOwner);
+      tm.commit();
+      assertEquals("v1", cache(0).get("k1"));
+      assertEquals("v1", cache(1).get("k1"));
+      assertEquals(0, txTable1.getLocalTxCount());
+      assertEquals(0, txTable0.getLocalTxCount());
+      assertEquals(0, lm0.getNumberOfLocksHeld());
+      assertEquals(0, lm1.getNumberOfLocksHeld());
+   }
+
+   private class TxStatusInterceptor extends CommandInterceptor {
+
+      private boolean teReceived;
+
+      private boolean isTxInTableAfterTeOnEagerLocking;
+
+      private int numLocksAfterTeOnEagerLocking;
+
+      @Override
+      public Object visitLockControlCommand(TxInvocationContext ctx, LockControlCommand command) throws Throwable {
+         try {
+            return invokeNextInterceptor(ctx, command);
+         } catch (TimeoutException te) {
+            teReceived = true;
+            isTxInTableAfterTeOnEagerLocking = txTable1.containRemoteTx(ctx.getGlobalTransaction());
+            numLocksAfterTeOnEagerLocking = lm1.getNumberOfLocksHeld();
+            throw te;
+         }
+      }
+
+      @Override
+      protected Object handleDefault(InvocationContext ctx, VisitableCommand command) throws Throwable {
+         return super.handleDefault(ctx, command);
+      }
+
+      public void reset() {
+         this.teReceived = false;
+         this.isTxInTableAfterTeOnEagerLocking = false;
+         this.numLocksAfterTeOnEagerLocking = -1;
+      }
+   }
+}
\ No newline at end of file

Deleted: trunk/core/src/test/java/org/infinispan/tx/exception/ReplicationExceptionTest.java
===================================================================
--- branches/4.2.x/core/src/test/java/org/infinispan/tx/exception/ReplicationExceptionTest.java	2010-09-15 16:19:59 UTC (rev 2385)
+++ trunk/core/src/test/java/org/infinispan/tx/exception/ReplicationExceptionTest.java	2010-09-15 19:09:38 UTC (rev 2386)
@@ -1,43 +0,0 @@
-package org.infinispan.tx.exception;
-
-import org.infinispan.config.Configuration;
-import org.infinispan.test.MultipleCacheManagersTest;
-import org.infinispan.test.TestingUtil;
-import org.infinispan.test.fwk.TestCacheManagerFactory;
-import org.infinispan.tx.dld.BaseDldTest;
-import org.infinispan.tx.dld.ControlledRpcManager;
-import org.testng.annotations.Test;
-
-import javax.transaction.RollbackException;
-import javax.transaction.TransactionManager;
-
-/**
- * @author Mircea.Markus at jboss.com
- * @since 4.2
- */
- at Test(testName = "tx.exception.ReplicationExceptionTest")
-public class ReplicationExceptionTest extends MultipleCacheManagersTest {
-   private ControlledRpcManager crm0;
-
-   @Override
-   protected void createCacheManagers() throws Throwable {
-      Configuration config = getDefaultClusteredConfig(Configuration.CacheMode.REPL_SYNC);
-      registerCacheManager(TestCacheManagerFactory.createCacheManager(config, true));
-      registerCacheManager(TestCacheManagerFactory.createCacheManager(config, true));
-      TestingUtil.blockUntilViewsReceived(10000, cache(0), cache(1));
-      crm0 = BaseDldTest.replaceRpcManager(cache(0));
-   }
-
-
-   public void testReplicationFailure() throws Exception {
-      TransactionManager tm = cache(0).getAdvancedCache().getTransactionManager();
-      tm.begin();
-      cache(0).put("k0","v");
-      try {
-         tm.commit();
-         assert false;
-      } catch (RollbackException e) {
-         //expected
-      }
-   }
-}

Copied: trunk/core/src/test/java/org/infinispan/tx/exception/ReplicationExceptionTest.java (from rev 2385, branches/4.2.x/core/src/test/java/org/infinispan/tx/exception/ReplicationExceptionTest.java)
===================================================================
--- trunk/core/src/test/java/org/infinispan/tx/exception/ReplicationExceptionTest.java	                        (rev 0)
+++ trunk/core/src/test/java/org/infinispan/tx/exception/ReplicationExceptionTest.java	2010-09-15 19:09:38 UTC (rev 2386)
@@ -0,0 +1,43 @@
+package org.infinispan.tx.exception;
+
+import org.infinispan.config.Configuration;
+import org.infinispan.test.MultipleCacheManagersTest;
+import org.infinispan.test.TestingUtil;
+import org.infinispan.test.fwk.TestCacheManagerFactory;
+import org.infinispan.tx.dld.BaseDldTest;
+import org.infinispan.tx.dld.ControlledRpcManager;
+import org.testng.annotations.Test;
+
+import javax.transaction.RollbackException;
+import javax.transaction.TransactionManager;
+
+/**
+ * @author Mircea.Markus at jboss.com
+ * @since 4.2
+ */
+ at Test(testName = "tx.exception.ReplicationExceptionTest")
+public class ReplicationExceptionTest extends MultipleCacheManagersTest {
+   private ControlledRpcManager crm0;
+
+   @Override
+   protected void createCacheManagers() throws Throwable {
+      Configuration config = getDefaultClusteredConfig(Configuration.CacheMode.REPL_SYNC);
+      registerCacheManager(TestCacheManagerFactory.createCacheManager(config, true));
+      registerCacheManager(TestCacheManagerFactory.createCacheManager(config, true));
+      TestingUtil.blockUntilViewsReceived(10000, cache(0), cache(1));
+      crm0 = BaseDldTest.replaceRpcManager(cache(0));
+   }
+
+
+   public void testReplicationFailure() throws Exception {
+      TransactionManager tm = cache(0).getAdvancedCache().getTransactionManager();
+      tm.begin();
+      cache(0).put("k0","v");
+      try {
+         tm.commit();
+         assert false;
+      } catch (RollbackException e) {
+         //expected
+      }
+   }
+}

Deleted: trunk/core/src/test/java/org/infinispan/tx/exception/TxAndInvalidationTimeoutTest.java
===================================================================
--- branches/4.2.x/core/src/test/java/org/infinispan/tx/exception/TxAndInvalidationTimeoutTest.java	2010-09-15 16:19:59 UTC (rev 2385)
+++ trunk/core/src/test/java/org/infinispan/tx/exception/TxAndInvalidationTimeoutTest.java	2010-09-15 19:09:38 UTC (rev 2386)
@@ -1,174 +0,0 @@
-package org.infinispan.tx.exception;
-
-import org.infinispan.commands.VisitableCommand;
-import org.infinispan.commands.write.InvalidateCommand;
-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.TestingUtil;
-import org.infinispan.transaction.xa.TransactionTable;
-import org.infinispan.util.concurrent.TimeoutException;
-import org.infinispan.util.concurrent.locks.LockManager;
-import org.infinispan.util.logging.Log;
-import org.infinispan.util.logging.LogFactory;
-import org.testng.annotations.Test;
-
-import javax.transaction.HeuristicMixedException;
-import javax.transaction.HeuristicRollbackException;
-import javax.transaction.InvalidTransactionException;
-import javax.transaction.NotSupportedException;
-import javax.transaction.RollbackException;
-import javax.transaction.SystemException;
-import javax.transaction.Transaction;
-import javax.transaction.TransactionManager;
-import java.util.HashMap;
-import java.util.Map;
-
-import static org.testng.Assert.assertEquals;
-
-/**
- *
- * @author Mircea.Markus at jboss.com
- * @since 4.2
- */
- at Test (testName = "tx.timeout.TxAndInvalidationTimeoutTest", groups = "functional")
-public class TxAndInvalidationTimeoutTest extends MultipleCacheManagersTest {
-
-   private static Log log = LogFactory.getLog(TxAndInvalidationTimeoutTest.class);
-
-   private LockManager lm1;
-   private LockManager lm0;
-   private TransactionTable txTable0;
-   private TransactionTable txTable1;
-   private TransactionManager tm;
-   private TxStatusInterceptor txStatus = new TxStatusInterceptor();
-
-   @Override
-   protected void createCacheManagers() throws Throwable {
-      Configuration defaultConfig = getDefaultConfig();
-      defaultConfig.setLockAcquisitionTimeout(500);
-      defaultConfig.setUseLockStriping(false);
-      addClusterEnabledCacheManager(defaultConfig);
-      addClusterEnabledCacheManager(defaultConfig);
-      lm0 = TestingUtil.extractLockManager(cache(0));
-      lm1 = TestingUtil.extractLockManager(cache(1));
-      txTable0 = TestingUtil.getTransactionTable(cache(0));
-      txTable1 = TestingUtil.getTransactionTable(cache(1));
-      tm = cache(0).getAdvancedCache().getTransactionManager();
-      cache(1).getAdvancedCache().addInterceptor(txStatus, 0);
-      TestingUtil.blockUntilViewReceived(cache(0), 2, 10000);
-   }
-
-   protected Configuration getDefaultConfig() {
-      return getDefaultClusteredConfig(Configuration.CacheMode.INVALIDATION_SYNC, true);
-   }
-
-   public void testPutTimeoutsInTx() throws Exception {
-      runAssertion(new CacheOperation() {
-         @Override
-         public void execute() {
-            cache(0).put("k1", "v2222");
-         }
-      });
-   }
-
-   public void testRemoveTimeoutsInTx() throws Exception {
-      runAssertion(new CacheOperation() {
-         @Override
-         public void execute() {
-            cache(0).remove("k1");
-         }
-      });
-   }
-
-   public void testPutAllTimeoutsInTx() throws Exception {
-      runAssertion(new CacheOperation() {
-         @Override
-         public void execute() {
-            Map toAdd = new HashMap();
-            toAdd.put("k1", "v22222");
-            cache(0).putAll(toAdd);
-         }
-      });
-   }
-
-
-   private void runAssertion(CacheOperation operation) throws NotSupportedException, SystemException, HeuristicMixedException, HeuristicRollbackException, InvalidTransactionException, RollbackException {
-      txStatus.reset();
-      tm.begin();
-      cache(1).put("k1", "v1");
-      Transaction k1LockOwner = tm.suspend();
-      assert lm1.isLocked("k1");
-
-      assertEquals(1, txTable1.getLocalTxCount());
-      tm.begin();
-      cache(0).put("k2", "v2");
-      assert lm0.isLocked("k2");
-      assert !lm1.isLocked("k2");
-
-      operation.execute();
-
-      assertEquals(1, txTable1.getLocalTxCount());
-      assertEquals(1, txTable0.getLocalTxCount());
-
-
-      log.trace("Before commit");
-
-      try {
-         tm.commit();
-         assert false;
-      } catch (RollbackException re) {
-         //expected
-      }
-      assert txStatus.teReceived;
-      //expect 1 as k1 is locked by the other tx
-      assertEquals(txStatus.numLocksAfterTeOnInvalidate, 1, "This would make sure that locks are being released quickly, not waiting for a remote rollback to happen");
-
-      assertEquals(0, txTable0.getLocalTxCount());
-      assertEquals(1, txTable1.getLocalTxCount());
-
-      log.trace("Right before second commit");
-      tm.resume(k1LockOwner);
-      tm.commit();
-      assertEquals(null, cache(0).get("k1"));
-      assertEquals("v1", cache(1).get("k1"));
-      assertEquals(0, txTable1.getLocalTxCount());
-      assertEquals(0, txTable1.getLocalTxCount());
-      assertEquals(0, lm0.getNumberOfLocksHeld());
-      assertEquals(0, lm1.getNumberOfLocksHeld());
-   }
-
-   private class TxStatusInterceptor extends CommandInterceptor {
-
-      private boolean teReceived;
-
-      private int numLocksAfterTeOnInvalidate;
-
-      @Override
-      public Object visitInvalidateCommand(InvocationContext ctx, InvalidateCommand invalidateCommand) throws Throwable {
-         try {
-            return invokeNextInterceptor(ctx, invalidateCommand);
-         } catch (TimeoutException te) {
-            numLocksAfterTeOnInvalidate = lm1.getNumberOfLocksHeld();
-            teReceived = true;
-            throw te;
-         }
-      }
-
-      @Override
-      protected Object handleDefault(InvocationContext ctx, VisitableCommand command) throws Throwable {
-         return super.handleDefault(ctx, command);
-      }
-
-      public void reset() {
-         this.teReceived = false;
-         this.numLocksAfterTeOnInvalidate = -1;
-      }
-   }
-
-   public interface CacheOperation {
-
-      public abstract void execute();
-   }
-}

Copied: trunk/core/src/test/java/org/infinispan/tx/exception/TxAndInvalidationTimeoutTest.java (from rev 2385, branches/4.2.x/core/src/test/java/org/infinispan/tx/exception/TxAndInvalidationTimeoutTest.java)
===================================================================
--- trunk/core/src/test/java/org/infinispan/tx/exception/TxAndInvalidationTimeoutTest.java	                        (rev 0)
+++ trunk/core/src/test/java/org/infinispan/tx/exception/TxAndInvalidationTimeoutTest.java	2010-09-15 19:09:38 UTC (rev 2386)
@@ -0,0 +1,174 @@
+package org.infinispan.tx.exception;
+
+import org.infinispan.commands.VisitableCommand;
+import org.infinispan.commands.write.InvalidateCommand;
+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.TestingUtil;
+import org.infinispan.transaction.xa.TransactionTable;
+import org.infinispan.util.concurrent.TimeoutException;
+import org.infinispan.util.concurrent.locks.LockManager;
+import org.infinispan.util.logging.Log;
+import org.infinispan.util.logging.LogFactory;
+import org.testng.annotations.Test;
+
+import javax.transaction.HeuristicMixedException;
+import javax.transaction.HeuristicRollbackException;
+import javax.transaction.InvalidTransactionException;
+import javax.transaction.NotSupportedException;
+import javax.transaction.RollbackException;
+import javax.transaction.SystemException;
+import javax.transaction.Transaction;
+import javax.transaction.TransactionManager;
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.testng.Assert.assertEquals;
+
+/**
+ *
+ * @author Mircea.Markus at jboss.com
+ * @since 4.2
+ */
+ at Test (testName = "tx.timeout.TxAndInvalidationTimeoutTest", groups = "functional")
+public class TxAndInvalidationTimeoutTest extends MultipleCacheManagersTest {
+
+   private static Log log = LogFactory.getLog(TxAndInvalidationTimeoutTest.class);
+
+   private LockManager lm1;
+   private LockManager lm0;
+   private TransactionTable txTable0;
+   private TransactionTable txTable1;
+   private TransactionManager tm;
+   private TxStatusInterceptor txStatus = new TxStatusInterceptor();
+
+   @Override
+   protected void createCacheManagers() throws Throwable {
+      Configuration defaultConfig = getDefaultConfig();
+      defaultConfig.setLockAcquisitionTimeout(500);
+      defaultConfig.setUseLockStriping(false);
+      addClusterEnabledCacheManager(defaultConfig);
+      addClusterEnabledCacheManager(defaultConfig);
+      lm0 = TestingUtil.extractLockManager(cache(0));
+      lm1 = TestingUtil.extractLockManager(cache(1));
+      txTable0 = TestingUtil.getTransactionTable(cache(0));
+      txTable1 = TestingUtil.getTransactionTable(cache(1));
+      tm = cache(0).getAdvancedCache().getTransactionManager();
+      cache(1).getAdvancedCache().addInterceptor(txStatus, 0);
+      TestingUtil.blockUntilViewReceived(cache(0), 2, 10000);
+   }
+
+   protected Configuration getDefaultConfig() {
+      return getDefaultClusteredConfig(Configuration.CacheMode.INVALIDATION_SYNC, true);
+   }
+
+   public void testPutTimeoutsInTx() throws Exception {
+      runAssertion(new CacheOperation() {
+         @Override
+         public void execute() {
+            cache(0).put("k1", "v2222");
+         }
+      });
+   }
+
+   public void testRemoveTimeoutsInTx() throws Exception {
+      runAssertion(new CacheOperation() {
+         @Override
+         public void execute() {
+            cache(0).remove("k1");
+         }
+      });
+   }
+
+   public void testPutAllTimeoutsInTx() throws Exception {
+      runAssertion(new CacheOperation() {
+         @Override
+         public void execute() {
+            Map toAdd = new HashMap();
+            toAdd.put("k1", "v22222");
+            cache(0).putAll(toAdd);
+         }
+      });
+   }
+
+
+   private void runAssertion(CacheOperation operation) throws NotSupportedException, SystemException, HeuristicMixedException, HeuristicRollbackException, InvalidTransactionException, RollbackException {
+      txStatus.reset();
+      tm.begin();
+      cache(1).put("k1", "v1");
+      Transaction k1LockOwner = tm.suspend();
+      assert lm1.isLocked("k1");
+
+      assertEquals(1, txTable1.getLocalTxCount());
+      tm.begin();
+      cache(0).put("k2", "v2");
+      assert lm0.isLocked("k2");
+      assert !lm1.isLocked("k2");
+
+      operation.execute();
+
+      assertEquals(1, txTable1.getLocalTxCount());
+      assertEquals(1, txTable0.getLocalTxCount());
+
+
+      log.trace("Before commit");
+
+      try {
+         tm.commit();
+         assert false;
+      } catch (RollbackException re) {
+         //expected
+      }
+      assert txStatus.teReceived;
+      //expect 1 as k1 is locked by the other tx
+      assertEquals(txStatus.numLocksAfterTeOnInvalidate, 1, "This would make sure that locks are being released quickly, not waiting for a remote rollback to happen");
+
+      assertEquals(0, txTable0.getLocalTxCount());
+      assertEquals(1, txTable1.getLocalTxCount());
+
+      log.trace("Right before second commit");
+      tm.resume(k1LockOwner);
+      tm.commit();
+      assertEquals(null, cache(0).get("k1"));
+      assertEquals("v1", cache(1).get("k1"));
+      assertEquals(0, txTable1.getLocalTxCount());
+      assertEquals(0, txTable1.getLocalTxCount());
+      assertEquals(0, lm0.getNumberOfLocksHeld());
+      assertEquals(0, lm1.getNumberOfLocksHeld());
+   }
+
+   private class TxStatusInterceptor extends CommandInterceptor {
+
+      private boolean teReceived;
+
+      private int numLocksAfterTeOnInvalidate;
+
+      @Override
+      public Object visitInvalidateCommand(InvocationContext ctx, InvalidateCommand invalidateCommand) throws Throwable {
+         try {
+            return invokeNextInterceptor(ctx, invalidateCommand);
+         } catch (TimeoutException te) {
+            numLocksAfterTeOnInvalidate = lm1.getNumberOfLocksHeld();
+            teReceived = true;
+            throw te;
+         }
+      }
+
+      @Override
+      protected Object handleDefault(InvocationContext ctx, VisitableCommand command) throws Throwable {
+         return super.handleDefault(ctx, command);
+      }
+
+      public void reset() {
+         this.teReceived = false;
+         this.numLocksAfterTeOnInvalidate = -1;
+      }
+   }
+
+   public interface CacheOperation {
+
+      public abstract void execute();
+   }
+}

Deleted: trunk/core/src/test/java/org/infinispan/tx/exception/TxAndRemoteTimeoutExceptionTest.java
===================================================================
--- branches/4.2.x/core/src/test/java/org/infinispan/tx/exception/TxAndRemoteTimeoutExceptionTest.java	2010-09-15 16:19:59 UTC (rev 2385)
+++ trunk/core/src/test/java/org/infinispan/tx/exception/TxAndRemoteTimeoutExceptionTest.java	2010-09-15 19:09:38 UTC (rev 2386)
@@ -1,200 +0,0 @@
-package org.infinispan.tx.exception;
-
-import org.infinispan.commands.VisitableCommand;
-import org.infinispan.commands.tx.PrepareCommand;
-import org.infinispan.config.Configuration;
-import org.infinispan.context.InvocationContext;
-import org.infinispan.context.impl.TxInvocationContext;
-import org.infinispan.interceptors.base.CommandInterceptor;
-import org.infinispan.test.MultipleCacheManagersTest;
-import org.infinispan.test.TestingUtil;
-import org.infinispan.transaction.xa.TransactionTable;
-import org.infinispan.util.concurrent.TimeoutException;
-import org.infinispan.util.concurrent.locks.LockManager;
-import org.infinispan.util.logging.Log;
-import org.infinispan.util.logging.LogFactory;
-import org.testng.annotations.Test;
-
-import javax.transaction.HeuristicMixedException;
-import javax.transaction.HeuristicRollbackException;
-import javax.transaction.InvalidTransactionException;
-import javax.transaction.NotSupportedException;
-import javax.transaction.RollbackException;
-import javax.transaction.SystemException;
-import javax.transaction.Transaction;
-import javax.transaction.TransactionManager;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import static org.testng.Assert.assertEquals;
-
-/**
- * Tester for https://jira.jboss.org/browse/ISPN-629.
- *
- * @author Mircea.Markus at jboss.com
- * @since 4.2
- */
- at Test(groups = "functional", testName = "tx.TestTxAndRemoteTimeoutException")
-public class TxAndRemoteTimeoutExceptionTest extends MultipleCacheManagersTest {
-
-   private static Log log = LogFactory.getLog(TxAndRemoteTimeoutExceptionTest.class);
-
-   private LockManager lm1;
-   private LockManager lm0;
-   private TransactionTable txTable0;
-   private TransactionTable txTable1;
-   private TransactionManager tm;
-   private TxStatusInterceptor txStatus = new TxStatusInterceptor();
-
-   @Override
-   protected void createCacheManagers() throws Throwable {
-      Configuration defaultConfig = getDefaultConfig();
-      defaultConfig.setLockAcquisitionTimeout(500);
-      defaultConfig.setUseLockStriping(false);
-      addClusterEnabledCacheManager(defaultConfig);
-      addClusterEnabledCacheManager(defaultConfig);
-      lm0 = TestingUtil.extractLockManager(cache(0));
-      lm1 = TestingUtil.extractLockManager(cache(1));
-      txTable0 = TestingUtil.getTransactionTable(cache(0));
-      txTable1 = TestingUtil.getTransactionTable(cache(1));
-      tm = cache(0).getAdvancedCache().getTransactionManager();
-      cache(1).getAdvancedCache().addInterceptor(txStatus, 0);
-      TestingUtil.blockUntilViewReceived(cache(0), 2, 10000);
-   }
-
-   protected Configuration getDefaultConfig() {
-      return getDefaultClusteredConfig(Configuration.CacheMode.REPL_SYNC, true);
-   }
-
-   public void testClearTimeoutsInTx() throws Exception {
-      cache(0).put("k1", "value");
-      runAssertion(new CacheOperation() {
-         @Override
-         public void execute() {
-            cache(0).clear();
-         }
-      });
-   }
-
-   public void testPutTimeoutsInTx() throws Exception {
-      runAssertion(new CacheOperation() {
-         @Override
-         public void execute() {
-            cache(0).put("k1", "v2222");
-         }
-      });
-   }
-
-   public void testRemoveTimeoutsInTx() throws Exception {
-      runAssertion(new CacheOperation() {
-         @Override
-         public void execute() {
-            cache(0).remove("k1");
-         }
-      });
-   }
-
-   public void testReplaceTimeoutsInTx() throws Exception {
-      cache(1).put("k1", "value");
-      runAssertion(new CacheOperation() {
-         @Override
-         public void execute() {
-            cache(0).replace("k1", "newValue");
-         }
-      });
-   }
-
-   public void testPutAllTimeoutsInTx() throws Exception {
-      runAssertion(new CacheOperation() {
-         @Override
-         public void execute() {
-            Map toAdd = new HashMap();
-            toAdd.put("k1", "v22222");
-            cache(0).putAll(toAdd);
-         }
-      });
-   }
-
-
-   private void runAssertion(CacheOperation operation) throws NotSupportedException, SystemException, HeuristicMixedException, HeuristicRollbackException, InvalidTransactionException, RollbackException {
-      txStatus.reset();
-      tm.begin();
-      cache(1).put("k1", "v1");
-      Transaction k1LockOwner = tm.suspend();
-      assert lm1.isLocked("k1");
-
-      assertEquals(1, txTable1.getLocalTxCount());
-      tm.begin();
-      cache(0).put("k2", "v2");
-      assert lm0.isLocked("k2");
-      assert !lm1.isLocked("k2");
-
-      operation.execute();
-
-      assertEquals(1, txTable1.getLocalTxCount());
-      assertEquals(1, txTable0.getLocalTxCount());
-
-
-      try {
-         tm.commit();
-         assert false;
-      } catch (RollbackException re) {
-         //expected
-      }
-      assert txStatus.teReceived;
-      assert txStatus.isTxInTableAfterTeOnPrepare;
-      //expect 1 as k1 is locked by the other tx
-      assertEquals(txStatus.numLocksAfterTeOnPrepare, 1, "This would make sure that locks are being released quickly, not waiting for a remote rollback to happen");
-
-      assertEquals(0, txTable0.getLocalTxCount());
-      assertEquals(1, txTable1.getLocalTxCount());
-
-      log.trace("Right before second commit");
-      tm.resume(k1LockOwner);
-      tm.commit();
-      assertEquals("v1", cache(0).get("k1"));
-      assertEquals("v1", cache(1).get("k1"));
-      assertEquals(0, txTable1.getLocalTxCount());
-      assertEquals(0, txTable1.getLocalTxCount());
-      assertEquals(0, lm0.getNumberOfLocksHeld());
-      assertEquals(0, lm1.getNumberOfLocksHeld());
-   }
-
-   private class TxStatusInterceptor extends CommandInterceptor {
-
-      private boolean teReceived;
-
-      private boolean isTxInTableAfterTeOnPrepare;
-
-      private int numLocksAfterTeOnPrepare;
-
-      @Override
-      public Object visitPrepareCommand(TxInvocationContext ctx, PrepareCommand command) throws Throwable {
-         try {
-            return invokeNextInterceptor(ctx, command);
-         } catch (TimeoutException te) {
-            numLocksAfterTeOnPrepare = lm1.getNumberOfLocksHeld();
-            isTxInTableAfterTeOnPrepare = txTable1.containRemoteTx(ctx.getGlobalTransaction());
-            teReceived = true;
-            throw te;
-         }
-      }
-
-      @Override
-      protected Object handleDefault(InvocationContext ctx, VisitableCommand command) throws Throwable {
-         return super.handleDefault(ctx, command);
-      }
-
-      public void reset() {
-         this.teReceived = false;
-         this.isTxInTableAfterTeOnPrepare = false;
-         this.numLocksAfterTeOnPrepare = -1;
-      }
-   }
-
-   public interface CacheOperation {
-
-      public abstract void execute();
-   }
-}

Copied: trunk/core/src/test/java/org/infinispan/tx/exception/TxAndRemoteTimeoutExceptionTest.java (from rev 2385, branches/4.2.x/core/src/test/java/org/infinispan/tx/exception/TxAndRemoteTimeoutExceptionTest.java)
===================================================================
--- trunk/core/src/test/java/org/infinispan/tx/exception/TxAndRemoteTimeoutExceptionTest.java	                        (rev 0)
+++ trunk/core/src/test/java/org/infinispan/tx/exception/TxAndRemoteTimeoutExceptionTest.java	2010-09-15 19:09:38 UTC (rev 2386)
@@ -0,0 +1,200 @@
+package org.infinispan.tx.exception;
+
+import org.infinispan.commands.VisitableCommand;
+import org.infinispan.commands.tx.PrepareCommand;
+import org.infinispan.config.Configuration;
+import org.infinispan.context.InvocationContext;
+import org.infinispan.context.impl.TxInvocationContext;
+import org.infinispan.interceptors.base.CommandInterceptor;
+import org.infinispan.test.MultipleCacheManagersTest;
+import org.infinispan.test.TestingUtil;
+import org.infinispan.transaction.xa.TransactionTable;
+import org.infinispan.util.concurrent.TimeoutException;
+import org.infinispan.util.concurrent.locks.LockManager;
+import org.infinispan.util.logging.Log;
+import org.infinispan.util.logging.LogFactory;
+import org.testng.annotations.Test;
+
+import javax.transaction.HeuristicMixedException;
+import javax.transaction.HeuristicRollbackException;
+import javax.transaction.InvalidTransactionException;
+import javax.transaction.NotSupportedException;
+import javax.transaction.RollbackException;
+import javax.transaction.SystemException;
+import javax.transaction.Transaction;
+import javax.transaction.TransactionManager;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.testng.Assert.assertEquals;
+
+/**
+ * Tester for https://jira.jboss.org/browse/ISPN-629.
+ *
+ * @author Mircea.Markus at jboss.com
+ * @since 4.2
+ */
+ at Test(groups = "functional", testName = "tx.TestTxAndRemoteTimeoutException")
+public class TxAndRemoteTimeoutExceptionTest extends MultipleCacheManagersTest {
+
+   private static Log log = LogFactory.getLog(TxAndRemoteTimeoutExceptionTest.class);
+
+   private LockManager lm1;
+   private LockManager lm0;
+   private TransactionTable txTable0;
+   private TransactionTable txTable1;
+   private TransactionManager tm;
+   private TxStatusInterceptor txStatus = new TxStatusInterceptor();
+
+   @Override
+   protected void createCacheManagers() throws Throwable {
+      Configuration defaultConfig = getDefaultConfig();
+      defaultConfig.setLockAcquisitionTimeout(500);
+      defaultConfig.setUseLockStriping(false);
+      addClusterEnabledCacheManager(defaultConfig);
+      addClusterEnabledCacheManager(defaultConfig);
+      lm0 = TestingUtil.extractLockManager(cache(0));
+      lm1 = TestingUtil.extractLockManager(cache(1));
+      txTable0 = TestingUtil.getTransactionTable(cache(0));
+      txTable1 = TestingUtil.getTransactionTable(cache(1));
+      tm = cache(0).getAdvancedCache().getTransactionManager();
+      cache(1).getAdvancedCache().addInterceptor(txStatus, 0);
+      TestingUtil.blockUntilViewReceived(cache(0), 2, 10000);
+   }
+
+   protected Configuration getDefaultConfig() {
+      return getDefaultClusteredConfig(Configuration.CacheMode.REPL_SYNC, true);
+   }
+
+   public void testClearTimeoutsInTx() throws Exception {
+      cache(0).put("k1", "value");
+      runAssertion(new CacheOperation() {
+         @Override
+         public void execute() {
+            cache(0).clear();
+         }
+      });
+   }
+
+   public void testPutTimeoutsInTx() throws Exception {
+      runAssertion(new CacheOperation() {
+         @Override
+         public void execute() {
+            cache(0).put("k1", "v2222");
+         }
+      });
+   }
+
+   public void testRemoveTimeoutsInTx() throws Exception {
+      runAssertion(new CacheOperation() {
+         @Override
+         public void execute() {
+            cache(0).remove("k1");
+         }
+      });
+   }
+
+   public void testReplaceTimeoutsInTx() throws Exception {
+      cache(1).put("k1", "value");
+      runAssertion(new CacheOperation() {
+         @Override
+         public void execute() {
+            cache(0).replace("k1", "newValue");
+         }
+      });
+   }
+
+   public void testPutAllTimeoutsInTx() throws Exception {
+      runAssertion(new CacheOperation() {
+         @Override
+         public void execute() {
+            Map toAdd = new HashMap();
+            toAdd.put("k1", "v22222");
+            cache(0).putAll(toAdd);
+         }
+      });
+   }
+
+
+   private void runAssertion(CacheOperation operation) throws NotSupportedException, SystemException, HeuristicMixedException, HeuristicRollbackException, InvalidTransactionException, RollbackException {
+      txStatus.reset();
+      tm.begin();
+      cache(1).put("k1", "v1");
+      Transaction k1LockOwner = tm.suspend();
+      assert lm1.isLocked("k1");
+
+      assertEquals(1, txTable1.getLocalTxCount());
+      tm.begin();
+      cache(0).put("k2", "v2");
+      assert lm0.isLocked("k2");
+      assert !lm1.isLocked("k2");
+
+      operation.execute();
+
+      assertEquals(1, txTable1.getLocalTxCount());
+      assertEquals(1, txTable0.getLocalTxCount());
+
+
+      try {
+         tm.commit();
+         assert false;
+      } catch (RollbackException re) {
+         //expected
+      }
+      assert txStatus.teReceived;
+      assert txStatus.isTxInTableAfterTeOnPrepare;
+      //expect 1 as k1 is locked by the other tx
+      assertEquals(txStatus.numLocksAfterTeOnPrepare, 1, "This would make sure that locks are being released quickly, not waiting for a remote rollback to happen");
+
+      assertEquals(0, txTable0.getLocalTxCount());
+      assertEquals(1, txTable1.getLocalTxCount());
+
+      log.trace("Right before second commit");
+      tm.resume(k1LockOwner);
+      tm.commit();
+      assertEquals("v1", cache(0).get("k1"));
+      assertEquals("v1", cache(1).get("k1"));
+      assertEquals(0, txTable1.getLocalTxCount());
+      assertEquals(0, txTable1.getLocalTxCount());
+      assertEquals(0, lm0.getNumberOfLocksHeld());
+      assertEquals(0, lm1.getNumberOfLocksHeld());
+   }
+
+   private class TxStatusInterceptor extends CommandInterceptor {
+
+      private boolean teReceived;
+
+      private boolean isTxInTableAfterTeOnPrepare;
+
+      private int numLocksAfterTeOnPrepare;
+
+      @Override
+      public Object visitPrepareCommand(TxInvocationContext ctx, PrepareCommand command) throws Throwable {
+         try {
+            return invokeNextInterceptor(ctx, command);
+         } catch (TimeoutException te) {
+            numLocksAfterTeOnPrepare = lm1.getNumberOfLocksHeld();
+            isTxInTableAfterTeOnPrepare = txTable1.containRemoteTx(ctx.getGlobalTransaction());
+            teReceived = true;
+            throw te;
+         }
+      }
+
+      @Override
+      protected Object handleDefault(InvocationContext ctx, VisitableCommand command) throws Throwable {
+         return super.handleDefault(ctx, command);
+      }
+
+      public void reset() {
+         this.teReceived = false;
+         this.isTxInTableAfterTeOnPrepare = false;
+         this.numLocksAfterTeOnPrepare = -1;
+      }
+   }
+
+   public interface CacheOperation {
+
+      public abstract void execute();
+   }
+}

Deleted: trunk/core/src/test/java/org/infinispan/tx/exception/TxAndTimeoutExceptionTest.java
===================================================================
--- branches/4.2.x/core/src/test/java/org/infinispan/tx/exception/TxAndTimeoutExceptionTest.java	2010-09-15 16:19:59 UTC (rev 2385)
+++ trunk/core/src/test/java/org/infinispan/tx/exception/TxAndTimeoutExceptionTest.java	2010-09-15 19:09:38 UTC (rev 2386)
@@ -1,143 +0,0 @@
-package org.infinispan.tx.exception;
-
-import org.infinispan.config.Configuration;
-import org.infinispan.manager.EmbeddedCacheManager;
-import org.infinispan.test.SingleCacheManagerTest;
-import org.infinispan.test.TestingUtil;
-import org.infinispan.test.fwk.TestCacheManagerFactory;
-import org.infinispan.transaction.xa.TransactionTable;
-import org.infinispan.util.concurrent.TimeoutException;
-import org.infinispan.util.concurrent.locks.LockManager;
-import org.testng.annotations.Test;
-
-import javax.transaction.Status;
-import javax.transaction.Transaction;
-import javax.transaction.TransactionManager;
-import java.util.HashMap;
-import java.util.Map;
-
-import static org.testng.Assert.assertEquals;
-
-/**
- * Tester for https://jira.jboss.org/browse/ISPN-629.
- *
- * @author Mircea.Markus at jboss.com
- * @since 4.2
- */
- at Test(testName = "tx.TxAndTimeoutExceptionTest", groups = "functional")
-public class TxAndTimeoutExceptionTest extends SingleCacheManagerTest {
-
-   @Override
-   protected EmbeddedCacheManager createCacheManager() throws Exception {
-      Configuration config = getDefaultStandaloneConfig(true);
-      config.setUseLockStriping(false);
-      config.setLockAcquisitionTimeout(1000);
-      EmbeddedCacheManager cm = TestCacheManagerFactory.createCacheManager(config, true);
-      cache = cm.getCache();
-      return cm;
-   }
-
-
-   public void testPutTimeoutsInTx() throws Exception {
-      assertExpectedBehavior(new CacheOperation() {
-         @Override
-         public void execute() {
-            cache.put("k1", "v2222");
-         }
-      });
-   }
-
-   public void testRemoveTimeoutsInTx() throws Exception {
-      assertExpectedBehavior(new CacheOperation() {
-         @Override
-         public void execute() {
-            cache.remove("k1");
-         }
-      });
-   }
-
-   public void testClearTimeoutsInTx() throws Exception {
-      cache.put("k1", "value");
-      assertExpectedBehavior(new CacheOperation() {
-         @Override
-         public void execute() {
-            cache.clear();
-         }
-      });
-   }
-
-   public void testReplaceTimeoutsInTx() throws Exception {
-      assertExpectedBehavior(new CacheOperation() {
-         @Override
-         public void execute() {
-            cache.replace("k1", "newValue");
-         }
-      });
-   }
-
-   public void testPutAllTimeoutsInTx() throws Exception {
-      assertExpectedBehavior(new CacheOperation() {
-         @Override
-         public void execute() {
-            Map toAdd = new HashMap();
-            toAdd.put("k1", "v22222");
-            cache.putAll(toAdd);
-         }
-      });
-   }
-
-   private void assertExpectedBehavior(CacheOperation op) throws Exception {
-      LockManager lm = TestingUtil.extractLockManager(cache);
-      TransactionTable txTable = TestingUtil.getTransactionTable(cache);
-      TransactionManager tm = cache.getAdvancedCache().getTransactionManager();
-      tm.begin();
-      cache.put("k1", "v1");
-      Transaction k1LockOwner = tm.suspend();
-      assert lm.isLocked("k1");
-
-      assertEquals(1, txTable.getLocalTxCount());
-      tm.begin();
-      cache.put("k2", "v2");
-      assert lm.isLocked("k2");
-      assertEquals(2, txTable.getLocalTxCount());
-      try {
-         op.execute();
-         assert false : "Timeout exception expected";
-      } catch (TimeoutException e) {
-         //expected
-      }
-
-      //make sure that locks acquired by that tx were released even before the transaction is rolled back, the tx object
-      //was marked for rollback 
-      Transaction transaction = tm.getTransaction();
-      assert transaction != null;
-      assert transaction.getStatus() == Status.STATUS_MARKED_ROLLBACK;
-      assert !lm.isLocked("k2");
-      assert lm.isLocked("k1");
-      try {
-         cache.put("k3", "v3");
-         assert false;
-      } catch (IllegalStateException e) {
-         //expected
-      }
-      assertEquals(txTable.getLocalTxCount(), 2);
-
-      //now the TM is expected to rollback the tx
-      tm.rollback();
-      assertEquals(txTable.getLocalTxCount(), 1);
-
-      tm.resume(k1LockOwner);
-      tm.commit();
-
-      //now test that the other tx works as expected
-      assertEquals(0, txTable.getLocalTxCount());
-      assertEquals(cache.get("k1"), "v1");
-      assert !lm.isLocked("k1");
-      assertEquals(txTable.getLocalTxCount(), 0);
-   }
-
-   public interface CacheOperation {
-
-      public abstract void execute();
-   }
-}

Copied: trunk/core/src/test/java/org/infinispan/tx/exception/TxAndTimeoutExceptionTest.java (from rev 2385, branches/4.2.x/core/src/test/java/org/infinispan/tx/exception/TxAndTimeoutExceptionTest.java)
===================================================================
--- trunk/core/src/test/java/org/infinispan/tx/exception/TxAndTimeoutExceptionTest.java	                        (rev 0)
+++ trunk/core/src/test/java/org/infinispan/tx/exception/TxAndTimeoutExceptionTest.java	2010-09-15 19:09:38 UTC (rev 2386)
@@ -0,0 +1,143 @@
+package org.infinispan.tx.exception;
+
+import org.infinispan.config.Configuration;
+import org.infinispan.manager.EmbeddedCacheManager;
+import org.infinispan.test.SingleCacheManagerTest;
+import org.infinispan.test.TestingUtil;
+import org.infinispan.test.fwk.TestCacheManagerFactory;
+import org.infinispan.transaction.xa.TransactionTable;
+import org.infinispan.util.concurrent.TimeoutException;
+import org.infinispan.util.concurrent.locks.LockManager;
+import org.testng.annotations.Test;
+
+import javax.transaction.Status;
+import javax.transaction.Transaction;
+import javax.transaction.TransactionManager;
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.testng.Assert.assertEquals;
+
+/**
+ * Tester for https://jira.jboss.org/browse/ISPN-629.
+ *
+ * @author Mircea.Markus at jboss.com
+ * @since 4.2
+ */
+ at Test(testName = "tx.TxAndTimeoutExceptionTest", groups = "functional")
+public class TxAndTimeoutExceptionTest extends SingleCacheManagerTest {
+
+   @Override
+   protected EmbeddedCacheManager createCacheManager() throws Exception {
+      Configuration config = getDefaultStandaloneConfig(true);
+      config.setUseLockStriping(false);
+      config.setLockAcquisitionTimeout(1000);
+      EmbeddedCacheManager cm = TestCacheManagerFactory.createCacheManager(config, true);
+      cache = cm.getCache();
+      return cm;
+   }
+
+
+   public void testPutTimeoutsInTx() throws Exception {
+      assertExpectedBehavior(new CacheOperation() {
+         @Override
+         public void execute() {
+            cache.put("k1", "v2222");
+         }
+      });
+   }
+
+   public void testRemoveTimeoutsInTx() throws Exception {
+      assertExpectedBehavior(new CacheOperation() {
+         @Override
+         public void execute() {
+            cache.remove("k1");
+         }
+      });
+   }
+
+   public void testClearTimeoutsInTx() throws Exception {
+      cache.put("k1", "value");
+      assertExpectedBehavior(new CacheOperation() {
+         @Override
+         public void execute() {
+            cache.clear();
+         }
+      });
+   }
+
+   public void testReplaceTimeoutsInTx() throws Exception {
+      assertExpectedBehavior(new CacheOperation() {
+         @Override
+         public void execute() {
+            cache.replace("k1", "newValue");
+         }
+      });
+   }
+
+   public void testPutAllTimeoutsInTx() throws Exception {
+      assertExpectedBehavior(new CacheOperation() {
+         @Override
+         public void execute() {
+            Map toAdd = new HashMap();
+            toAdd.put("k1", "v22222");
+            cache.putAll(toAdd);
+         }
+      });
+   }
+
+   private void assertExpectedBehavior(CacheOperation op) throws Exception {
+      LockManager lm = TestingUtil.extractLockManager(cache);
+      TransactionTable txTable = TestingUtil.getTransactionTable(cache);
+      TransactionManager tm = cache.getAdvancedCache().getTransactionManager();
+      tm.begin();
+      cache.put("k1", "v1");
+      Transaction k1LockOwner = tm.suspend();
+      assert lm.isLocked("k1");
+
+      assertEquals(1, txTable.getLocalTxCount());
+      tm.begin();
+      cache.put("k2", "v2");
+      assert lm.isLocked("k2");
+      assertEquals(2, txTable.getLocalTxCount());
+      try {
+         op.execute();
+         assert false : "Timeout exception expected";
+      } catch (TimeoutException e) {
+         //expected
+      }
+
+      //make sure that locks acquired by that tx were released even before the transaction is rolled back, the tx object
+      //was marked for rollback 
+      Transaction transaction = tm.getTransaction();
+      assert transaction != null;
+      assert transaction.getStatus() == Status.STATUS_MARKED_ROLLBACK;
+      assert !lm.isLocked("k2");
+      assert lm.isLocked("k1");
+      try {
+         cache.put("k3", "v3");
+         assert false;
+      } catch (IllegalStateException e) {
+         //expected
+      }
+      assertEquals(txTable.getLocalTxCount(), 2);
+
+      //now the TM is expected to rollback the tx
+      tm.rollback();
+      assertEquals(txTable.getLocalTxCount(), 1);
+
+      tm.resume(k1LockOwner);
+      tm.commit();
+
+      //now test that the other tx works as expected
+      assertEquals(0, txTable.getLocalTxCount());
+      assertEquals(cache.get("k1"), "v1");
+      assert !lm.isLocked("k1");
+      assertEquals(txTable.getLocalTxCount(), 0);
+   }
+
+   public interface CacheOperation {
+
+      public abstract void execute();
+   }
+}

Copied: trunk/core/src/test/java/org/infinispan/tx/timeout (from rev 2385, branches/4.2.x/core/src/test/java/org/infinispan/tx/timeout)

Modified: trunk/core/src/test/java/org/infinispan/util/DeadlockDetectingLockManagerTest.java
===================================================================
--- trunk/core/src/test/java/org/infinispan/util/DeadlockDetectingLockManagerTest.java	2010-09-15 16:19:59 UTC (rev 2385)
+++ trunk/core/src/test/java/org/infinispan/util/DeadlockDetectingLockManagerTest.java	2010-09-15 19:09:38 UTC (rev 2386)
@@ -5,14 +5,16 @@
 import static org.easymock.EasyMock.expect;
 import static org.easymock.classextension.EasyMock.replay;
 import static org.easymock.classextension.EasyMock.verify;
+import static org.testng.Assert.assertEquals;
 
 import org.infinispan.config.Configuration;
 import org.infinispan.context.InvocationContext;
 import org.infinispan.context.impl.NonTxInvocationContext;
 import org.infinispan.context.impl.LocalTxInvocationContext;
 import org.infinispan.test.AbstractInfinispanTest;
+import org.infinispan.transaction.xa.DldGlobalTransaction;
 import org.infinispan.transaction.xa.GlobalTransactionFactory;
-import org.infinispan.transaction.xa.DeadlockDetectingGlobalTransaction;
+import org.infinispan.util.concurrent.locks.DeadlockDetectedException;
 import org.infinispan.util.concurrent.locks.DeadlockDetectingLockManager;
 import org.infinispan.util.concurrent.locks.containers.LockContainer;
 import org.testng.annotations.BeforeMethod;
@@ -34,13 +36,13 @@
    Configuration config = new Configuration();
    private LockContainer lc;
    private static final int SPIN_DURATION = 1000;
-   private DeadlockDetectingGlobalTransaction lockOwner;
+   private DldGlobalTransaction lockOwner;
 
    @BeforeMethod
    public void setUp() {
       lc = createMock(LockContainer.class);
       lockManager = new DeadlockDetectingLockManagerMock(SPIN_DURATION, true, lc, config);
-      lockOwner = (DeadlockDetectingGlobalTransaction) gtf.instantiateGlobalTransaction();
+      lockOwner = (DldGlobalTransaction) gtf.instantiateGlobalTransaction();
    }
 
 
@@ -58,7 +60,7 @@
    }
 
    public void testLockHeldByThread() throws Exception {
-      InvocationContext localTxContext = new LocalTxInvocationContext();
+      InvocationContext localTxContext = buildLocalTxIc(new DldGlobalTransaction());
 
       //this makes sure that we cannot acquire lock from the first try
       expect(lc.acquireLock("k", SPIN_DURATION, TimeUnit.MILLISECONDS)).andReturn(null);
@@ -73,31 +75,42 @@
    }
 
    public void testLocalDeadlock() throws Exception {
-      final DeadlockDetectingGlobalTransaction ddgt = (DeadlockDetectingGlobalTransaction) gtf.instantiateGlobalTransaction();
+      final DldGlobalTransaction ddgt = (DldGlobalTransaction) gtf.instantiateGlobalTransaction();
 
-      InvocationContext localTxContext = new LocalTxInvocationContext() {
-         @Override
-         public Object getLockOwner() {
-            return ddgt;
-         }
-      };
+      InvocationContext localTxContext = buildLocalTxIc(ddgt);
 
       ddgt.setCoinToss(0);
-      lockOwner.setCoinToss(-1);
-      assert ddgt.thisWillInterrupt(lockOwner);
+      lockOwner.setCoinToss(1);
+      assert ddgt.wouldLose(lockOwner);
 
       //this makes sure that we cannot acquire lock from the first try
       expect(lc.acquireLock("k", SPIN_DURATION, TimeUnit.MILLISECONDS)).andReturn(null);
       Lock mockLock = createNiceMock(Lock.class);
       expect(lc.acquireLock("k", SPIN_DURATION, TimeUnit.MILLISECONDS)).andReturn(mockLock);
       lockOwner.setRemote(false);
+      lockOwner.setLockIntention("k");
       lockManager.setOwner(lockOwner);
       lockManager.setOwnsLock(true);
       replay(lc);
-      assert lockManager.lockAndRecord("k", localTxContext);
-      assert lockManager.getDetectedLocalDeadlocks() == 1;
+      try {
+         lockManager.lockAndRecord("k", localTxContext);
+         assert false;
+      } catch (DeadlockDetectedException e) {
+         //expected
+      }
+      assertEquals(1l,lockManager.getDetectedLocalDeadlocks());
    }
 
+   private InvocationContext buildLocalTxIc(final DldGlobalTransaction ddgt) {
+      InvocationContext localTxContext = new LocalTxInvocationContext() {
+         @Override
+         public Object getLockOwner() {
+            return ddgt;
+         }
+      };
+      return localTxContext;
+   }
+
    public static class DeadlockDetectingLockManagerMock extends DeadlockDetectingLockManager {
 
       private Object owner;

Modified: trunk/core/src/test/resources/configs/named-cache-test.xml
===================================================================
--- trunk/core/src/test/resources/configs/named-cache-test.xml	2010-09-15 16:19:59 UTC (rev 2385)
+++ trunk/core/src/test/resources/configs/named-cache-test.xml	2010-09-15 19:09:38 UTC (rev 2386)
@@ -54,7 +54,7 @@
    </default>
 
    <namedCache name="transactional">
-      <transaction transactionManagerLookupClass="org.infinispan.transaction.lookup.GenericTransactionManagerLookup" useEagerLocking="true"/>
+      <transaction transactionManagerLookupClass="org.infinispan.transaction.lookup.GenericTransactionManagerLookup" useEagerLocking="true" eagerLockSingleNode="true"/>
    </namedCache>
 
    <namedCache name="syncRepl">

Modified: trunk/core/src/test/resources/log4j.xml
===================================================================
--- trunk/core/src/test/resources/log4j.xml	2010-09-15 16:19:59 UTC (rev 2385)
+++ trunk/core/src/test/resources/log4j.xml	2010-09-15 19:09:38 UTC (rev 2386)
@@ -45,7 +45,7 @@
    <!-- ================ -->
 
    <category name="org.infinispan">
-      <priority value="INFO"/>
+      <priority value="TRACE"/>
    </category>
 
    <category name="org.infinispan.profiling">
@@ -65,7 +65,7 @@
    <!-- ======================= -->
 
    <root>
-      <priority value="TRACE"/>
+      <priority value="INFO"/>
       <!--<appender-ref ref="CONSOLE"/>-->
       <appender-ref ref="FILE"/>
    </root>

Modified: trunk/lucene-directory/src/main/java/org/infinispan/lucene/readlocks/DistributedSegmentReadLocker.java
===================================================================
--- trunk/lucene-directory/src/main/java/org/infinispan/lucene/readlocks/DistributedSegmentReadLocker.java	2010-09-15 16:19:59 UTC (rev 2385)
+++ trunk/lucene-directory/src/main/java/org/infinispan/lucene/readlocks/DistributedSegmentReadLocker.java	2010-09-15 19:09:38 UTC (rev 2386)
@@ -159,12 +159,15 @@
       FileCacheKey key = new FileCacheKey(indexName, filename);
       boolean batch = cache.startBatch();
       FileMetadata file = (FileMetadata) cache.withFlags(Flag.SKIP_LOCKING).remove(key);
-      for (int i = 0; i < file.getNumberOfChunks(); i++) {
-         ChunkCacheKey chunkKey = new ChunkCacheKey(indexName, filename, i);
-         cache.withFlags(Flag.SKIP_REMOTE_LOOKUP).removeAsync(chunkKey);  
+      if (file != null) { //during optimization of index a same file could be deleted twice, so you could see a null here
+         for (int i = 0; i < file.getNumberOfChunks(); i++) {
+            ChunkCacheKey chunkKey = new ChunkCacheKey(indexName, filename, i);
+            cache.withFlags(Flag.SKIP_REMOTE_LOOKUP).removeAsync(chunkKey);
+         }
+         cache.withFlags(Flag.SKIP_REMOTE_LOOKUP).removeAsync(key);
       }
-      cache.withFlags(Flag.SKIP_REMOTE_LOOKUP).removeAsync(key);
-      //last operation, as being set as value==0 it prevents others from using it during the deletion process:
+      // last operation, as being set as value==0 it prevents others from using it during the
+      // deletion process:
       cache.withFlags(Flag.SKIP_REMOTE_LOOKUP).removeAsync(readLockKey);
       if (batch) {
          cache.endBatch(true);


Property changes on: trunk/tree
___________________________________________________________________
Name: svn:ignore
   - target
.settings
eclipse-output
test-output
output
.classpath
.project
temp-testng-customsuite.xml
*.iml
*.log

   + target
.settings
eclipse-output
test-output
output
.classpath
.project
temp-testng-customsuite.xml
*.iml
*.log
PutObjectStoreDirHere




More information about the infinispan-commits mailing list