[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