JBoss Cache SVN: r6029 - core/trunk/src/main/java/org/jboss/cache.
by jbosscache-commits@lists.jboss.org
Author: manik.surtani(a)jboss.com
Date: 2008-06-25 09:24:47 -0400 (Wed, 25 Jun 2008)
New Revision: 6029
Modified:
core/trunk/src/main/java/org/jboss/cache/RegionManager.java
Log:
Catch interruptedException
Modified: core/trunk/src/main/java/org/jboss/cache/RegionManager.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/RegionManager.java 2008-06-25 13:23:13 UTC (rev 6028)
+++ core/trunk/src/main/java/org/jboss/cache/RegionManager.java 2008-06-25 13:24:47 UTC (rev 6029)
@@ -6,15 +6,28 @@
import static org.jboss.cache.Region.Type.*;
import org.jboss.cache.buddyreplication.BuddyFqnTransformer;
import org.jboss.cache.buddyreplication.BuddyManager;
-import org.jboss.cache.config.*;
+import org.jboss.cache.config.Configuration;
+import org.jboss.cache.config.ConfigurationException;
+import org.jboss.cache.config.EvictionConfig;
+import org.jboss.cache.config.EvictionPolicyConfig;
+import org.jboss.cache.config.EvictionRegionConfig;
import org.jboss.cache.eviction.EvictionTimerTask;
import org.jboss.cache.eviction.RegionNameConflictException;
-import org.jboss.cache.factories.annotations.*;
+import org.jboss.cache.factories.annotations.Destroy;
+import org.jboss.cache.factories.annotations.Inject;
+import org.jboss.cache.factories.annotations.NonVolatile;
+import org.jboss.cache.factories.annotations.Start;
+import org.jboss.cache.factories.annotations.Stop;
import org.jboss.cache.lock.LockManager;
import static org.jboss.cache.lock.LockType.WRITE;
import org.jgroups.Address;
-import java.util.*;
+import java.util.ArrayList;
+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;
/**
@@ -602,6 +615,10 @@
}
}
}
+ catch (InterruptedException e)
+ {
+ throw new CacheException(e);
+ }
finally
{
// If we didn't succeed, undo the marshalling change
16 years, 6 months
JBoss Cache SVN: r6028 - in core/trunk/src/main/java/org/jboss/cache: transaction and 1 other directory.
by jbosscache-commits@lists.jboss.org
Author: manik.surtani(a)jboss.com
Date: 2008-06-25 09:23:13 -0400 (Wed, 25 Jun 2008)
New Revision: 6028
Modified:
core/trunk/src/main/java/org/jboss/cache/InvocationContext.java
core/trunk/src/main/java/org/jboss/cache/transaction/TransactionEntry.java
Log:
Updated interface methods to simplify collection and recording of locks.
Modified: core/trunk/src/main/java/org/jboss/cache/InvocationContext.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/InvocationContext.java 2008-06-25 13:21:38 UTC (rev 6027)
+++ core/trunk/src/main/java/org/jboss/cache/InvocationContext.java 2008-06-25 13:23:13 UTC (rev 6028)
@@ -18,8 +18,11 @@
import javax.transaction.Transaction;
import java.util.ArrayList;
-import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.LinkedHashSet;
import java.util.List;
+import java.util.Map;
/**
* This context holds information specific to a method invocation.
@@ -27,7 +30,7 @@
* @author <a href="mailto:manik@jboss.org">Manik Surtani (manik(a)jboss.org)</a>
*/
@SuppressWarnings("deprecation")
-public class InvocationContext implements Cloneable
+public class InvocationContext
{
private static final Log log = LogFactory.getLog(InvocationContext.class);
private static final boolean trace = log.isTraceEnabled();
@@ -44,46 +47,39 @@
private MethodCall methodCall;
@Deprecated
private VisitableCommand command;
- List<NodeLock> invocationLocks;
- // used to store cache peeks within the scope of a single context. Performing a cache peek can be a huge bottle neck.
- // See JBCACHE-811
- // backing out for now
- //private Map<Fqn, NodeSPI> peekedNodes = new HashMap<Fqn, NodeSPI>();
-
/**
- * Retrieves a node that may have previously been "peeked" within the scope of the same invocation.
- *
- * @param f fqn of node to find
- * @return node, if previously peeked, or null if not.
- * @since 2.1.0
+ * LinkedHashSet of locks acquired by the invocation. We use a LinkedHashSet because we need efficient Set semantics
+ * but also need guaranteed ordering for use by lock release code (see JBCCACHE-874).
+ * <p/>
+ * This needs to be unchecked since we support both MVCC (Fqns held here) or legacy Opt/Pess locking (NodeLocks held here).
+ * once we drop support for opt/pess locks we can genericise this to contain Fqns. - Manik Surtani, June 2008
*/
-// public NodeSPI getPeekedNode(Fqn f)
-// {
-// return peekedNodes.get(f);
-// }
+ private LinkedHashSet invocationLocks;
- /**
- * Adds a node to the previously peeked list.
- *
- * @param n node to add
- * @param f fqn of node
- * @since 2.1.0
- */
-// public void savePeekedNode(NodeSPI n, Fqn f)
-// {
-// peekedNodes.put(f, n);
-// }
+ private final Map<Fqn, NodeSPI> lookedUpNodes = new HashMap<Fqn, NodeSPI>();
- /**
- * Wipe list of previously peeked nodes.
- *
- * @since 2.1.0
- */
-// public void wipePeekedNodes()
-// {
-// peekedNodes.clear();
-// }
+ public NodeSPI lookUpNode(Fqn fqn)
+ {
+ // TODO: should delegate to TransactionEntry if one is in scope
+ return lookedUpNodes.get(fqn);
+ }
+
+ public void putLookedUpNode(Fqn f, NodeSPI n)
+ {
+ lookedUpNodes.put(f, n);
+ }
+
+ public void clearLookedUpNodes()
+ {
+ lookedUpNodes.clear();
+ }
+
+ public Map<Fqn, NodeSPI> getLookedUpNodes()
+ {
+ return lookedUpNodes;
+ }
+
public void setLocalRollbackOnly(boolean localRollbackOnly)
{
this.localRollbackOnly = localRollbackOnly;
@@ -188,26 +184,139 @@
return originLocal;
}
- public List<NodeLock> getInvocationLocksAcquired()
+ /**
+ * Returns an immutable, defensive copy of the List of locks currently maintained for the current scope.
+ * <p/>
+ * Note that if a transaction is in scope, these locks are retrieved from the {@link org.jboss.cache.transaction.TransactionEntry} rather than
+ * this {@link org.jboss.cache.InvocationContext}. Retrieving locks from here will ensure they are retrieved from the appropriate
+ * scope.
+ * <p/>
+ * Note that currently (as of 3.0.0) this list is unchecked. This is to allow support for both MVCC (which uses Fqns as locks)
+ * as well as legacy Optimistic and Pessimistic Locking schemes (which use {@link NodeLock} as locks). Once support for
+ * legacy node locking schemes are dropped, this method will be more strongly typed to return <tt>List<Fqn></tt>.
+ *
+ * @return locks held in current scope.
+ */
+ @SuppressWarnings("unchecked")
+ public List getLocks()
{
- return invocationLocks;
+ // first check transactional scope
+ if (transactionEntry != null) return transactionEntry.getLocks();
+ return Collections.unmodifiableList(new ArrayList(invocationLocks));
}
- public void addInvocationLocksAcquired(Collection<NodeLock> locks)
+ /**
+ * Adds a List of locks to the currently maintained collection of locks acquired.
+ * <p/>
+ * Note that if a transaction is in scope, these locks are recorded on the {@link org.jboss.cache.transaction.TransactionEntry} rather than
+ * this {@link org.jboss.cache.InvocationContext}. Adding locks here will ensure they are promoted to the appropriate
+ * scope.
+ * <p/>
+ * Note that currently (as of 3.0.0) this list is unchecked. This is to allow support for both MVCC (which uses Fqns as locks)
+ * as well as legacy Optimistic and Pessimistic Locking schemes (which use {@link NodeLock} as locks). Once support for
+ * legacy node locking schemes are dropped, this method will be more strongly typed to accept <tt>List<Fqn></tt>.
+ *
+ * @param locks locks to add
+ */
+ @SuppressWarnings("unchecked")
+ public void addAllLocks(List locks)
{
- // no need to worry about concurrency here - a context is only valid for a single thread.
- if (invocationLocks == null) invocationLocks = new ArrayList<NodeLock>(5);
- invocationLocks.addAll(locks);
+ // first check transactional scope
+ if (transactionEntry != null)
+ {
+ transactionEntry.addAllLocks(locks);
+ }
+ else
+ {
+ // no need to worry about concurrency here - a context is only valid for a single thread.
+ if (invocationLocks == null) invocationLocks = new LinkedHashSet(5);
+ invocationLocks.addAll(locks);
+ }
}
- public void addInvocationLockAcquired(NodeLock l)
+ /**
+ * Adds a lock to the currently maintained collection of locks acquired.
+ * <p/>
+ * Note that if a transaction is in scope, this lock is recorded on the {@link org.jboss.cache.transaction.TransactionEntry} rather than
+ * this {@link org.jboss.cache.InvocationContext}. Adding a lock here will ensure it is promoted to the appropriate
+ * scope.
+ * <p/>
+ * Note that currently (as of 3.0.0) this lock is weakly typed. This is to allow support for both MVCC (which uses {@link Fqn}s as locks)
+ * as well as legacy Optimistic and Pessimistic Locking schemes (which use {@link NodeLock} as locks). Once support for
+ * legacy node locking schemes are dropped, this method will be more strongly typed to accept {@link Fqn}.
+ *
+ * @param lock lock to add
+ */
+ @SuppressWarnings("unchecked")
+ public void addLock(Object lock)
{
- // no need to worry about concurrency here - a context is only valid for a single thread.
- if (invocationLocks == null) invocationLocks = new ArrayList<NodeLock>(5);
- invocationLocks.add(l);
+ // first check transactional scope
+ if (transactionEntry != null)
+ {
+ transactionEntry.addLock(lock);
+ }
+ else
+ {
+ // no need to worry about concurrency here - a context is only valid for a single thread.
+ if (invocationLocks == null) invocationLocks = new LinkedHashSet(5);
+ invocationLocks.add(lock);
+ }
}
/**
+ * Removes a lock from the currently maintained collection of locks acquired.
+ * <p/>
+ * Note that if a transaction is in scope, this lock is removed from the {@link org.jboss.cache.transaction.TransactionEntry} rather than
+ * this {@link org.jboss.cache.InvocationContext}. Removing a lock here will ensure it is removed in the appropriate
+ * scope.
+ * <p/>
+ * Note that currently (as of 3.0.0) this lock is weakly typed. This is to allow support for both MVCC (which uses {@link Fqn}s as locks)
+ * as well as legacy Optimistic and Pessimistic Locking schemes (which use {@link NodeLock} as locks). Once support for
+ * legacy node locking schemes are dropped, this method will be more strongly typed to accept {@link Fqn}.
+ *
+ * @param lock lock to remove
+ */
+ @SuppressWarnings("unchecked")
+ public void removeLock(Object lock)
+ {
+ // first check transactional scope
+ if (transactionEntry != null)
+ {
+ transactionEntry.removeLock(lock);
+ }
+ else
+ {
+ // no need to worry about concurrency here - a context is only valid for a single thread.
+ if (invocationLocks != null) invocationLocks.remove(lock);
+ }
+ }
+
+ /**
+ * Clears all locks from the currently maintained collection of locks acquired.
+ * <p/>
+ * Note that if a transaction is in scope, locks are cleared from the {@link org.jboss.cache.transaction.TransactionEntry} rather than
+ * this {@link org.jboss.cache.InvocationContext}. Clearing locks here will ensure they are cleared in the appropriate
+ * scope.
+ * <p/>
+ * Note that currently (as of 3.0.0) this lock is weakly typed. This is to allow support for both MVCC (which uses {@link Fqn}s as locks)
+ * as well as legacy Optimistic and Pessimistic Locking schemes (which use {@link NodeLock} as locks). Once support for
+ * legacy node locking schemes are dropped, this method will be more strongly typed to accept {@link Fqn}.
+ */
+ public void clearLocks()
+ {
+ // first check transactional scope
+ if (transactionEntry != null)
+ {
+ transactionEntry.clearLocks();
+ }
+ else
+ {
+ // no need to worry about concurrency here - a context is only valid for a single thread.
+ if (invocationLocks != null) invocationLocks.clear();
+ }
+ }
+
+ /**
* @return true if options exist to suppress locking - false otherwise. Note that this is only used by the {@link org.jboss.cache.interceptors.PessimisticLockInterceptor}.
*/
public boolean isLockingSuppressed()
@@ -268,12 +377,20 @@
command = null;
}
- @Override
- public InvocationContext clone() throws CloneNotSupportedException
+ /**
+ * This is a "copy-factory-method" that should be used whenever a clone of this class is needed. The resulting instance
+ * is equal() to, but not ==, to the template passed in.
+ *
+ * @param template template to copy
+ * @return a new InvocationContext
+ */
+ public static InvocationContext copy(InvocationContext template)
{
- InvocationContext clone = (InvocationContext) super.clone();
- clone.setOptionOverrides(getOptionOverrides().clone());
- return clone;
+ // TODO: Remove all use of cloning and replace with copy factory methods.
+// InvocationContext clone = (InvocationContext) super.clone();
+// clone.setOptionOverrides(getOptionOverrides().clone());
+// return clone;
+ return null;
}
/**
Modified: core/trunk/src/main/java/org/jboss/cache/transaction/TransactionEntry.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/transaction/TransactionEntry.java 2008-06-25 13:21:38 UTC (rev 6027)
+++ core/trunk/src/main/java/org/jboss/cache/transaction/TransactionEntry.java 2008-06-25 13:23:13 UTC (rev 6028)
@@ -12,6 +12,7 @@
import org.apache.commons.logging.LogFactory;
import org.jboss.cache.Fqn;
import org.jboss.cache.Modification;
+import org.jboss.cache.NodeSPI;
import org.jboss.cache.commands.ReversibleCommand;
import org.jboss.cache.config.Option;
import org.jboss.cache.interceptors.OrderedSynchronizationHandler;
@@ -22,12 +23,13 @@
import javax.transaction.SystemException;
import javax.transaction.Transaction;
import java.util.ArrayList;
-import java.util.Collection;
import java.util.Collections;
+import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
+import java.util.Map;
/**
* Information associated with a {@link GlobalTransaction} about the transaction state.
@@ -72,13 +74,16 @@
private List<ReversibleCommand> localModifications;
/**
- * LinkedHashSet<IdentityLock> of locks acquired by the transaction. We use
- * a LinkedHashSet because we need efficient Set semantics (same lock can
- * be added multiple times) but also need guaranteed ordering for use
- * by lock release code (see JBCCACHE-874).
+ * LinkedHashSet of locks acquired by the transaction. We use a LinkedHashSet because we need efficient Set semantics
+ * but also need guaranteed ordering for use by lock release code (see JBCCACHE-874).
+ * <p/>
+ * This needs to be unchecked since we support both MVCC (Fqns held here) or legacy Opt/Pess locking (NodeLocks held here).
+ * once we drop support for opt/pess locks we can genericise this to contain Fqns. - Manik Surtani, June 2008
*/
- private final LinkedHashSet<NodeLock> locks = new LinkedHashSet<NodeLock>();
+ private LinkedHashSet transactionLocks;
+ private final Map<Fqn, NodeSPI> lookedUpNodes = new HashMap<Fqn, NodeSPI>();
+
/**
* A list of dummy uninitialised nodes created by the cache loader interceptor to load data for a
* given node in this tx.
@@ -170,49 +175,106 @@
}
/**
- * Adds a lock to the end of the lock list, if it isn't already present.
+ * Adds a lock to the currently maintained collection of locks acquired.
+ * <p/>
+ * Most code could not use this method directly, but use {@link org.jboss.cache.InvocationContext#addLock(Object)} instead,
+ * which would delegate to this method if a transaction is in scope or otherwise use invocation-specific locks.
+ * <p/>
+ * Note that currently (as of 3.0.0) this lock is weakly typed. This is to allow support for both MVCC (which uses {@link Fqn}s as locks)
+ * as well as legacy Optimistic and Pessimistic Locking schemes (which use {@link NodeLock} as locks). Once support for
+ * legacy node locking schemes are dropped, this method will be more strongly typed to accept {@link Fqn}.
+ *
+ * @param lock lock to add
+ * @see org.jboss.cache.InvocationContext#addLock(Object)
*/
- public void addLock(NodeLock l)
+ @SuppressWarnings("unchecked")
+ public void addLock(Object lock)
{
- if (l != null)
- {
- synchronized (locks)
- {
- locks.add(l);
- }
- }
+ // no need to worry about concurrency here - a context is only valid for a single thread.
+ if (transactionLocks == null) transactionLocks = new LinkedHashSet(5);
+ transactionLocks.add(lock);
}
/**
- * Add multiple locks to the lock list.
+ * Removes a lock from the currently maintained collection of locks acquired.
+ * <p/>
+ * Most code could not use this method directly, but use {@link org.jboss.cache.InvocationContext#removeLock(Object)} instead,
+ * which would delegate to this method if a transaction is in scope or otherwise use invocation-specific locks.
+ * <p/>
+ * Note that currently (as of 3.0.0) this lock is weakly typed. This is to allow support for both MVCC (which uses {@link Fqn}s as locks)
+ * as well as legacy Optimistic and Pessimistic Locking schemes (which use {@link NodeLock} as locks). Once support for
+ * legacy node locking schemes are dropped, this method will be more strongly typed to accept {@link Fqn}.
*
- * @param newLocks Collection<NodeLock>
+ * @param lock lock to remove
+ * @see org.jboss.cache.InvocationContext#removeLock(Object)
*/
- public void addLocks(Collection<NodeLock> newLocks)
+ @SuppressWarnings("unchecked")
+ public void removeLock(Object lock)
{
- if (newLocks != null)
- {
- synchronized (locks)
- {
- locks.addAll(newLocks);
- }
- }
+ // no need to worry about concurrency here - a context is only valid for a single thread.
+ if (transactionLocks != null) transactionLocks.remove(lock);
}
/**
- * Returns the locks in use.
+ * Clears all locks from the currently maintained collection of locks acquired.
+ * <p/>
+ * Most code could not use this method directly, but use {@link org.jboss.cache.InvocationContext#clearLocks()} instead,
+ * which would delegate to this method if a transaction is in scope or otherwise use invocation-specific locks.
+ * <p/>
+ * Note that currently (as of 3.0.0) this lock is weakly typed. This is to allow support for both MVCC (which uses {@link Fqn}s as locks)
+ * as well as legacy Optimistic and Pessimistic Locking schemes (which use {@link NodeLock} as locks). Once support for
+ * legacy node locking schemes are dropped, this method will be more strongly typed to accept {@link Fqn}.
*
- * @return a defensive copy of the internal data structure.
+ * @see org.jboss.cache.InvocationContext#clearLocks()
*/
- public List<NodeLock> getLocks()
+ public void clearLocks()
{
- synchronized (locks)
- {
- return new ArrayList<NodeLock>(locks);
- }
+ if (transactionLocks != null) transactionLocks.clear();
}
+
/**
+ * Adds a List of locks to the currently maintained collection of locks acquired.
+ * <p/>
+ * Most code could not use this method directly, but use {@link org.jboss.cache.InvocationContext#addAllLocks(java.util.List)} instead,
+ * which would delegate to this method if a transaction is in scope or otherwise use invocation-specific locks.
+ * <p/>
+ * Note that currently (as of 3.0.0) this list is unchecked. This is to allow support for both MVCC (which uses Fqns as locks)
+ * as well as legacy Optimistic and Pessimistic Locking schemes (which use {@link NodeLock} as locks). Once support for
+ * legacy node locking schemes are dropped, this method will be more strongly typed to accept <tt>List<Fqn></tt>.
+ *
+ * @param newLocks locks to add
+ * @see org.jboss.cache.InvocationContext#addAllLocks(java.util.List)
+ */
+ @SuppressWarnings("unchecked")
+ public void addAllLocks(List newLocks)
+ {
+ // no need to worry about concurrency here - a context is only valid for a single thread.
+ if (transactionLocks == null) transactionLocks = new LinkedHashSet(5);
+ transactionLocks.addAll(newLocks);
+ }
+
+ /**
+ * Returns an immutable, defensive copy of the List of locks currently maintained for the transaction.
+ * <p/>
+ * Most code could not use this method directly, but use {@link org.jboss.cache.InvocationContext#getLocks()} instead,
+ * which would delegate to this method if a transaction is in scope or otherwise use invocation-specific locks.
+ * <p/>
+ * Note that currently (as of 3.0.0) this list is unchecked. This is to allow support for both MVCC (which uses Fqns as locks)
+ * as well as legacy Optimistic and Pessimistic Locking schemes (which use {@link NodeLock} as locks). Once support for
+ * legacy node locking schemes are dropped, this method will be more strongly typed to return <tt>List<Fqn></tt>.
+ *
+ * @return locks held in current scope.
+ * @see org.jboss.cache.InvocationContext#getLocks()
+ */
+ @SuppressWarnings("unchecked")
+ public List getLocks()
+ {
+ return Collections.unmodifiableList(new ArrayList(transactionLocks));
+ }
+
+
+ /**
* Gets the value of the forceAsyncReplication flag. Used by ReplicationInterceptor and OptimisticReplicationInterceptor
* when dealing with {@link org.jboss.cache.Cache#putForExternalRead(org.jboss.cache.Fqn,Object,Object)} within
* a transactional context.
@@ -305,12 +367,8 @@
@Override
public String toString()
{
- StringBuffer sb = new StringBuffer();
+ StringBuilder sb = new StringBuilder();
sb.append("TransactionEntry\nmodificationList: ").append(modificationList);
- synchronized (locks)
- {
- sb.append("\nlocks: ").append(locks);
- }
return sb.toString();
}
@@ -370,7 +428,27 @@
return localModifications != null && !localModifications.isEmpty();
}
+ public NodeSPI lookUpNode(Fqn fqn)
+ {
+ return lookedUpNodes.get(fqn);
+ }
+ public void putLookedUpNode(Fqn f, NodeSPI n)
+ {
+ lookedUpNodes.put(f, n);
+ }
+
+ public void clearLookedUpNodes()
+ {
+ lookedUpNodes.clear();
+ }
+
+ public Map<Fqn, NodeSPI> getLookedUpNodes()
+ {
+ return lookedUpNodes;
+ }
+
+
/**
* Cleans up internal state
*/
@@ -380,7 +458,7 @@
if (modificationList != null) modificationList = null;
if (localModifications != null) localModifications = null;
option = null;
- locks.clear();
+ transactionLocks.clear();
if (dummyNodesCreatedByCacheLoader != null) dummyNodesCreatedByCacheLoader.clear();
removedNodes.clear();
}
16 years, 6 months
JBoss Cache SVN: r6027 - core/trunk/src/main/java/org/jboss/cache/lock.
by jbosscache-commits@lists.jboss.org
Author: manik.surtani(a)jboss.com
Date: 2008-06-25 09:21:38 -0400 (Wed, 25 Jun 2008)
New Revision: 6027
Added:
core/trunk/src/main/java/org/jboss/cache/lock/MVCCLockManager.java
Log:
First-cut implementation of the mvcc lock manager
Added: core/trunk/src/main/java/org/jboss/cache/lock/MVCCLockManager.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/lock/MVCCLockManager.java (rev 0)
+++ core/trunk/src/main/java/org/jboss/cache/lock/MVCCLockManager.java 2008-06-25 13:21:38 UTC (rev 6027)
@@ -0,0 +1,378 @@
+package org.jboss.cache.lock;
+
+import net.jcip.annotations.ThreadSafe;
+import org.jboss.cache.CacheSPI;
+import org.jboss.cache.DataContainer;
+import org.jboss.cache.Fqn;
+import org.jboss.cache.InvocationContext;
+import org.jboss.cache.Node;
+import org.jboss.cache.NodeSPI;
+import org.jboss.cache.factories.annotations.Inject;
+import org.jboss.cache.factories.annotations.Start;
+import org.jboss.cache.invocation.InvocationContextContainer;
+import org.jboss.cache.util.concurrent.locks.OwnableReentrantLock;
+
+import javax.transaction.TransactionManager;
+import java.util.Collection;
+import java.util.List;
+import java.util.Set;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
+/**
+ * This lock manager acquires and releases locks based on the Fqn passed in and not on the node itself. The main benefit
+ * here is that locks can be acquired and held even for nonexistent nodes.
+ * <p/>
+ * Uses lock striping so that a fixed number of locks are maintained for the entire cache, and not a single lock per node.
+ * <p/>
+ * This implementation only acquires exclusive WRITE locks, and throws an exception if you attempt to use it to acquire a
+ * READ lock. JBoss Cache's MVCC design doesn't use read locks at all.
+ * <p/>
+ * The concept of lock owners is implicit in this implementation and any owners passed in as parameters (where required)
+ * will be ignored. See {@link org.jboss.cache.util.concurrent.locks.OwnableReentrantLock} for details on how ownership
+ * is determined.
+ * <p/>
+ *
+ * @author Manik Surtani (<a href="mailto:manik@jboss.org">manik(a)jboss.org</a>)
+ * @see org.jboss.cache.util.concurrent.locks.OwnableReentrantLock
+ * @since 3.0
+ */
+public class MVCCLockManager extends FqnLockManager
+{
+ LockContainer lockContainer;
+ DataContainer dataContainer;
+ private Set<Fqn> internalFqns;
+ private CacheSPI cache;
+ private TransactionManager transactionManager;
+ private InvocationContextContainer invocationContextContainer;
+ private static final int DEFAULT_CONCURRENCY = 20;
+
+ @Inject
+ public void injectDataContainer(DataContainer dataContainer, CacheSPI cache, TransactionManager transactionManager, InvocationContextContainer invocationContextContainer)
+ {
+ this.dataContainer = dataContainer;
+ this.cache = cache;
+ this.transactionManager = transactionManager;
+ this.invocationContextContainer = invocationContextContainer;
+ }
+
+ @Start
+ public void startLockManager()
+ {
+ lockContainer = transactionManager == null ? new ReentrantLockContainer() : new OwnableReentrantLockContainer();
+ }
+
+ @Start
+ @SuppressWarnings("unchecked")
+ public void setInternalFqns()
+ {
+ internalFqns = cache.getInternalFqns();
+ }
+
+
+ protected void assertIsWriteLock(LockType lockType)
+ {
+ if (lockType != LockType.WRITE)
+ throw new UnsupportedOperationException(getClass().getName() + " only supports write locks.");
+ }
+
+ public boolean lock(Fqn fqn, LockType lockType, Object owner) throws InterruptedException
+ {
+ assertIsWriteLock(lockType);
+ Lock lock = lockContainer.getLock(fqn);
+ return lock.tryLock(lockAcquisitionTimeout, MILLISECONDS);
+ }
+
+ public boolean lock(Fqn fqn, LockType lockType, Object owner, long timeoutMillis) throws InterruptedException
+ {
+ assertIsWriteLock(lockType);
+ Lock lock = lockContainer.getLock(fqn);
+ return lock.tryLock(timeoutMillis, MILLISECONDS);
+ }
+
+ public boolean lockAndRecord(Fqn fqn, LockType lockType, InvocationContext ctx) throws InterruptedException
+ {
+ assertIsWriteLock(lockType);
+ Lock lock = lockContainer.getLock(fqn);
+ if (lock.tryLock(ctx.getContextLockAcquisitionTimeout(lockAcquisitionTimeout), MILLISECONDS))
+ {
+ ctx.addLock(fqn);
+ return true;
+ }
+
+ // couldn't acquire lock!
+ return false;
+ }
+
+ public void unlock(Fqn fqn, Object owner)
+ {
+ Lock lock = lockContainer.getLock(fqn);
+ lock.unlock();
+ }
+
+ public void unlock(InvocationContext ctx)
+ {
+ List<Fqn> locks = ctx.getLocks();
+ if (!locks.isEmpty())
+ {
+ // unlocking needs to be done in reverse order.
+ Fqn[] fqns = new Fqn[locks.size()];
+ fqns = locks.toArray(fqns);
+ for (int i = fqns.length - 1; i > -1; i--) lockContainer.getLock(fqns[i]).unlock();
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ protected boolean lockRecursively(Node node, long timeoutMillis, boolean excludeInternalFqns, InvocationContext ctx) throws InterruptedException
+ {
+ if (excludeInternalFqns && internalFqns.contains(node.getFqn()))
+ return true; // this will stop the recursion from proceeding down this subtree.
+
+ boolean locked = ctx == null ?
+ lock(node.getFqn(), LockType.WRITE, null, timeoutMillis) :
+ lockAndRecord(node.getFqn(), LockType.WRITE, ctx);
+
+ if (!locked) return false;
+ boolean needToUnlock = false;
+
+ // need to recursively walk through the node's children and acquire locks. This needs to happen using API methods
+ // since any cache loading will need to happen.
+ Set<Node> children = node.getChildren();
+ try
+ {
+ if (children != null)
+ {
+ for (Node child : children)
+ {
+ locked = lockRecursively(child, timeoutMillis, excludeInternalFqns, ctx);
+ if (!locked)
+ {
+ needToUnlock = true;
+ break;
+ }
+ }
+ }
+ }
+ finally
+ {
+ if (needToUnlock)
+ {
+ for (Node child : children)
+ {
+ Fqn childFqn = child.getFqn();
+ unlock(childFqn, null);
+ if (ctx != null) ctx.removeLock(childFqn);
+ }
+ unlock(node.getFqn(), null);
+ if (ctx != null) ctx.removeLock(node.getFqn());
+ }
+ }
+ return locked;
+ }
+
+ public boolean lockAll(NodeSPI node, LockType lockType, Object owner) throws InterruptedException
+ {
+ assertIsWriteLock(lockType);
+ return lockRecursively(node, lockAcquisitionTimeout, false, null);
+ }
+
+ public boolean lockAll(NodeSPI node, LockType lockType, Object owner, long timeout) throws InterruptedException
+ {
+ assertIsWriteLock(lockType);
+ return lockRecursively(node, timeout, false, null);
+ }
+
+ public boolean lockAll(NodeSPI node, LockType lockType, Object owner, long timeout, boolean excludeInternalFqns) throws InterruptedException
+ {
+ assertIsWriteLock(lockType);
+ return lockRecursively(node, timeout, excludeInternalFqns, null);
+ }
+
+ public boolean lockAllAndRecord(NodeSPI node, LockType lockType, InvocationContext ctx) throws InterruptedException
+ {
+ assertIsWriteLock(lockType);
+ return lockRecursively(node, ctx.getContextLockAcquisitionTimeout(lockAcquisitionTimeout), false, ctx);
+ }
+
+ public boolean lockAllAndRecord(Fqn fqn, LockType lockType, InvocationContext ctx) throws InterruptedException
+ {
+ return lockAllAndRecord(dataContainer.peek(fqn, false), lockType, ctx);
+ }
+
+ @SuppressWarnings("unchecked")
+ public void unlockAll(NodeSPI node, Object owner)
+ {
+ // depth first.
+ Set<Node> children = node.getChildren();
+ if (children != null)
+ {
+ for (Node child : children) unlockAll((NodeSPI) child, null);
+ }
+ unlock(node.getFqn(), null);
+ }
+
+ public void unlockAll(NodeSPI node)
+ {
+ throw new UnsupportedOperationException("Not supported in this impl.");
+ }
+
+ public boolean ownsLock(Fqn fqn, LockType lockType, Object owner)
+ {
+ assertIsWriteLock(lockType);
+ return lockContainer.ownsLock(fqn, owner);
+ }
+
+ public boolean ownsLock(Fqn fqn, Object owner)
+ {
+ return lockContainer.ownsLock(fqn, owner);
+ }
+
+ public boolean isLocked(NodeSPI n)
+ {
+ return lockContainer.isLocked(n.getFqn());
+ }
+
+ public boolean isLocked(NodeSPI n, LockType lockType)
+ {
+ assertIsWriteLock(lockType);
+ return lockContainer.isLocked(n.getFqn());
+ }
+
+ public Object getWriteOwner(Fqn f)
+ {
+ throw new UnsupportedOperationException("Not supported in this impl.");
+ }
+
+ public Collection<Object> getReadOwners(Fqn f)
+ {
+ throw new UnsupportedOperationException("Not supported in this impl.");
+ }
+
+ public String printLockInfo(NodeSPI node)
+ {
+ return "Not supported in this impl.";
+ }
+
+ @ThreadSafe
+ abstract class LockContainer
+ {
+ private final int lockSegmentMask;
+ private final int lockSegmentShift;
+
+ /**
+ * This constructor just calls {@link #LockContainer(int)} with a default concurrency value of 20.
+ */
+ LockContainer()
+ {
+ this(DEFAULT_CONCURRENCY);
+ }
+
+ /**
+ * Creates a new LockContainer which uses a certain number of shared locks across all elements that need to be locked.
+ *
+ * @param concurrency number of threads expected to use this class concurrently.
+ */
+ LockContainer(int concurrency)
+ {
+ int tempLockSegShift = 0;
+ int numLocks = 1;
+ while (numLocks < concurrency)
+ {
+ ++tempLockSegShift;
+ numLocks <<= 1;
+ }
+ lockSegmentShift = 32 - tempLockSegShift;
+ lockSegmentMask = numLocks - 1;
+
+ initLocks(numLocks);
+ }
+
+ int hashToIndex(Fqn fqn)
+ {
+ return (hash(fqn) >>> lockSegmentShift) & lockSegmentMask;
+ }
+
+ /**
+ * Returns a hash code for non-null Object x.
+ * Uses the same hash code spreader as most other java.util hash tables, except that this uses the string representation
+ * of the object passed in.
+ *
+ * @param x the object serving as a key
+ * @return the hash code
+ */
+ int hash(Object x)
+ {
+ int h = x.toString().hashCode();
+ h += ~(h << 9);
+ h ^= (h >>> 14);
+ h += (h << 4);
+ h ^= (h >>> 10);
+ return h;
+ }
+
+ abstract void initLocks(int numLocks);
+
+ abstract boolean ownsLock(Fqn fqn, Object owner);
+
+ abstract boolean isLocked(Fqn fqn);
+
+ abstract Lock getLock(Fqn fqn);
+ }
+
+ class ReentrantLockContainer extends LockContainer
+ {
+ ReentrantLock[] sharedLocks;
+
+ void initLocks(int numLocks)
+ {
+ sharedLocks = new ReentrantLock[numLocks];
+ for (int i = 0; i < numLocks; i++) sharedLocks[i] = new ReentrantLock();
+ }
+
+ ReentrantLock getLock(Fqn fqn)
+ {
+ return sharedLocks[hashToIndex(fqn)];
+ }
+
+ boolean ownsLock(Fqn fqn, Object owner)
+ {
+ ReentrantLock lock = getLock(fqn);
+ return lock.isHeldByCurrentThread();
+ }
+
+ boolean isLocked(Fqn fqn)
+ {
+ ReentrantLock lock = getLock(fqn);
+ return lock.isLocked();
+ }
+ }
+
+ class OwnableReentrantLockContainer extends LockContainer
+ {
+ OwnableReentrantLock[] sharedLocks;
+
+ void initLocks(int numLocks)
+ {
+ sharedLocks = new OwnableReentrantLock[numLocks];
+ for (int i = 0; i < numLocks; i++) sharedLocks[i] = new OwnableReentrantLock(invocationContextContainer);
+ }
+
+ OwnableReentrantLock getLock(Fqn fqn)
+ {
+ return sharedLocks[hashToIndex(fqn)];
+ }
+
+ boolean ownsLock(Fqn fqn, Object owner)
+ {
+ OwnableReentrantLock lock = getLock(fqn);
+ return owner.equals(lock.getOwner());
+ }
+
+ boolean isLocked(Fqn fqn)
+ {
+ OwnableReentrantLock lock = getLock(fqn);
+ return lock.isLocked();
+ }
+ }
+}
16 years, 6 months
JBoss Cache SVN: r6026 - core/trunk/src/main/java/org/jboss/cache/lock.
by jbosscache-commits@lists.jboss.org
Author: manik.surtani(a)jboss.com
Date: 2008-06-25 09:21:22 -0400 (Wed, 25 Jun 2008)
New Revision: 6026
Modified:
core/trunk/src/main/java/org/jboss/cache/lock/IsolationLevel.java
Log:
Javadoc
Modified: core/trunk/src/main/java/org/jboss/cache/lock/IsolationLevel.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/lock/IsolationLevel.java 2008-06-25 13:20:58 UTC (rev 6025)
+++ core/trunk/src/main/java/org/jboss/cache/lock/IsolationLevel.java 2008-06-25 13:21:22 UTC (rev 6026)
@@ -6,7 +6,11 @@
package org.jboss.cache.lock;
/**
- * Various transaction isolation levels as an enumerated class.
+ * Various transaction isolation levels as an enumerated class. Note that <a href="http://wiki.jboss.org/wiki/JBossCacheMVCC">MVCC</a>
+ * in JBoss Cache 3.0.0 and above only supports {@link #READ_COMMITTED} and {@link #REPEATABLE_READ}, upgrading where possible.
+ * <p/>
+ * Also note that JBoss Cache defaults to {@link #REPEATABLE_READ}.
+ * <p/>
*
* @see <a href="http://en.wikipedia.org/wiki/Isolation_%28computer_science%29">Isolation levels</a>
*/
@@ -20,4 +24,4 @@
REPEATABLE_READ,
READ_COMMITTED,
READ_UNCOMMITTED
-}
\ No newline at end of file
+}
16 years, 6 months
JBoss Cache SVN: r6025 - core/trunk/src/main/java/org/jboss/cache/lock.
by jbosscache-commits@lists.jboss.org
Author: manik.surtani(a)jboss.com
Date: 2008-06-25 09:20:58 -0400 (Wed, 25 Jun 2008)
New Revision: 6025
Added:
core/trunk/src/main/java/org/jboss/cache/lock/AbstractLockManager.java
core/trunk/src/main/java/org/jboss/cache/lock/FqnLockManager.java
Log:
Added abstract classes to simplify lock manager implementations
Added: core/trunk/src/main/java/org/jboss/cache/lock/AbstractLockManager.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/lock/AbstractLockManager.java (rev 0)
+++ core/trunk/src/main/java/org/jboss/cache/lock/AbstractLockManager.java 2008-06-25 13:20:58 UTC (rev 6025)
@@ -0,0 +1,35 @@
+package org.jboss.cache.lock;
+
+import org.jboss.cache.InvocationContext;
+import org.jboss.cache.config.Configuration;
+import org.jboss.cache.factories.annotations.Inject;
+import org.jboss.cache.factories.annotations.Start;
+
+/**
+ * Common lock manager functionality
+ *
+ * @author Manik Surtani (<a href="mailto:manik@jboss.org">manik(a)jboss.org</a>)
+ * @since 3.0
+ */
+public abstract class AbstractLockManager implements LockManager
+{
+ protected Configuration configuration;
+ protected long lockAcquisitionTimeout;
+
+ @Inject
+ public void injectConfiguration(Configuration configuration)
+ {
+ this.configuration = configuration;
+ }
+
+ @Start
+ public void setLockAcquisitionTimeout()
+ {
+ this.lockAcquisitionTimeout = configuration.getLockAcquisitionTimeout();
+ }
+
+ public Object getLockOwner(InvocationContext ctx)
+ {
+ return ctx.getGlobalTransaction() != null ? ctx.getGlobalTransaction() : Thread.currentThread();
+ }
+}
Added: core/trunk/src/main/java/org/jboss/cache/lock/FqnLockManager.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/lock/FqnLockManager.java (rev 0)
+++ core/trunk/src/main/java/org/jboss/cache/lock/FqnLockManager.java 2008-06-25 13:20:58 UTC (rev 6025)
@@ -0,0 +1,50 @@
+package org.jboss.cache.lock;
+
+import org.jboss.cache.InvocationContext;
+import org.jboss.cache.NodeSPI;
+
+import java.util.Collection;
+
+/**
+ * An abstract lock manager that deals with Fqns rather than nodes.
+ *
+ * @author Manik Surtani (<a href="mailto:manik@jboss.org">manik(a)jboss.org</a>)
+ * @since 3.0
+ */
+public abstract class FqnLockManager extends AbstractLockManager
+{
+ public boolean lock(NodeSPI node, LockType lockType, Object owner) throws InterruptedException
+ {
+ return lock(node.getFqn(), lockType, owner);
+ }
+
+ public boolean lock(NodeSPI node, LockType lockType, Object owner, long timeout) throws InterruptedException
+ {
+ return lock(node.getFqn(), lockType, owner, timeout);
+ }
+
+ public boolean lockAndRecord(NodeSPI node, LockType lockType, InvocationContext ctx) throws InterruptedException
+ {
+ return lockAndRecord(node.getFqn(), lockType, ctx);
+ }
+
+ public void unlock(NodeSPI node, Object owner)
+ {
+ unlock(node.getFqn(), owner);
+ }
+
+ public boolean ownsLock(NodeSPI node, Object owner)
+ {
+ return ownsLock(node.getFqn(), owner);
+ }
+
+ public Object getWriteOwner(NodeSPI node)
+ {
+ return getWriteOwner(node.getFqn());
+ }
+
+ public Collection<Object> getReadOwners(NodeSPI node)
+ {
+ return getReadOwners(node.getFqn());
+ }
+}
16 years, 6 months
JBoss Cache SVN: r6024 - core/trunk/src/main/java/org/jboss/cache/lock.
by jbosscache-commits@lists.jboss.org
Author: manik.surtani(a)jboss.com
Date: 2008-06-25 09:20:23 -0400 (Wed, 25 Jun 2008)
New Revision: 6024
Modified:
core/trunk/src/main/java/org/jboss/cache/lock/PessimisticNodeBasedLockManager.java
Log:
Updated to use new invocation context methods
Modified: core/trunk/src/main/java/org/jboss/cache/lock/PessimisticNodeBasedLockManager.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/lock/PessimisticNodeBasedLockManager.java 2008-06-25 13:19:39 UTC (rev 6023)
+++ core/trunk/src/main/java/org/jboss/cache/lock/PessimisticNodeBasedLockManager.java 2008-06-25 13:20:23 UTC (rev 6024)
@@ -246,7 +246,7 @@
}
else
{
- ctx.addInvocationLockAcquired(lock);
+ ctx.addLock(lock);
}
}
}
16 years, 6 months
JBoss Cache SVN: r6023 - core/trunk/src/main/java/org/jboss/cache/lock.
by jbosscache-commits@lists.jboss.org
Author: manik.surtani(a)jboss.com
Date: 2008-06-25 09:19:39 -0400 (Wed, 25 Jun 2008)
New Revision: 6023
Removed:
core/trunk/src/main/java/org/jboss/cache/lock/SimpleLock.java
core/trunk/src/main/java/org/jboss/cache/lock/SimpleReadWriteLock.java
Log:
Removed unused classes
Deleted: core/trunk/src/main/java/org/jboss/cache/lock/SimpleLock.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/lock/SimpleLock.java 2008-06-25 13:19:23 UTC (rev 6022)
+++ core/trunk/src/main/java/org/jboss/cache/lock/SimpleLock.java 2008-06-25 13:19:39 UTC (rev 6023)
@@ -1,52 +0,0 @@
-/*
- * JBoss, the OpenSource J2EE webOS
- *
- * Distributable under LGPL license.
- * See terms of license at gnu.org.
- */
-package org.jboss.cache.lock;
-
-import java.util.concurrent.locks.Lock;
-
-/**
- * Simple lock that does not differentiate read and write lock. All locks are obtained FIFO.
- * This class is used as a delegate for LockStrategy
- * is transaction isolation level.
- *
- * @author <a href="mailto:bwang00@sourceforge.net">Ben Wang</a> July 15, 2003
- * @version $Revision$
- */
-public class SimpleLock
-{
- // Log log=LogFactory.getLog(getClass());
- private final SemaphoreLock sem_;
-
- public SimpleLock()
- {
- sem_ = new SemaphoreLock(1);
- }
-
- /**
- * @see org.jboss.cache.lock.LockStrategy#readLock()
- */
- public Lock readLock()
- {
- return sem_;
- }
-
- /**
- * @see org.jboss.cache.lock.LockStrategy#upgradeLockAttempt(long)
- */
- public Lock upgradeLockAttempt(long msecs)
- {
- return sem_;
- }
-
- /**
- * @see org.jboss.cache.lock.LockStrategy#writeLock()
- */
- public Lock writeLock()
- {
- return sem_;
- }
-}
Deleted: core/trunk/src/main/java/org/jboss/cache/lock/SimpleReadWriteLock.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/lock/SimpleReadWriteLock.java 2008-06-25 13:19:23 UTC (rev 6022)
+++ core/trunk/src/main/java/org/jboss/cache/lock/SimpleReadWriteLock.java 2008-06-25 13:19:39 UTC (rev 6023)
@@ -1,16 +0,0 @@
-package org.jboss.cache.lock;
-
-import java.util.concurrent.locks.ReentrantReadWriteLock;
-
-/**
- * @author Bela Ban
- * @version $Id$
- */
-public class SimpleReadWriteLock extends ReentrantReadWriteLock {
-
- /**
- * It's unclear why this class should be serializable.
- */
- private static final long serialVersionUID = 6317491956891614462L;
-
-}
16 years, 6 months
JBoss Cache SVN: r6022 - core/trunk/src/main/java/org/jboss/cache/lock.
by jbosscache-commits@lists.jboss.org
Author: manik.surtani(a)jboss.com
Date: 2008-06-25 09:19:23 -0400 (Wed, 25 Jun 2008)
New Revision: 6022
Modified:
core/trunk/src/main/java/org/jboss/cache/lock/LockManager.java
Log:
* Updated javadocs
* Updated methods to throw InterruptedException
Modified: core/trunk/src/main/java/org/jboss/cache/lock/LockManager.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/lock/LockManager.java 2008-06-25 13:17:18 UTC (rev 6021)
+++ core/trunk/src/main/java/org/jboss/cache/lock/LockManager.java 2008-06-25 13:19:23 UTC (rev 6022)
@@ -32,7 +32,7 @@
* @param owner owner to acquire the lock for
* @return true if the lock was acquired, false otherwise.
*/
- boolean lock(Fqn fqn, LockType lockType, Object owner);
+ boolean lock(Fqn fqn, LockType lockType, Object owner) throws InterruptedException;
/**
* Acquires a lock of type lockType, for a given owner, on a specific Node in the cache, denoted by fqn. This
@@ -44,7 +44,7 @@
* @param timeout maximum length of time to wait for (in millis)
* @return true if the lock was acquired, false otherwise.
*/
- boolean lock(Fqn fqn, LockType lockType, Object owner, long timeout);
+ boolean lock(Fqn fqn, LockType lockType, Object owner, long timeout) throws InterruptedException;
/**
* As {@link #lock(org.jboss.cache.Fqn, LockType, Object)} except that a NodeSPI is passed in instead of an Fqn.
@@ -54,7 +54,7 @@
* @param owner owner to acquire the lock for
* @return true if the lock was acquired, false otherwise.
*/
- boolean lock(NodeSPI node, LockType lockType, Object owner);
+ boolean lock(NodeSPI node, LockType lockType, Object owner) throws InterruptedException;
/**
* As {@link #lock(org.jboss.cache.Fqn, LockType, Object, long)} except that a NodeSPI is passed in instead of an Fqn.
@@ -65,7 +65,7 @@
* @param timeout maximum length of time to wait for (in millis)
* @return true if the lock was acquired, false otherwise.
*/
- boolean lock(NodeSPI node, LockType lockType, Object owner, long timeout);
+ boolean lock(NodeSPI node, LockType lockType, Object owner, long timeout) throws InterruptedException;
/**
* Acquires a lock of type lockType, on a specific Node in the cache, denoted by fqn. This
@@ -73,8 +73,7 @@
* is specified in {@link org.jboss.cache.config.Option#getLockAcquisitionTimeout()} and, if this is unset, the default timeout
* set in {@link org.jboss.cache.config.Configuration#getLockAcquisitionTimeout()} is used.
* <p/>
- * In addition, any locks acquired are added to the context using {@link org.jboss.cache.InvocationContext#addInvocationLockAcquired(NodeLock)}
- * if you are not running in a transaction, or using {@link org.jboss.cache.transaction.TransactionEntry#addLock(NodeLock)} if you are.
+ * In addition, any locks acquired are added to the context OR transaction entry using {@link org.jboss.cache.InvocationContext#addLock(Object)}.
* <p/>
* The owner for the lock is determined by passing the invocation context to {@link #getLockOwner(org.jboss.cache.InvocationContext)}.
* <p/>
@@ -84,7 +83,7 @@
* @param ctx invocation context associated with this invocation
* @return true if the lock was acquired, false otherwise.
*/
- boolean lockAndRecord(Fqn fqn, LockType lockType, InvocationContext ctx);
+ boolean lockAndRecord(Fqn fqn, LockType lockType, InvocationContext ctx) throws InterruptedException;
/**
* Acquires a lock of type lockType, on a specific Node in the cache, denoted by fqn. This
@@ -92,8 +91,7 @@
* is specified in {@link org.jboss.cache.config.Option#getLockAcquisitionTimeout()} and, if this is unset, the default timeout
* set in {@link org.jboss.cache.config.Configuration#getLockAcquisitionTimeout()} is used.
* <p/>
- * In addition, any locks acquired are added to the context using {@link org.jboss.cache.InvocationContext#addInvocationLockAcquired(NodeLock)}
- * if you are not running in a transaction, or using {@link org.jboss.cache.transaction.TransactionEntry#addLock(NodeLock)} if you are.
+ * In addition, any locks acquired are added to the context OR transaction entry using {@link org.jboss.cache.InvocationContext#addLock(Object)}.
* <p/>
* The owner for the lock is determined by passing the invocation context to {@link #getLockOwner(org.jboss.cache.InvocationContext)}.
* <p/>
@@ -103,7 +101,7 @@
* @param ctx invocation context associated with this invocation
* @return true if the lock was acquired, false otherwise.
*/
- boolean lockAndRecord(NodeSPI node, LockType lockType, InvocationContext ctx);
+ boolean lockAndRecord(NodeSPI node, LockType lockType, InvocationContext ctx) throws InterruptedException;
/**
@@ -147,7 +145,7 @@
* @param owner owner to acquire the lock for
* @return true if the lock was acquired, false otherwise.
*/
- boolean lockAll(NodeSPI node, LockType lockType, Object owner);
+ boolean lockAll(NodeSPI node, LockType lockType, Object owner) throws InterruptedException;
/**
* Locks the node and all child nodes, acquiring lock of type specified for the owner specified. If only some locks are
@@ -159,7 +157,7 @@
* @param timeout maximum length of time to wait for (in millis)
* @return true if all locks were acquired, false otherwise.
*/
- boolean lockAll(NodeSPI node, LockType lockType, Object owner, long timeout);
+ boolean lockAll(NodeSPI node, LockType lockType, Object owner, long timeout) throws InterruptedException;
/**
* Locks the node and all child nodes, acquiring lock of type specified for the owner specified. If only some locks are
@@ -172,14 +170,13 @@
* @param excludeInternalFqns if true, any Fqns that are internal are excluded.
* @return true if all locks were acquired, false otherwise.
*/
- boolean lockAll(NodeSPI node, LockType lockType, Object owner, long timeout, boolean excludeInternalFqns);
+ boolean lockAll(NodeSPI node, LockType lockType, Object owner, long timeout, boolean excludeInternalFqns) throws InterruptedException;
/**
* Locks the node and all child nodes, acquiring lock of type specified for the owner specified. If only some locks are
* acquired, all locks are released and the method returns false.
* <p/>
- * In addition, any locks acquired are added to the context using {@link org.jboss.cache.InvocationContext#addInvocationLockAcquired(NodeLock)}
- * if you are not running in a transaction, or using {@link org.jboss.cache.transaction.TransactionEntry#addLock(NodeLock)} if you are.
+ * In addition, any locks acquired are added to the context OR transaction entry using {@link org.jboss.cache.InvocationContext#addLock(Object)}.
* <p/>
* The owner for the lock is determined by passing the invocation context to {@link #getLockOwner(org.jboss.cache.InvocationContext)}.
* <p/>
@@ -189,14 +186,13 @@
* @param ctx invocation context associated with this invocation
* @return true if all locks were acquired, false otherwise.
*/
- boolean lockAllAndRecord(NodeSPI node, LockType lockType, InvocationContext ctx);
+ boolean lockAllAndRecord(NodeSPI node, LockType lockType, InvocationContext ctx) throws InterruptedException;
/**
* Locks the node and all child nodes, acquiring lock of type specified for the owner specified. If only some locks are
* acquired, all locks are released and the method returns false.
* <p/>
- * In addition, any locks acquired are added to the context using {@link org.jboss.cache.InvocationContext#addInvocationLockAcquired(NodeLock)}
- * if you are not running in a transaction, or using {@link org.jboss.cache.transaction.TransactionEntry#addLock(NodeLock)} if you are.
+ * In addition, any locks acquired are added to the context OR transaction entry using {@link org.jboss.cache.InvocationContext#addLock(Object)}.
* <p/>
* The owner for the lock is determined by passing the invocation context to {@link #getLockOwner(org.jboss.cache.InvocationContext)}.
* <p/>
@@ -206,7 +202,7 @@
* @param ctx invocation context associated with this invocation
* @return true if all locks were acquired, false otherwise.
*/
- boolean lockAllAndRecord(Fqn fqn, LockType lockType, InvocationContext ctx);
+ boolean lockAllAndRecord(Fqn fqn, LockType lockType, InvocationContext ctx) throws InterruptedException;
/**
* Releases locks on a given node and all children for a given owner.
16 years, 6 months
JBoss Cache SVN: r6021 - core/trunk/src/main/java/org/jboss/cache/lock.
by jbosscache-commits@lists.jboss.org
Author: manik.surtani(a)jboss.com
Date: 2008-06-25 09:17:18 -0400 (Wed, 25 Jun 2008)
New Revision: 6021
Modified:
core/trunk/src/main/java/org/jboss/cache/lock/NodeBasedLockManager.java
Log:
UPdated to use new methods on InvocationContext
Modified: core/trunk/src/main/java/org/jboss/cache/lock/NodeBasedLockManager.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/lock/NodeBasedLockManager.java 2008-06-25 13:16:45 UTC (rev 6020)
+++ core/trunk/src/main/java/org/jboss/cache/lock/NodeBasedLockManager.java 2008-06-25 13:17:18 UTC (rev 6021)
@@ -6,7 +6,6 @@
import org.jboss.cache.Fqn;
import org.jboss.cache.InvocationContext;
import org.jboss.cache.NodeSPI;
-import org.jboss.cache.config.Configuration;
import org.jboss.cache.factories.annotations.Inject;
import org.jboss.cache.factories.annotations.Start;
@@ -19,27 +18,23 @@
* @since 2.2
*/
@SuppressWarnings("deprecation")
-public class NodeBasedLockManager implements LockManager
+public class NodeBasedLockManager extends AbstractLockManager
{
private static final Log log = LogFactory.getLog(NodeBasedLockManager.class);
private static final boolean trace = log.isTraceEnabled();
- protected Configuration configuration;
- protected long lockAcquisitionTimeout;
protected DataContainer dataContainer;
protected NodeSPI rootNode;
@Inject
- public void inject(Configuration configuration, DataContainer dataContainer)
+ public void inject(DataContainer dataContainer)
{
- this.configuration = configuration;
this.dataContainer = dataContainer;
}
@Start
public void setRootNode()
{
- this.lockAcquisitionTimeout = configuration.getLockAcquisitionTimeout();
rootNode = dataContainer.getRoot();
}
@@ -78,11 +73,6 @@
return null;
}
- public Object getLockOwner(InvocationContext ctx)
- {
- return ctx.getGlobalTransaction() != null ? ctx.getGlobalTransaction() : Thread.currentThread();
- }
-
public boolean lock(Fqn fqn, LockType lockType, Object owner)
{
return acquireLock(fqn, lockType, owner, lockAcquisitionTimeout) != null;
@@ -120,7 +110,7 @@
}
else
{
- ctx.addInvocationLockAcquired(lock);
+ ctx.addLock(lock);
}
return true;
}
@@ -132,8 +122,8 @@
public void unlock(InvocationContext ctx)
{
- List<NodeLock> locks = ctx.getTransactionEntry() != null ? ctx.getTransactionEntry().getLocks() : ctx.getInvocationLocksAcquired();
- if (locks == null || locks.isEmpty()) return;
+ List<NodeLock> locks = ctx.getLocks();
+ if (locks.isEmpty()) return;
Object owner = getLockOwner(ctx);
// Copying out to an array is faster than creating an ArrayList and iterating,
@@ -145,7 +135,8 @@
log.trace("releasing lock for " + lockArray[i].getFqn() + " (" + lockArray[i] + "), owner " + owner);
lockArray[i].release(owner);
}
- locks.clear();
+
+ ctx.clearLocks();
}
private void unlock(NodeLock lock, Object owner)
@@ -219,11 +210,11 @@
{
if (ctx.getGlobalTransaction() != null)
{
- ctx.getTransactionEntry().addLocks(locks);
+ ctx.getTransactionEntry().addAllLocks(locks);
}
else
{
- ctx.addInvocationLocksAcquired(locks);
+ ctx.addAllLocks(locks);
}
}
16 years, 6 months
JBoss Cache SVN: r6020 - core/trunk/src/test/java/org/jboss/cache/lock.
by jbosscache-commits@lists.jboss.org
Author: manik.surtani(a)jboss.com
Date: 2008-06-25 09:16:45 -0400 (Wed, 25 Jun 2008)
New Revision: 6020
Modified:
core/trunk/src/test/java/org/jboss/cache/lock/ReentrantWriterPreferenceReadWriteLockTest.java
Log:
Updated this not to use deprecated/removed classes
Modified: core/trunk/src/test/java/org/jboss/cache/lock/ReentrantWriterPreferenceReadWriteLockTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/lock/ReentrantWriterPreferenceReadWriteLockTest.java 2008-06-25 13:16:27 UTC (rev 6019)
+++ core/trunk/src/test/java/org/jboss/cache/lock/ReentrantWriterPreferenceReadWriteLockTest.java 2008-06-25 13:16:45 UTC (rev 6020)
@@ -18,8 +18,7 @@
@Test(groups = {"functional"})
public class ReentrantWriterPreferenceReadWriteLockTest
{
- // ReentrantWriterPreferenceReadWriteLock lock;
- SimpleReadWriteLock lock;
+ ReentrantReadWriteLock lock;
Lock rl, wl;
Exception thread_ex = null;
@@ -27,7 +26,7 @@
public void setUp() throws Exception
{
// lock=new ReentrantWriterPreferenceReadWriteLock();
- lock = new SimpleReadWriteLock();
+ lock = new ReentrantReadWriteLock();
rl = lock.readLock();
wl = lock.writeLock();
thread_ex = null;
16 years, 6 months