[infinispan-commits] Infinispan SVN: r1797 - in trunk/core/src/main/java/org/infinispan: context/impl and 2 other directories.

infinispan-commits at lists.jboss.org infinispan-commits at lists.jboss.org
Mon May 17 11:10:56 EDT 2010


Author: manik.surtani at jboss.com
Date: 2010-05-17 11:10:55 -0400 (Mon, 17 May 2010)
New Revision: 1797

Modified:
   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/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/interceptors/InvocationContextInterceptor.java
   trunk/core/src/main/java/org/infinispan/transaction/xa/CacheTransaction.java
   trunk/core/src/main/java/org/infinispan/transaction/xa/RemoteTransaction.java
   trunk/core/src/main/java/org/infinispan/transaction/xa/TransactionXaAdapter.java
Log:
[ISPN-444] (Release lock when thread is interrupted) a better fix involving a trap in the InvocationContextInterceptor

Modified: trunk/core/src/main/java/org/infinispan/context/InvocationContext.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/context/InvocationContext.java	2010-05-17 15:03:20 UTC (rev 1796)
+++ trunk/core/src/main/java/org/infinispan/context/InvocationContext.java	2010-05-17 15:10:55 UTC (rev 1797)
@@ -21,6 +21,9 @@
  */
 package org.infinispan.context;
 
+import java.util.Collections;
+import java.util.Set;
+
 /**
  * A context that contains information pertaining to a given invocation.  These contexts typically have the lifespan of
  * a single invocation.
@@ -55,6 +58,13 @@
 
    void setUseFutureReturnType(boolean useFutureReturnType);
 
-   public InvocationContext clone();
+   InvocationContext clone();
 
+   /**
+    * Retrieves a set of keys added to the context within the scope of the current ivocation 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.
+    */
+   Set<Object> getKeysAddedInCurrentInvocation();
 }

Modified: trunk/core/src/main/java/org/infinispan/context/impl/AbstractInvocationContext.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/context/impl/AbstractInvocationContext.java	2010-05-17 15:03:20 UTC (rev 1796)
+++ trunk/core/src/main/java/org/infinispan/context/impl/AbstractInvocationContext.java	2010-05-17 15:10:55 UTC (rev 1797)
@@ -3,11 +3,14 @@
 import org.infinispan.container.entries.CacheEntry;
 import org.infinispan.context.Flag;
 import org.infinispan.context.InvocationContext;
