[jbosscache-commits] JBoss Cache SVN: r6267 - core/trunk/src/main/java/org/jboss/cache.
jbosscache-commits at lists.jboss.org
jbosscache-commits at lists.jboss.org
Tue Jul 15 07:52:05 EDT 2008
Author: manik.surtani at jboss.com
Date: 2008-07-15 07:52:04 -0400 (Tue, 15 Jul 2008)
New Revision: 6267
Modified:
core/trunk/src/main/java/org/jboss/cache/LegacyRegionManagerImpl.java
core/trunk/src/main/java/org/jboss/cache/RegionManagerImpl.java
Log:
fixed locking issues with region activation and deactivation
Modified: core/trunk/src/main/java/org/jboss/cache/LegacyRegionManagerImpl.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/LegacyRegionManagerImpl.java 2008-07-15 11:13:55 UTC (rev 6266)
+++ core/trunk/src/main/java/org/jboss/cache/LegacyRegionManagerImpl.java 2008-07-15 11:52:04 UTC (rev 6267)
@@ -1,7 +1,12 @@
package org.jboss.cache;
import net.jcip.annotations.ThreadSafe;
+import org.jboss.cache.buddyreplication.BuddyManager;
+import static org.jboss.cache.lock.LockType.WRITE;
+import java.util.ArrayList;
+import java.util.Set;
+
/**
* For optimistic and pessimistically locked caches
*
@@ -11,9 +16,133 @@
@ThreadSafe
public class LegacyRegionManagerImpl extends RegionManagerImpl
{
+ /**
+ * Causes the cache to stop accepting replication events for the subtree
+ * rooted at <code>subtreeFqn</code> and evict all nodes in that subtree.
+ * <p/>
+ * This is legacy code and should not be called directly. This is a private method for now and will be refactored out.
+ * You should be using {@link #activate(Fqn)} and {@link #deactivate(Fqn)}
+ * <p/>
+ *
+ * @param fqn Fqn string indicating the uppermost node in the
+ * portion of the cache that should be activated.
+ * @throws CacheException if there is a problem evicting nodes
+ * @throws IllegalStateException if {@link org.jboss.cache.config.Configuration#isUseRegionBasedMarshalling()} is <code>false</code>
+ */
@Override
- protected Object getOwnerForLock()
+ protected void inactivateRegion(Fqn fqn) throws CacheException
{
+ if (isActivatingDeactivating(fqn))
+ throw new CacheException("Region " + fqn + " is already being activated/deactivated");
+
+ NodeSPI parent = null;
+ NodeSPI subtreeRoot = null;
+ boolean parentLocked = false;
+ boolean subtreeLocked = false;
+
+ try
+ {
+ // Record that this fqn is in status change, so can't provide state
+ activationChangeNodes.add(fqn);
+
+ if (!isInactive(fqn))
+ {
+ deactivate(fqn);
+ }
+
+ // Create a list with the Fqn in the main cache and any buddy backup trees
+ BuddyManager buddyManager = cache.getBuddyManager();
+ ArrayList<Fqn> list = new ArrayList<Fqn>();
+ list.add(fqn);
+
+ if (buddyManager != null)
+ {
+ Set buddies = cache.peek(BuddyManager.BUDDY_BACKUP_SUBTREE_FQN, false, false).getChildrenNames();
+ if (buddies != null)
+ {
+ for (Object buddy : buddies)
+ {
+ list.add(buddyFqnTransformer.getBackupFqn((String) buddy, fqn));
+ }
+ }
+ }
+
+ long stateFetchTimeout = cache.getConfiguration().getLockAcquisitionTimeout() + 5000;
+ // Remove the subtree from the main cache and any buddy backup trees
+ for (Fqn subtree : list)
+ {
+ subtreeRoot = cache.peek(subtree, false);
+ if (subtreeRoot != null)
+ {
+ // Acquire locks
+ subtreeLocked = lockManager.lockAll(subtreeRoot, WRITE, getOwnerForLock(), stateFetchTimeout);
+
+ // Lock the parent, as we're about to write to it
+ parent = subtreeRoot.getParentDirect();
+ if (parent != null)
+ parentLocked = lockManager.lockAll(parent, WRITE, getOwnerForLock(), stateFetchTimeout);
+
+ // Remove the subtree
+ cache.evict(subtree, true);
+
+ // Release locks
+ if (parent != null)
+ {
+ log.debug("forcing release of locks in parent");
+ lockManager.unlockAll(parent);
+ }
+
+ parentLocked = false;
+
+ log.debug("forcing release of all locks in subtree");
+ lockManager.unlockAll(subtreeRoot);
+ subtreeLocked = false;
+ }
+ }
+ }
+ catch (InterruptedException e)
+ {
+ throw new CacheException(e);
+ }
+ finally
+ {
+ // If we didn't succeed, undo the marshalling change
+ // NO. Since we inactivated, we may have missed changes
+ //if (!success && !inactive)
+ // marshaller_.activate(subtreeFqn);
+
+ // If necessary, release locks
+ if (parentLocked)
+ {
+ log.debug("forcing release of locks in parent");
+ try
+ {
+ if (parent != null) lockManager.unlockAll(parent);
+ }
+ catch (Throwable t)
+ {
+ log.error("failed releasing locks", t);
+ }
+ }
+ if (subtreeLocked)
+ {
+ log.debug("forcing release of all locks in subtree");
+ try
+ {
+ if (subtreeRoot != null) lockManager.unlockAll(subtreeRoot);
+ }
+ catch (Throwable t)
+ {
+ log.error("failed releasing locks", t);
+ }
+ }
+
+ activationChangeNodes.remove(fqn);
+ }
+ }
+
+ private Object getOwnerForLock()
+ {
Object owner = cache.getCurrentTransaction();
return owner == null ? Thread.currentThread() : owner;
}
Modified: core/trunk/src/main/java/org/jboss/cache/RegionManagerImpl.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/RegionManagerImpl.java 2008-07-15 11:13:55 UTC (rev 6266)
+++ core/trunk/src/main/java/org/jboss/cache/RegionManagerImpl.java 2008-07-15 11:52:04 UTC (rev 6267)
@@ -16,6 +16,7 @@
import org.jboss.cache.factories.annotations.Inject;
import org.jboss.cache.factories.annotations.Start;
import org.jboss.cache.factories.annotations.Stop;
+import org.jboss.cache.invocation.InvocationContext;
import org.jboss.cache.lock.LockManager;
import static org.jboss.cache.lock.LockType.WRITE;
import org.jgroups.Address;
@@ -44,7 +45,7 @@
private RegionRegistry regionsRegistry;
private boolean defaultInactive;
- private final Log log = LogFactory.getLog(RegionManagerImpl.class);
+ protected final Log log = LogFactory.getLog(RegionManagerImpl.class);
CacheSPI cache;
private boolean usingEvictions;
private EvictionConfig evictionConfig;
@@ -54,7 +55,7 @@
protected Configuration configuration;
protected RPCManager rpcManager;
protected LockManager lockManager;
- private BuddyFqnTransformer buddyFqnTransformer;
+ protected BuddyFqnTransformer buddyFqnTransformer;
private boolean isUsingBR;
@Inject
@@ -471,17 +472,17 @@
* @throws CacheException if there is a problem evicting nodes
* @throws IllegalStateException if {@link org.jboss.cache.config.Configuration#isUseRegionBasedMarshalling()} is <code>false</code>
*/
- private void inactivateRegion(Fqn fqn) throws CacheException
+ protected void inactivateRegion(Fqn fqn) throws CacheException
{
if (isActivatingDeactivating(fqn))
- {
throw new CacheException("Region " + fqn + " is already being activated/deactivated");
- }
NodeSPI parent = null;
NodeSPI subtreeRoot = null;
boolean parentLocked = false;
boolean subtreeLocked = false;
+ InvocationContext ctx = cache.getInvocationContext();
+ ctx.getOptionOverrides().setLockAcquisitionTimeout((int) (cache.getConfiguration().getLockAcquisitionTimeout() + 5000));
try
{
@@ -510,36 +511,34 @@
}
}
- long stateFetchTimeout = cache.getConfiguration().getLockAcquisitionTimeout() + 5000;
// Remove the subtree from the main cache and any buddy backup trees
for (Fqn subtree : list)
{
subtreeRoot = cache.peek(subtree, false);
+
if (subtreeRoot != null)
{
// Acquire locks
- subtreeLocked = lockManager.lockAll(subtreeRoot, WRITE, getOwnerForLock(), stateFetchTimeout);
+ subtreeLocked = lockManager.lockAllAndRecord(subtreeRoot, WRITE, ctx);
// Lock the parent, as we're about to write to it
parent = subtreeRoot.getParentDirect();
- if (parent != null)
- parentLocked = lockManager.lockAll(parent, WRITE, getOwnerForLock(), stateFetchTimeout);
+ if (parent != null) parentLocked = lockManager.lockAllAndRecord(parent, WRITE, ctx);
// Remove the subtree
cache.evict(subtree, true);
- //cache._evictSubtree(subtree);
// Release locks
if (parent != null)
{
log.debug("forcing release of locks in parent");
- lockManager.unlockAll(parent);
+ if (lockManager.isLocked(parent)) lockManager.unlock(parent.getFqn(), null);
}
parentLocked = false;
log.debug("forcing release of all locks in subtree");
- lockManager.unlockAll(subtreeRoot);
+ lockManager.unlock(ctx);
subtreeLocked = false;
}
}
@@ -555,13 +554,12 @@
//if (!success && !inactive)
// marshaller_.activate(subtreeFqn);
- // If necessary, release locks
if (parentLocked)
{
log.debug("forcing release of locks in parent");
try
{
- if (parent != null) lockManager.unlockAll(parent);
+ if (parent != null && lockManager.isLocked(parent.getFqn())) lockManager.unlock(parent.getFqn(), null);
}
catch (Throwable t)
{
@@ -573,7 +571,8 @@
log.debug("forcing release of all locks in subtree");
try
{
- if (subtreeRoot != null) lockManager.unlockAll(subtreeRoot);
+ if (subtreeRoot != null && lockManager.isLocked(subtreeRoot.getFqn()))
+ lockManager.unlock(subtreeRoot.getFqn(), null);
}
catch (Throwable t)
{
@@ -581,16 +580,13 @@
}
}
+ // If necessary, release locks
+ if (ctx != null) lockManager.unlock(ctx);
+
activationChangeNodes.remove(fqn);
}
}
- // MVCC deduces lock owners implicitly.
- protected Object getOwnerForLock()
- {
- return null;
- }
-
/**
* <p/>
* This is legacy code and should not be called directly. This is a private method for now and will be refactored out.
@@ -600,7 +596,7 @@
* @param fqn fqn of the region
* @return true if the region defined by the fqn is in the process of activating/deactivating
*/
- private boolean isActivatingDeactivating(Fqn fqn)
+ protected boolean isActivatingDeactivating(Fqn fqn)
{
return activationChangeNodes.contains(fqn);
}
More information about the jbosscache-commits
mailing list