[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