+import org.infinispan.util.BidirectionalLinkedHashMap;
 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;
 
 /**
@@ -20,6 +23,7 @@
 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.
@@ -108,6 +112,7 @@
    public void reset() {
       flags = null;
       contextFlags = 0;
+      keysAddedInCurrentInvocation = null;
    }
 
    public boolean isFlagsUninitialized() {
@@ -143,11 +148,28 @@
       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!");

Modified: trunk/core/src/main/java/org/infinispan/context/impl/LocalTxInvocationContext.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/context/impl/LocalTxInvocationContext.java	2010-05-17 15:03:20 UTC (rev 1796)
+++ trunk/core/src/main/java/org/infinispan/context/impl/LocalTxInvocationContext.java	2010-05-17 15:10:55 UTC (rev 1797)
@@ -57,11 +57,15 @@
    }
 
    public void putLookedUpEntry(Object key, CacheEntry e) {
+      keyAddedInCurrentInvocation(key);
       xaAdapter.putLookedUpEntry(key, e);
    }
 
    public void putLookedUpEntries(Map<Object, CacheEntry> lookedUpEntries) {
-      xaAdapter.putLookedUpEntries(lookedUpEntries);
+      for (Map.Entry<Object, CacheEntry> ce: lookedUpEntries.entrySet()) {
+         keyAddedInCurrentInvocation(ce.getKey());
+         xaAdapter.putLookedUpEntry(ce.getKey(), ce.getValue());
+      }
    }
 
    public void removeLookedUpEntry(Object key) {

Modified: trunk/core/src/main/java/org/infinispan/context/impl/NonTxInvocationContext.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/context/impl/NonTxInvocationContext.java	2010-05-17 15:03:20 UTC (rev 1796)
+++ trunk/core/src/main/java/org/infinispan/context/impl/NonTxInvocationContext.java	2010-05-17 15:10:55 UTC (rev 1797)
@@ -27,12 +27,16 @@
 
    public void putLookedUpEntry(Object key, CacheEntry e) {
       initLookedUpEntries();
+      keyAddedInCurrentInvocation(key);
       lookedUpEntries.put(key, e);
    }
 
    public void putLookedUpEntries(Map<Object, CacheEntry> lookedUpEntries) {
       initLookedUpEntries();
-      this.lookedUpEntries.putAll(lookedUpEntries);
+      for (Map.Entry<Object, CacheEntry> ce: lookedUpEntries.entrySet()) {
+         keyAddedInCurrentInvocation(ce.getKey());
+         lookedUpEntries.put(ce.getKey(), ce.getValue());
+      }
    }
 
    public void clearLookedUpEntries() {

Modified: trunk/core/src/main/java/org/infinispan/context/impl/RemoteTxInvocationContext.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/context/impl/RemoteTxInvocationContext.java	2010-05-17 15:03:20 UTC (rev 1796)
+++ trunk/core/src/main/java/org/infinispan/context/impl/RemoteTxInvocationContext.java	2010-05-17 15:10:55 UTC (rev 1797)
@@ -61,6 +61,7 @@
    }
 
    public void putLookedUpEntry(Object key, CacheEntry e) {
+      keyAddedInCurrentInvocation(key);
       remoteTransaction.putLookedUpEntry(key, e);
    }
 
@@ -73,7 +74,10 @@
    }
 
    public void putLookedUpEntries(Map<Object, CacheEntry> lookedUpEntries) {
-      remoteTransaction.putLookedUpEntries(lookedUpEntries);
+      for (Map.Entry<Object, CacheEntry> ce: lookedUpEntries.entrySet()) {
+         keyAddedInCurrentInvocation(ce.getKey());
+         remoteTransaction.putLookedUpEntry(ce.getKey(), ce.getValue());
+      }
    }
 
    @Override

Modified: trunk/core/src/main/java/org/infinispan/interceptors/InvocationContextInterceptor.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/interceptors/InvocationContextInterceptor.java	2010-05-17 15:03:20 UTC (rev 1796)
+++ trunk/core/src/main/java/org/infinispan/interceptors/InvocationContextInterceptor.java	2010-05-17 15:10:55 UTC (rev 1797)
@@ -25,15 +25,24 @@
 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;
 
 public class InvocationContextInterceptor extends CommandInterceptor {
 
+   LockManager lockManager;
+
    @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;
 
@@ -48,6 +57,21 @@
          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;

Modified: trunk/core/src/main/java/org/infinispan/transaction/xa/CacheTransaction.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/transaction/xa/CacheTransaction.java	2010-05-17 15:03:20 UTC (rev 1796)
+++ trunk/core/src/main/java/org/infinispan/transaction/xa/CacheTransaction.java	2010-05-17 15:10:55 UTC (rev 1797)
@@ -32,8 +32,6 @@
 
    public void putLookedUpEntry(Object key, CacheEntry e);
 
-   public void putLookedUpEntries(Map<Object, CacheEntry> lookedUpEntries);
-
    public void removeLookedUpEntry(Object key);
 
    public void clearLookedUpEntries();

Modified: trunk/core/src/main/java/org/infinispan/transaction/xa/RemoteTransaction.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/transaction/xa/RemoteTransaction.java	2010-05-17 15:03:20 UTC (rev 1796)
+++ trunk/core/src/main/java/org/infinispan/transaction/xa/RemoteTransaction.java	2010-05-17 15:10:55 UTC (rev 1797)
@@ -62,10 +62,6 @@
       lookedUpEntries.put(key, e);
    }
 
-   public void putLookedUpEntries(Map<Object, CacheEntry> lookedUpEntries) {
-      lookedUpEntries.putAll(lookedUpEntries);
-   }
-
    public void removeLookedUpEntry(Object key) {
       lookedUpEntries.remove(key);
    }

Modified: trunk/core/src/main/java/org/infinispan/transaction/xa/TransactionXaAdapter.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/transaction/xa/TransactionXaAdapter.java	2010-05-17 15:03:20 UTC (rev 1796)
+++ trunk/core/src/main/java/org/infinispan/transaction/xa/TransactionXaAdapter.java	2010-05-17 15:10:55 UTC (rev 1797)
@@ -173,11 +173,6 @@
       return true;
    }
 
-   public void putLookedUpEntries(Map<Object, CacheEntry> entries) {
-      initLookedUpEntries();
-      lookedUpEntries.putAll(entries);
-   }
-
    public CacheEntry lookupEntry(Object key) {
       if (lookedUpEntries == null) return null;
       return lookedUpEntries.get(key);



More information about the infinispan-commits mailing list