manifoldcf-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From kwri...@apache.org
Subject svn commit: r1539701 - in /manifoldcf/branches/CONNECTORS-13/framework/core/src/main/java/org/apache/manifoldcf/core/lockmanager: BaseLockManager.java LocalLock.java LocalLockPool.java
Date Thu, 07 Nov 2013 16:29:47 GMT
Author: kwright
Date: Thu Nov  7 16:29:47 2013
New Revision: 1539701

URL: http://svn.apache.org/r1539701
Log:
Create base lock manager.  All lock managers will be derived from it, when I am ready

Added:
    manifoldcf/branches/CONNECTORS-13/framework/core/src/main/java/org/apache/manifoldcf/core/lockmanager/BaseLockManager.java
      - copied, changed from r1539618, manifoldcf/branches/CONNECTORS-13/framework/core/src/main/java/org/apache/manifoldcf/core/lockmanager/LockManager.java
    manifoldcf/branches/CONNECTORS-13/framework/core/src/main/java/org/apache/manifoldcf/core/lockmanager/LocalLock.java   (with props)
    manifoldcf/branches/CONNECTORS-13/framework/core/src/main/java/org/apache/manifoldcf/core/lockmanager/LocalLockPool.java   (with props)

Copied: manifoldcf/branches/CONNECTORS-13/framework/core/src/main/java/org/apache/manifoldcf/core/lockmanager/BaseLockManager.java (from r1539618, manifoldcf/branches/CONNECTORS-13/framework/core/src/main/java/org/apache/manifoldcf/core/lockmanager/LockManager.java)
URL: http://svn.apache.org/viewvc/manifoldcf/branches/CONNECTORS-13/framework/core/src/main/java/org/apache/manifoldcf/core/lockmanager/BaseLockManager.java?p2=manifoldcf/branches/CONNECTORS-13/framework/core/src/main/java/org/apache/manifoldcf/core/lockmanager/BaseLockManager.java&p1=manifoldcf/branches/CONNECTORS-13/framework/core/src/main/java/org/apache/manifoldcf/core/lockmanager/LockManager.java&r1=1539618&r2=1539701&rev=1539701&view=diff
==============================================================================
--- manifoldcf/branches/CONNECTORS-13/framework/core/src/main/java/org/apache/manifoldcf/core/lockmanager/LockManager.java (original)
+++ manifoldcf/branches/CONNECTORS-13/framework/core/src/main/java/org/apache/manifoldcf/core/lockmanager/BaseLockManager.java Thu Nov  7 16:29:47 2013
@@ -24,68 +24,50 @@ import org.apache.manifoldcf.core.system
 import java.util.*;
 import java.io.*;
 
-/** The lock manager manages locks across all threads and JVMs and cluster members.  There should be no more than ONE
-* instance of this class per thread!!!  The factory should enforce this.
+/** A lock manager manages locks and shared information across all threads and JVMs
+* and cluster members.  There should be no more than ONE instance of this class per thread!!!
+* The factory should enforce this.
+* This is the base lock manager class.  Its implementation works solely within one JVM,
+* which makes it ideal for single-process work.  Classes that handle multiple JVMs and thus
+* need cross-JVM synchronization are thus expected to extend this class and override pertinent
+* methods.
 */
-public class LockManager implements ILockManager
+public class BaseLockManager implements ILockManager
 {
   public static final String _rcsid = "@(#)$Id: LockManager.java 988245 2010-08-23 18:39:35Z kwright $";
 
-  /** Synchronization directory property - local to this implementation of ILockManager */
-  public static final String synchDirectoryProperty = "org.apache.manifoldcf.synchdirectory";
-
   // These are the lock/section types, in order of escalation
   protected final static int TYPE_READ = 1;
   protected final static int TYPE_WRITENONEX = 2;
   protected final static int TYPE_WRITE = 3;
 
-  // These are for locks (which cross JVM boundaries)
-  protected final HashMap localLocks = new HashMap();
-  protected final static Integer lockPoolInitialization = new Integer(0);
-  protected static LockPool myLocks = null;
+  // These are for locks which putatitively cross JVM boundaries.
+  // In this implementation, they ar strictly local, and are distinct from sections
+  // just because of the namespace issues.
+  protected final LocalLockPool localLocks = new LocalLockPool();
+  protected final static LockPool myLocks = new LockPool(new LockObjectFactory());
 
   // These are for critical sections (which do not cross JVM boundaries)
-  protected final HashMap localSections = new HashMap();
+  protected final LocalLockPool localSections = new LocalLockPool();
   protected final static LockPool mySections = new LockPool(new LockObjectFactory());
 
-  // This is the directory used for cross-JVM synchronization, or null if off
-  protected File synchDirectory = null;
+  /** Global flag information.  This is used only when all of ManifoldCF is run within one process. */
+  protected final static Map<String,Boolean> globalFlags = new HashMap<String,Boolean>();
 
-  public LockManager()
+  /** Global resource data.  Used only when ManifoldCF is run entirely out of one process. */
+  protected final static Map<String,byte[]> globalData = new HashMap<String,byte[]>();
+    
+  public BaseLockManager()
     throws ManifoldCFException
   {
-    synchronized(lockPoolInitialization)
-    {
-      if (myLocks == null)
-      {
-        synchDirectory = ManifoldCF.getFileProperty(synchDirectoryProperty);
-        if (synchDirectory != null)
-        {
-          if (!synchDirectory.isDirectory())
-            throw new ManifoldCFException("Property "+synchDirectoryProperty+" must point to an existing, writeable directory!",ManifoldCFException.SETUP_ERROR);
-        }
-        myLocks = new LockPool(new FileLockObjectFactory(synchDirectory));
-      }
-    }
   }
 
-  /** Calculate the name of a flag resource.
-  *@param flagName is the name of the flag.
-  *@return the name for the flag resource.
-  */
-  protected static String getFlagResourceName(String flagName)
-  {
-    return "flag-"+flagName;
-  }
-  
-  /** Global flag information.  This is used only when all of ManifoldCF is run within one process. */
-  protected static HashMap globalFlags = new HashMap();
-  
   /** Get the current shared configuration.  This configuration is available in common among all nodes,
   * and thus must not be accessed through here for the purpose of finding configuration data that is specific to any one
   * specific node.
   *@param configurationData is the globally-shared configuration information.
   */
+  @Override
   public ManifoldCFConfiguration getSharedConfiguration()
     throws ManifoldCFException
   {
@@ -97,57 +79,28 @@ public class LockManager implements ILoc
   * entire system is restarted.
   *@param flagName is the name of the flag to set.
   */
+  @Override
   public void setGlobalFlag(String flagName)
     throws ManifoldCFException
   {
-    if (synchDirectory == null)
+    // Keep local flag information in memory
+    synchronized (globalFlags)
     {
-      // Keep local flag information in memory
-      synchronized (globalFlags)
-      {
-        globalFlags.put(flagName,new Boolean(true));
-      }
-    }
-    else
-    {
-      String resourceName = getFlagResourceName(flagName);
-      String path = makeFilePath(resourceName);
-      (new File(path)).mkdirs();
-      File f = new File(path,ManifoldCF.safeFileName(resourceName));
-      try
-      {
-        f.createNewFile();
-      }
-      catch (InterruptedIOException e)
-      {
-        throw new ManifoldCFException("Interrupted: "+e.getMessage(),e,ManifoldCFException.INTERRUPTED);
-      }
-      catch (IOException e)
-      {
-        throw new ManifoldCFException(e.getMessage(),e);
-      }
+      globalFlags.put(flagName,new Boolean(true));
     }
   }
 
   /** Clear a flag.  Use this method to clear a condition, or retract a global signal.
   *@param flagName is the name of the flag to clear.
   */
+  @Override
   public void clearGlobalFlag(String flagName)
     throws ManifoldCFException
   {
-    if (synchDirectory == null)
-    {
-      // Keep flag information in memory
-      synchronized (globalFlags)
-      {
-        globalFlags.remove(flagName);
-      }
-    }
-    else
+    // Keep flag information in memory
+    synchronized (globalFlags)
     {
-      String resourceName = getFlagResourceName(flagName);
-      File f = new File(makeFilePath(resourceName),ManifoldCF.safeFileName(resourceName));
-      f.delete();
+      globalFlags.remove(flagName);
     }
   }
   
@@ -155,79 +108,30 @@ public class LockManager implements ILoc
   *@param flagName is the name of the flag to check.
   *@return true if the flag is set, false otherwise.
   */
+  @Override
   public boolean checkGlobalFlag(String flagName)
     throws ManifoldCFException
   {
-    if (synchDirectory == null)
-    {
-      // Keep flag information in memory
-      synchronized (globalFlags)
-      {
-        return globalFlags.get(flagName) != null;
-      }
-    }
-    else
+    // Keep flag information in memory
+    synchronized (globalFlags)
     {
-      String resourceName = getFlagResourceName(flagName);
-      File f = new File(makeFilePath(resourceName),ManifoldCF.safeFileName(resourceName));
-      return f.exists();
+      return globalFlags.get(flagName) != null;
     }
   }
 
-  /** Global resource data.  Used only when ManifoldCF is run entirely out of one process. */
-  protected static HashMap globalData = new HashMap();
-  
   /** Read data from a shared data resource.  Use this method to read any existing data, or get a null back if there is no such resource.
   * Note well that this is not necessarily an atomic operation, and it must thus be protected by a lock.
   *@param resourceName is the global name of the resource.
   *@return a byte array containing the data, or null.
   */
+  @Override
   public byte[] readData(String resourceName)
     throws ManifoldCFException
   {
-    if (synchDirectory == null)
-    {
-      // Keep resource data local
-      synchronized (globalData)
-      {
-        return (byte[])globalData.get(resourceName);
-      }
-    }
-    else
+    // Keep resource data local
+    synchronized (globalData)
     {
-      File f = new File(makeFilePath(resourceName),ManifoldCF.safeFileName(resourceName));
-      try
-      {
-        InputStream is = new FileInputStream(f);
-        try
-        {
-          ByteArrayBuffer bab = new ByteArrayBuffer();
-          while (true)
-          {
-            int x = is.read();
-            if (x == -1)
-              break;
-            bab.add((byte)x);
-          }
-          return bab.toArray();
-        }
-        finally
-        {
-          is.close();
-        }
-      }
-      catch (FileNotFoundException e)
-      {
-        return null;
-      }
-      catch (InterruptedIOException e)
-      {
-        throw new ManifoldCFException("Interrupted: "+e.getMessage(),e,ManifoldCFException.INTERRUPTED);
-      }
-      catch (IOException e)
-      {
-        throw new ManifoldCFException("IO exception: "+e.getMessage(),e);
-      }
+      return globalData.get(resourceName);
     }
   }
   
@@ -236,57 +140,24 @@ public class LockManager implements ILoc
   *@param resourceName is the global name of the resource.
   *@param data is the byte array containing the data.  Pass null if you want to delete the resource completely.
   */
+  @Override
   public void writeData(String resourceName, byte[] data)
     throws ManifoldCFException
   {
-    if (synchDirectory == null)
-    {
-      // Keep resource data local
-      synchronized (globalData)
-      {
-        if (data == null)
-          globalData.remove(resourceName);
-        else
-          globalData.put(resourceName,data);
-      }
-    }
-    else
+    // Keep resource data local
+    synchronized (globalData)
     {
-      try
-      {
-        String path = makeFilePath(resourceName);
-        // Make sure the directory exists
-        (new File(path)).mkdirs();
-        File f = new File(path,ManifoldCF.safeFileName(resourceName));
-        if (data == null)
-        {
-          f.delete();
-          return;
-        }
-        FileOutputStream os = new FileOutputStream(f);
-        try
-        {
-          os.write(data,0,data.length);
-        }
-        finally
-        {
-          os.close();
-        }
-      }
-      catch (InterruptedIOException e)
-      {
-        throw new ManifoldCFException("Interrupted: "+e.getMessage(),e,ManifoldCFException.INTERRUPTED);
-      }
-      catch (IOException e)
-      {
-        throw new ManifoldCFException("IO exception: "+e.getMessage(),e);
-      }
+      if (data == null)
+        globalData.remove(resourceName);
+      else
+        globalData.put(resourceName,data);
     }
   }
 
   /** Wait for a time before retrying a lock.
   */
-  public void timedWait(int time)
+  @Override
+  public final void timedWait(int time)
     throws ManifoldCFException
   {
 
@@ -311,38 +182,42 @@ public class LockManager implements ILoc
   * to an individual item that might affect the query, but where multiple modifications do not individually
   * interfere with one another (use of another, standard, write lock per item can guarantee this).
   */
+  @Override
   public void enterNonExWriteLock(String lockKey)
     throws ManifoldCFException
   {
-
+    enterNonExWrite(lockKey, "lock", localLocks, myLocks);
+  }
+  
+  protected static void enterNonExWrite(String lockKey, String description, LocalLockPool localLocks, LockPool crossLocks)
+    throws ManifoldCFException
+  {
     if (Logging.lock.isDebugEnabled())
-    {
-      Logging.lock.debug("Entering non-ex write lock '"+lockKey+"'");
-    }
-
-    LocalLock ll = getLocalLock(lockKey);
+      Logging.lock.debug("Entering non-ex write "+description+" '"+lockKey+"'");
 
+    LocalLock ll = localLocks.getLocalLock(lockKey);
 
     // See if we already own a write lock for the object
     // If we do, there is no reason to change the status of the global lock we own.
     if (ll.hasNonExWriteLock() || ll.hasWriteLock())
     {
       ll.incrementNonExWriteLocks();
-      Logging.lock.debug(" Successfully obtained lock!");
+      if (Logging.lock.isDebugEnabled())
+        Logging.lock.debug(" Successfully obtained "+description+"!");
       return;
     }
 
     // Check for illegalities
     if (ll.hasReadLock())
     {
-      throw new ManifoldCFException("Illegal lock sequence: NonExWrite lock can't be within read lock",ManifoldCFException.GENERAL_ERROR);
+      throw new ManifoldCFException("Illegal "+description+" sequence: NonExWrite "+description+" can't be within read "+description,ManifoldCFException.GENERAL_ERROR);
     }
 
     // We don't own a local non-ex write lock.  Get one.  The global lock will need
     // to know if we already have a a read lock.
     while (true)
     {
-      LockObject lo = myLocks.getObject(lockKey);
+      LockObject lo = crossLocks.getObject(lockKey);
       try
       {
         lo.enterNonExWriteLock();
@@ -358,19 +233,24 @@ public class LockManager implements ILoc
       }
     }
     ll.incrementNonExWriteLocks();
-    Logging.lock.debug(" Successfully obtained lock!");
+    if (Logging.lock.isDebugEnabled())
+      Logging.lock.debug(" Successfully obtained "+description+"!");
   }
 
-  public void enterNonExWriteLockNoWait(String lockKey)
+  @Override
+  public final void enterNonExWriteLockNoWait(String lockKey)
+    throws ManifoldCFException, LockException
+  {
+    enterNonExWriteNoWait(lockKey, "lock", localLocks, myLocks);
+  }
+  
+  protected static void enterNonExWriteNoWait(String lockKey, String description, LocalLockPool localLocks, LockPool crossLocks)
     throws ManifoldCFException, LockException
   {
-
     if (Logging.lock.isDebugEnabled())
-    {
-      Logging.lock.debug("Entering non-ex write lock no wait '"+lockKey+"'");
-    }
+      Logging.lock.debug("Entering non-ex write "+description+" no wait '"+lockKey+"'");
 
-    LocalLock ll = getLocalLock(lockKey);
+    LocalLock ll = localLocks.getLocalLock(lockKey);
 
 
     // See if we already own a write lock for the object
@@ -378,21 +258,22 @@ public class LockManager implements ILoc
     if (ll.hasNonExWriteLock() || ll.hasWriteLock())
     {
       ll.incrementNonExWriteLocks();
-      Logging.lock.debug(" Successfully obtained lock!");
+      if (Logging.lock.isDebugEnabled())
+        Logging.lock.debug(" Successfully obtained "+description+"!");
       return;
     }
 
     // Check for illegalities
     if (ll.hasReadLock())
     {
-      throw new ManifoldCFException("Illegal lock sequence: NonExWrite lock can't be within read lock",ManifoldCFException.GENERAL_ERROR);
+      throw new ManifoldCFException("Illegal "+description+" sequence: NonExWrite "+description+" can't be within read "+description,ManifoldCFException.GENERAL_ERROR);
     }
 
     // We don't own a local non-ex write lock.  Get one.  The global lock will need
     // to know if we already have a a read lock.
     while (true)
     {
-      LockObject lo = myLocks.getObject(lockKey);
+      LockObject lo = crossLocks.getObject(lockKey);
       try
       {
         synchronized (lo)
@@ -405,9 +286,7 @@ public class LockManager implements ILoc
       {
 
         if (Logging.lock.isDebugEnabled())
-        {
-          Logging.lock.debug(" Could not non-ex write lock '"+lockKey+"', lock exception");
-        }
+          Logging.lock.debug(" Could not non-ex write "+description+" '"+lockKey+"', lock exception");
 
         // Throw LockException instead
         throw new LockException(e.getMessage());
@@ -422,21 +301,26 @@ public class LockManager implements ILoc
       }
     }
     ll.incrementNonExWriteLocks();
-    Logging.lock.debug(" Successfully obtained lock!");
+    if (Logging.lock.isDebugEnabled())
+      Logging.lock.debug(" Successfully obtained "+description+"!");
   }
 
   /** Leave a non-exclusive write lock.
   */
+  @Override
   public void leaveNonExWriteLock(String lockKey)
     throws ManifoldCFException
   {
-
+    leaveNonExWrite(lockKey, "lock", localLocks, myLocks);
+  }
+  
+  protected static void leaveNonExWrite(String lockKey, String description, LocalLockPool localLocks, LockPool crossLocks)
+    throws ManifoldCFException
+  {
     if (Logging.lock.isDebugEnabled())
-    {
-      Logging.lock.debug("Leaving non-ex write lock '"+lockKey+"'");
-    }
+      Logging.lock.debug("Leaving non-ex write "+description+" '"+lockKey+"'");
 
-    LocalLock ll = getLocalLock(lockKey);
+    LocalLock ll = localLocks.getLocalLock(lockKey);
 
     ll.decrementNonExWriteLocks();
     // See if we no longer have a write lock for the object.
@@ -446,7 +330,7 @@ public class LockManager implements ILoc
     {
       while (true)
       {
-        LockObject lo = myLocks.getObject(lockKey);
+        LockObject lo = crossLocks.getObject(lockKey);
         try
         {
           lo.leaveNonExWriteLock();
@@ -477,37 +361,42 @@ public class LockManager implements ILoc
         }
       }
 
-      releaseLocalLock(lockKey);
+      localLocks.releaseLocalLock(lockKey);
     }
   }
 
   /** Enter a write locked area (i.e., block out both readers and other writers)
   * NOTE: Can't enter until all readers have left.
   */
-  public void enterWriteLock(String lockKey)
+  @Override
+  public final void enterWriteLock(String lockKey)
+    throws ManifoldCFException
+  {
+    enterWrite(lockKey, "lock", localLocks, myLocks);
+  }
+  
+  protected static void enterWrite(String lockKey, String description, LocalLockPool localLocks, LockPool crossLocks)
     throws ManifoldCFException
   {
-
     if (Logging.lock.isDebugEnabled())
-    {
-      Logging.lock.debug("Entering write lock '"+lockKey+"'");
-    }
+      Logging.lock.debug("Entering write "+description+" '"+lockKey+"'");
 
-    LocalLock ll = getLocalLock(lockKey);
+    LocalLock ll = localLocks.getLocalLock(lockKey);
 
 
     // See if we already own the write lock for the object
     if (ll.hasWriteLock())
     {
       ll.incrementWriteLocks();
-      Logging.lock.debug(" Successfully obtained lock!");
+      if (Logging.lock.isDebugEnabled())
+        Logging.lock.debug(" Successfully obtained "+description+"!");
       return;
     }
 
     // Check for illegalities
     if (ll.hasReadLock() || ll.hasNonExWriteLock())
     {
-      throw new ManifoldCFException("Illegal lock sequence: Write lock can't be within read lock or non-ex write lock",ManifoldCFException.GENERAL_ERROR);
+      throw new ManifoldCFException("Illegal "+description+" sequence: Write "+description+" can't be within read "+description+" or non-ex write "+description,ManifoldCFException.GENERAL_ERROR);
     }
 
     // We don't own a local write lock.  Get one.  The global lock will need
@@ -515,7 +404,7 @@ public class LockManager implements ILoc
     // it's illegal.
     while (true)
     {
-      LockObject lo = myLocks.getObject(lockKey);
+      LockObject lo = crossLocks.getObject(lockKey);
       try
       {
         lo.enterWriteLock();
@@ -531,33 +420,39 @@ public class LockManager implements ILoc
       }
     }
     ll.incrementWriteLocks();
-    Logging.lock.debug(" Successfully obtained lock!");
+    if (Logging.lock.isDebugEnabled())
+      Logging.lock.debug(" Successfully obtained "+description+"!");
   }
 
+  @Override
   public void enterWriteLockNoWait(String lockKey)
     throws ManifoldCFException, LockException
   {
-
+    enterWriteNoWait(lockKey, "lock", localLocks, myLocks);
+  }
+  
+  protected static void enterWriteNoWait(String lockKey, String description, LocalLockPool localLocks, LockPool crossLocks)
+    throws ManifoldCFException, LockException
+  {
     if (Logging.lock.isDebugEnabled())
-    {
-      Logging.lock.debug("Entering write lock no wait '"+lockKey+"'");
-    }
+      Logging.lock.debug("Entering write "+description+" no wait '"+lockKey+"'");
 
-    LocalLock ll = getLocalLock(lockKey);
+    LocalLock ll = localLocks.getLocalLock(lockKey);
 
 
     // See if we already own the write lock for the object
     if (ll.hasWriteLock())
     {
       ll.incrementWriteLocks();
-      Logging.lock.debug(" Successfully obtained lock!");
+      if (Logging.lock.isDebugEnabled())
+        Logging.lock.debug(" Successfully obtained "+description+"!");
       return;
     }
 
     // Check for illegalities
     if (ll.hasReadLock() || ll.hasNonExWriteLock())
     {
-      throw new ManifoldCFException("Illegal lock sequence: Write lock can't be within read lock or non-ex write lock",ManifoldCFException.GENERAL_ERROR);
+      throw new ManifoldCFException("Illegal "+description+" sequence: Write "+description+" can't be within read "+description+" or non-ex write "+description,ManifoldCFException.GENERAL_ERROR);
     }
 
     // We don't own a local write lock.  Get one.  The global lock will need
@@ -565,7 +460,7 @@ public class LockManager implements ILoc
     // it's illegal.
     while (true)
     {
-      LockObject lo = myLocks.getObject(lockKey);
+      LockObject lo = crossLocks.getObject(lockKey);
       try
       {
         synchronized (lo)
@@ -579,7 +474,7 @@ public class LockManager implements ILoc
 
         if (Logging.lock.isDebugEnabled())
         {
-          Logging.lock.debug(" Could not write lock '"+lockKey+"', lock exception");
+          Logging.lock.debug(" Could not write "+description+" '"+lockKey+"', lock exception");
         }
 
         throw new LockException(e.getMessage());
@@ -595,26 +490,31 @@ public class LockManager implements ILoc
     }
 
     ll.incrementWriteLocks();
-    Logging.lock.debug(" Successfully obtained lock!");
+    if (Logging.lock.isDebugEnabled())
+      Logging.lock.debug(" Successfully obtained "+description+"!");
   }
 
+  @Override
   public void leaveWriteLock(String lockKey)
     throws ManifoldCFException
   {
-
+    leaveWrite(lockKey, "lock", localLocks, myLocks);
+  }
+  
+  protected static void leaveWrite(String lockKey, String description, LocalLockPool localLocks, LockPool crossLocks)
+    throws ManifoldCFException
+  {
     if (Logging.lock.isDebugEnabled())
-    {
-      Logging.lock.debug("Leaving write lock '"+lockKey+"'");
-    }
+      Logging.lock.debug("Leaving write "+description+" '"+lockKey+"'");
 
-    LocalLock ll = getLocalLock(lockKey);
+    LocalLock ll = localLocks.getLocalLock(lockKey);
 
     ll.decrementWriteLocks();
     if (!ll.hasWriteLock())
     {
       while (true)
       {
-        LockObject lo = myLocks.getObject(lockKey);
+        LockObject lo = crossLocks.getObject(lockKey);
         try
         {
           lo.leaveWriteLock();
@@ -645,37 +545,42 @@ public class LockManager implements ILoc
         }
       }
 
-      releaseLocalLock(lockKey);
+      localLocks.releaseLocalLock(lockKey);
     }
   }
 
   /** Enter a read-only locked area (i.e., block ONLY if there's a writer)
   */
-  public void enterReadLock(String lockKey)
+  @Override
+  public final void enterReadLock(String lockKey)
+    throws ManifoldCFException
+  {
+    enterRead(lockKey, "lock", localLocks, myLocks);
+  }
+  
+  protected static void enterRead(String lockKey, String description, LocalLockPool localLocks, LockPool crossLocks)
     throws ManifoldCFException
   {
-
     if (Logging.lock.isDebugEnabled())
-    {
-      Logging.lock.debug("Entering read lock '"+lockKey+"'");
-    }
+      Logging.lock.debug("Entering read "+description+" '"+lockKey+"'");
 
 
-    LocalLock ll = getLocalLock(lockKey);
+    LocalLock ll = localLocks.getLocalLock(lockKey);
 
     // See if we already own the read lock for the object.
     // Write locks or non-ex writelocks count as well (they're stronger).
     if (ll.hasReadLock() || ll.hasNonExWriteLock() || ll.hasWriteLock())
     {
       ll.incrementReadLocks();
-      Logging.lock.debug(" Successfully obtained lock!");
+      if (Logging.lock.isDebugEnabled())
+        Logging.lock.debug(" Successfully obtained "+description+"!");
       return;
     }
 
     // We don't own a local read lock.  Get one.
     while (true)
     {
-      LockObject lo = myLocks.getObject(lockKey);
+      LockObject lo = crossLocks.getObject(lockKey);
       try
       {
         lo.enterReadLock();
@@ -691,33 +596,39 @@ public class LockManager implements ILoc
       }
     }
     ll.incrementReadLocks();
-    Logging.lock.debug(" Successfully obtained lock!");
+    if (Logging.lock.isDebugEnabled())
+      Logging.lock.debug(" Successfully obtained "+description+"!");
   }
 
+  @Override
   public void enterReadLockNoWait(String lockKey)
     throws ManifoldCFException, LockException
   {
-
+    enterReadNoWait(lockKey, "lock", localLocks, myLocks);
+  }
+  
+  protected static void enterReadNoWait(String lockKey, String description, LocalLockPool localLocks, LockPool crossLocks)
+    throws ManifoldCFException, LockException
+  {
     if (Logging.lock.isDebugEnabled())
-    {
-      Logging.lock.debug("Entering read lock no wait '"+lockKey+"'");
-    }
+      Logging.lock.debug("Entering read "+description+" no wait '"+lockKey+"'");
 
-    LocalLock ll = getLocalLock(lockKey);
+    LocalLock ll = localLocks.getLocalLock(lockKey);
 
     // See if we already own the read lock for the object.
     // Write locks or non-ex writelocks count as well (they're stronger).
     if (ll.hasReadLock() || ll.hasNonExWriteLock() || ll.hasWriteLock())
     {
       ll.incrementReadLocks();
-      Logging.lock.debug(" Successfully obtained lock!");
+      if (Logging.lock.isDebugEnabled())
+        Logging.lock.debug(" Successfully obtained "+description+"!");
       return;
     }
 
     // We don't own a local read lock.  Get one.
     while (true)
     {
-      LockObject lo = myLocks.getObject(lockKey);
+      LockObject lo = crossLocks.getObject(lockKey);
       try
       {
         synchronized (lo)
@@ -730,9 +641,7 @@ public class LockManager implements ILoc
       {
 
         if (Logging.lock.isDebugEnabled())
-        {
-          Logging.lock.debug(" Could not read lock '"+lockKey+"', lock exception");
-        }
+          Logging.lock.debug(" Could not read "+description+" '"+lockKey+"', lock exception");
 
         throw new LockException(e.getMessage());
       }
@@ -747,26 +656,31 @@ public class LockManager implements ILoc
     }
 
     ll.incrementReadLocks();
-    Logging.lock.debug(" Successfully obtained lock!");
+    if (Logging.lock.isDebugEnabled())
+      Logging.lock.debug(" Successfully obtained "+description+"!");
   }
 
-  public void leaveReadLock(String lockKey)
+  @Override
+  public final void leaveReadLock(String lockKey)
+    throws ManifoldCFException
+  {
+    leaveRead(lockKey, "lock", localLocks, myLocks);
+  }
+  
+  protected static void leaveRead(String lockKey, String description, LocalLockPool localLocks, LockPool crossLocks)
     throws ManifoldCFException
   {
-
     if (Logging.lock.isDebugEnabled())
-    {
-      Logging.lock.debug("Leaving read lock '"+lockKey+"'");
-    }
+      Logging.lock.debug("Leaving read "+description+" '"+lockKey+"'");
 
-    LocalLock ll = getLocalLock(lockKey);
+    LocalLock ll = localLocks.getLocalLock(lockKey);
 
     ll.decrementReadLocks();
     if (!(ll.hasReadLock() || ll.hasNonExWriteLock() || ll.hasWriteLock()))
     {
       while (true)
       {
-        LockObject lo = myLocks.getObject(lockKey);
+        LockObject lo = crossLocks.getObject(lockKey);
         try
         {
           lo.leaveReadLock();
@@ -796,50 +710,57 @@ public class LockManager implements ILoc
           // Try again
         }
       }
-      releaseLocalLock(lockKey);
+      localLocks.releaseLocalLock(lockKey);
     }
   }
 
+  @Override
   public void clearLocks()
     throws ManifoldCFException
   {
-
+    clear("lock", localLocks, myLocks);
+  }
+  
+  protected static void clear(String description, LocalLockPool localLocks, LockPool crossLocks)
+    throws ManifoldCFException
+  {
     if (Logging.lock.isDebugEnabled())
-    {
-      Logging.lock.debug("Clearing all locks");
-    }
-
+      Logging.lock.debug("Clearing all "+description+"s");
 
-    Iterator e = localLocks.keySet().iterator();
-    while (e.hasNext())
+    for (String keyValue : localLocks.keySet())
     {
-      String keyValue = (String)e.next();
-      LocalLock ll = (LocalLock)localLocks.get(keyValue);
+      LocalLock ll = localLocks.getLocalLock(keyValue);
       while (ll.hasWriteLock())
-        leaveWriteLock(keyValue);
+        leaveWrite(keyValue, description, localLocks, crossLocks);
       while (ll.hasNonExWriteLock())
-        leaveNonExWriteLock(keyValue);
+        leaveNonExWrite(keyValue, description, localLocks, crossLocks);
       while (ll.hasReadLock())
-        leaveReadLock(keyValue);
+        leaveRead(keyValue, description, localLocks, crossLocks);
     }
   }
 
   /** Enter multiple locks
   */
+  @Override
   public void enterLocks(String[] readLocks, String[] nonExWriteLocks, String[] writeLocks)
     throws ManifoldCFException
   {
-
+    enter(readLocks, nonExWriteLocks, writeLocks, "lock", localLocks, myLocks);
+  }
+  
+  protected static void enter(String[] readLocks, String[] nonExWriteLocks, String[] writeLocks, String description, LocalLockPool localLocks, LockPool crossLocks)
+    throws ManifoldCFException
+  {
     if (Logging.lock.isDebugEnabled())
     {
-      Logging.lock.debug("Entering multiple locks:");
+      Logging.lock.debug("Entering multiple "+description+"s:");
       int i;
       if (readLocks != null)
       {
         i = 0;
         while (i < readLocks.length)
         {
-          Logging.lock.debug(" Read lock '"+readLocks[i++]+"'");
+          Logging.lock.debug(" Read "+description+" '"+readLocks[i++]+"'");
         }
       }
       if (nonExWriteLocks != null)
@@ -847,7 +768,7 @@ public class LockManager implements ILoc
         i = 0;
         while (i < nonExWriteLocks.length)
         {
-          Logging.lock.debug(" Non-ex write lock '"+nonExWriteLocks[i++]+"'");
+          Logging.lock.debug(" Non-ex write "+description+" '"+nonExWriteLocks[i++]+"'");
         }
       }
       if (writeLocks != null)
@@ -855,7 +776,7 @@ public class LockManager implements ILoc
         i = 0;
         while (i < writeLocks.length)
         {
-          Logging.lock.debug(" Write lock '"+writeLocks[i++]+"'");
+          Logging.lock.debug(" Write "+description+" '"+writeLocks[i++]+"'");
         }
       }
     }
@@ -876,11 +797,11 @@ public class LockManager implements ILoc
         switch (lockType)
         {
         case TYPE_WRITE:
-          ll = getLocalLock(lockKey);
+          ll = localLocks.getLocalLock(lockKey);
           // Check for illegalities
           if ((ll.hasReadLock() || ll.hasNonExWriteLock()) && !ll.hasWriteLock())
           {
-            throw new ManifoldCFException("Illegal lock sequence: Write lock can't be within read lock or non-ex write lock",ManifoldCFException.GENERAL_ERROR);
+            throw new ManifoldCFException("Illegal "+description+" sequence: Write "+description+" can't be within read "+description+" or non-ex write "+description,ManifoldCFException.GENERAL_ERROR);
           }
 
           // See if we already own the write lock for the object
@@ -889,7 +810,7 @@ public class LockManager implements ILoc
             // We don't own a local write lock.  Get one.
             while (true)
             {
-              LockObject lo = myLocks.getObject(lockKey);
+              LockObject lo = crossLocks.getObject(lockKey);
               try
               {
                 lo.enterWriteLock();
@@ -904,11 +825,11 @@ public class LockManager implements ILoc
           ll.incrementWriteLocks();
           break;
         case TYPE_WRITENONEX:
-          ll = getLocalLock(lockKey);
+          ll = localLocks.getLocalLock(lockKey);
           // Check for illegalities
           if (ll.hasReadLock() && !(ll.hasNonExWriteLock() || ll.hasWriteLock()))
           {
-            throw new ManifoldCFException("Illegal lock sequence: NonExWrite lock can't be within read lock",ManifoldCFException.GENERAL_ERROR);
+            throw new ManifoldCFException("Illegal "+description+" sequence: NonExWrite "+description+" can't be within read "+description,ManifoldCFException.GENERAL_ERROR);
           }
 
           // See if we already own the write lock for the object
@@ -917,7 +838,7 @@ public class LockManager implements ILoc
             // We don't own a local write lock.  Get one.
             while (true)
             {
-              LockObject lo = myLocks.getObject(lockKey);
+              LockObject lo = crossLocks.getObject(lockKey);
               try
               {
                 lo.enterNonExWriteLock();
@@ -932,13 +853,13 @@ public class LockManager implements ILoc
           ll.incrementNonExWriteLocks();
           break;
         case TYPE_READ:
-          ll = getLocalLock(lockKey);
+          ll = localLocks.getLocalLock(lockKey);
           if (!(ll.hasReadLock() || ll.hasNonExWriteLock() || ll.hasWriteLock()))
           {
             // We don't own a local read lock.  Get one.
             while (true)
             {
-              LockObject lo = myLocks.getObject(lockKey);
+              LockObject lo = crossLocks.getObject(lockKey);
               try
               {
                 lo.enterReadLock();
@@ -956,7 +877,7 @@ public class LockManager implements ILoc
         locksProcessed++;
       }
       // Got all; we are done!
-      Logging.lock.debug(" Successfully obtained multiple locks!");
+      Logging.lock.debug(" Successfully obtained multiple "+description+"s!");
       return;
     }
     catch (Throwable ex)
@@ -975,13 +896,13 @@ public class LockManager implements ILoc
           switch (lockType)
           {
           case TYPE_READ:
-            leaveReadLock(lockKey);
+            leaveRead(lockKey,description,localLocks,crossLocks);
             break;
           case TYPE_WRITENONEX:
-            leaveNonExWriteLock(lockKey);
+            leaveNonExWrite(lockKey,description,localLocks,crossLocks);
             break;
           case TYPE_WRITE:
-            leaveWriteLock(lockKey);
+            leaveWrite(lockKey,description,localLocks,crossLocks);
             break;
           }
         }
@@ -1012,20 +933,26 @@ public class LockManager implements ILoc
     }
   }
 
+  @Override
   public void enterLocksNoWait(String[] readLocks, String[] nonExWriteLocks, String[] writeLocks)
     throws ManifoldCFException, LockException
   {
-
+    enterNoWait(readLocks, nonExWriteLocks, writeLocks, "lock", localLocks, myLocks);
+  }
+  
+  protected static void enterNoWait(String[] readLocks, String[] nonExWriteLocks, String[] writeLocks, String description, LocalLockPool localLocks, LockPool crossLocks)
+    throws ManifoldCFException, LockException
+  {
     if (Logging.lock.isDebugEnabled())
     {
-      Logging.lock.debug("Entering multiple locks no wait:");
+      Logging.lock.debug("Entering multiple "+description+"s no wait:");
       int i;
       if (readLocks != null)
       {
         i = 0;
         while (i < readLocks.length)
         {
-          Logging.lock.debug(" Read lock '"+readLocks[i++]+"'");
+          Logging.lock.debug(" Read "+description+" '"+readLocks[i++]+"'");
         }
       }
       if (nonExWriteLocks != null)
@@ -1033,7 +960,7 @@ public class LockManager implements ILoc
         i = 0;
         while (i < nonExWriteLocks.length)
         {
-          Logging.lock.debug(" Non-ex write lock '"+nonExWriteLocks[i++]+"'");
+          Logging.lock.debug(" Non-ex write "+description+" '"+nonExWriteLocks[i++]+"'");
         }
       }
       if (writeLocks != null)
@@ -1041,7 +968,7 @@ public class LockManager implements ILoc
         i = 0;
         while (i < writeLocks.length)
         {
-          Logging.lock.debug(" Write lock '"+writeLocks[i++]+"'");
+          Logging.lock.debug(" Write "+description+" '"+writeLocks[i++]+"'");
         }
       }
     }
@@ -1062,11 +989,11 @@ public class LockManager implements ILoc
         switch (lockType)
         {
         case TYPE_WRITE:
-          ll = getLocalLock(lockKey);
+          ll = localLocks.getLocalLock(lockKey);
           // Check for illegalities
           if ((ll.hasReadLock() || ll.hasNonExWriteLock()) && !ll.hasWriteLock())
           {
-            throw new ManifoldCFException("Illegal lock sequence: Write lock can't be within read lock or non-ex write lock",ManifoldCFException.GENERAL_ERROR);
+            throw new ManifoldCFException("Illegal "+description+" sequence: Write "+description+" can't be within read "+description+" or non-ex write "+description,ManifoldCFException.GENERAL_ERROR);
           }
 
           // See if we already own the write lock for the object
@@ -1075,7 +1002,7 @@ public class LockManager implements ILoc
             // We don't own a local write lock.  Get one.
             while (true)
             {
-              LockObject lo = myLocks.getObject(lockKey);
+              LockObject lo = crossLocks.getObject(lockKey);
               synchronized (lo)
               {
                 try
@@ -1093,11 +1020,11 @@ public class LockManager implements ILoc
           ll.incrementWriteLocks();
           break;
         case TYPE_WRITENONEX:
-          ll = getLocalLock(lockKey);
+          ll = localLocks.getLocalLock(lockKey);
           // Check for illegalities
           if (ll.hasReadLock() && !(ll.hasNonExWriteLock() || ll.hasWriteLock()))
           {
-            throw new ManifoldCFException("Illegal lock sequence: NonExWrite lock can't be within read lock",ManifoldCFException.GENERAL_ERROR);
+            throw new ManifoldCFException("Illegal "+description+" sequence: NonExWrite "+description+" can't be within read "+description,ManifoldCFException.GENERAL_ERROR);
           }
 
           // See if we already own the write lock for the object
@@ -1106,7 +1033,7 @@ public class LockManager implements ILoc
             // We don't own a local write lock.  Get one.
             while (true)
             {
-              LockObject lo = myLocks.getObject(lockKey);
+              LockObject lo = crossLocks.getObject(lockKey);
               synchronized (lo)
               {
                 try
@@ -1124,13 +1051,13 @@ public class LockManager implements ILoc
           ll.incrementNonExWriteLocks();
           break;
         case TYPE_READ:
-          ll = getLocalLock(lockKey);
+          ll = localLocks.getLocalLock(lockKey);
           if (!(ll.hasReadLock() || ll.hasNonExWriteLock() || ll.hasWriteLock()))
           {
             // We don't own a local read lock.  Get one.
             while (true)
             {
-              LockObject lo = myLocks.getObject(lockKey);
+              LockObject lo = crossLocks.getObject(lockKey);
               synchronized (lo)
               {
                 try
@@ -1151,7 +1078,8 @@ public class LockManager implements ILoc
         locksProcessed++;
       }
       // Got all; we are done!
-      Logging.lock.debug(" Successfully obtained multiple locks!");
+      if (Logging.lock.isDebugEnabled())
+        Logging.lock.debug(" Successfully obtained multiple "+description+"s!");
       return;
     }
     catch (Throwable ex)
@@ -1170,13 +1098,13 @@ public class LockManager implements ILoc
           switch (lockType)
           {
           case TYPE_READ:
-            leaveReadLock(lockKey);
+            leaveRead(lockKey,description,localLocks,crossLocks);
             break;
           case TYPE_WRITENONEX:
-            leaveNonExWriteLock(lockKey);
+            leaveNonExWrite(lockKey,description,localLocks,crossLocks);
             break;
           case TYPE_WRITE:
-            leaveWriteLock(lockKey);
+            leaveWrite(lockKey,description,localLocks,crossLocks);
             break;
           }
         }
@@ -1196,7 +1124,7 @@ public class LockManager implements ILoc
       }
       if (ex instanceof LockException || ex instanceof LocalLockException)
       {
-        Logging.lock.debug(" Couldn't get lock; throwing LockException");
+        Logging.lock.debug(" Couldn't get "+description+"; throwing LockException");
         // It's either LockException or LocalLockException
         throw new LockException(ex.getMessage());
       }
@@ -1216,9 +1144,16 @@ public class LockManager implements ILoc
 
   /** Leave multiple locks
   */
+  @Override
   public void leaveLocks(String[] readLocks, String[] writeNonExLocks, String[] writeLocks)
     throws ManifoldCFException
   {
+    leave(readLocks, writeNonExLocks, writeLocks, "lock", localLocks, myLocks);
+  }
+  
+  protected static void leave(String[] readLocks, String[] writeNonExLocks, String[] writeLocks, String description, LocalLockPool localLocks, LockPool crossLocks)
+    throws ManifoldCFException
+  {
     LockDescription[] lds = getSortedUniqueLocks(readLocks,writeNonExLocks,writeLocks);
     // Free them all... one at a time is fine
     ManifoldCFException ae = null;
@@ -1233,13 +1168,13 @@ public class LockManager implements ILoc
         switch (lockType)
         {
         case TYPE_READ:
-          leaveReadLock(lockKey);
+          leaveRead(lockKey,description,localLocks,crossLocks);
           break;
         case TYPE_WRITENONEX:
-          leaveNonExWriteLock(lockKey);
+          leaveNonExWrite(lockKey,description,localLocks,crossLocks);
           break;
         case TYPE_WRITE:
-          leaveWriteLock(lockKey);
+          leaveWrite(lockKey,description,localLocks,crossLocks);
           break;
         }
       }
@@ -1260,38 +1195,11 @@ public class LockManager implements ILoc
   *@param sectionKey is the name of the section to enter.  Only one thread can be in any given named
   * section at a time.
   */
-  public void enterReadCriticalSection(String sectionKey)
+  @Override
+  public final void enterReadCriticalSection(String sectionKey)
     throws ManifoldCFException
   {
-    LocalLock ll = getLocalSection(sectionKey);
-
-    // See if we already own the read lock for the object.
-    // Write locks or non-ex writelocks count as well (they're stronger).
-    if (ll.hasReadLock() || ll.hasNonExWriteLock() || ll.hasWriteLock())
-    {
-      ll.incrementReadLocks();
-      return;
-    }
-
-    // We don't own a local read lock.  Get one.
-    while (true)
-    {
-      LockObject lo = mySections.getObject(sectionKey);
-      try
-      {
-        lo.enterReadLock();
-        break;
-      }
-      catch (InterruptedException e)
-      {
-        throw new ManifoldCFException("Interrupted",e,ManifoldCFException.INTERRUPTED);
-      }
-      catch (ExpiredObjectException e)
-      {
-        // Try again
-      }
-    }
-    ll.incrementReadLocks();
+    enterRead(sectionKey, "critical section", localSections, mySections);
   }
 
   /** Leave a named, read critical section (NOT a lock).  Critical sections never cross JVM boundaries.
@@ -1299,49 +1207,11 @@ public class LockManager implements ILoc
   *@param sectionKey is the name of the section to leave.  Only one thread can be in any given named
   * section at a time.
   */
-  public void leaveReadCriticalSection(String sectionKey)
+  @Override
+  public final void leaveReadCriticalSection(String sectionKey)
     throws ManifoldCFException
   {
-    LocalLock ll = getLocalSection(sectionKey);
-
-    ll.decrementReadLocks();
-    if (!(ll.hasReadLock() || ll.hasNonExWriteLock() || ll.hasWriteLock()))
-    {
-      while (true)
-      {
-        LockObject lo = mySections.getObject(sectionKey);
-        try
-        {
-          lo.leaveReadLock();
-          break;
-        }
-        catch (InterruptedException e)
-        {
-          // Try one more time
-          try
-          {
-            lo.leaveReadLock();
-            throw new ManifoldCFException("Interrupted",e,ManifoldCFException.INTERRUPTED);
-          }
-          catch (InterruptedException e2)
-          {
-            ll.incrementReadLocks();
-            throw new ManifoldCFException("Interrupted",e2,ManifoldCFException.INTERRUPTED);
-          }
-          catch (ExpiredObjectException e2)
-          {
-            ll.incrementReadLocks();
-            throw new ManifoldCFException("Interrupted",e,ManifoldCFException.INTERRUPTED);
-          }
-        }
-        catch (ExpiredObjectException e)
-        {
-          // Try again
-        }
-      }
-
-      releaseLocalSection(sectionKey);
-    }
+    leaveRead(sectionKey, "critical section", localSections, mySections);
   }
 
   /** Enter a named, non-exclusive write critical section (NOT a lock).  Critical sections never cross JVM boundaries.
@@ -1349,197 +1219,47 @@ public class LockManager implements ILoc
   *@param sectionKey is the name of the section to enter.  Only one thread can be in any given named
   * section at a time.
   */
-  public void enterNonExWriteCriticalSection(String sectionKey)
+  @Override
+  public final void enterNonExWriteCriticalSection(String sectionKey)
     throws ManifoldCFException
   {
-    LocalLock ll = getLocalSection(sectionKey);
-
-
-    // See if we already own a write lock for the object
-    // If we do, there is no reason to change the status of the global lock we own.
-    if (ll.hasNonExWriteLock() || ll.hasWriteLock())
-    {
-      ll.incrementNonExWriteLocks();
-      return;
-    }
-
-    // Check for illegalities
-    if (ll.hasReadLock())
-    {
-      throw new ManifoldCFException("Illegal lock sequence: NonExWrite critical section can't be within read critical section",ManifoldCFException.GENERAL_ERROR);
-    }
-
-    // We don't own a local non-ex write lock.  Get one.  The global lock will need
-    // to know if we already have a a read lock.
-    while (true)
-    {
-      LockObject lo = mySections.getObject(sectionKey);
-      try
-      {
-        lo.enterNonExWriteLock();
-        break;
-      }
-      catch (InterruptedException e)
-      {
-        throw new ManifoldCFException("Interrupted",e,ManifoldCFException.INTERRUPTED);
-      }
-      catch (ExpiredObjectException e)
-      {
-        // Try again
-      }
-    }
-    ll.incrementNonExWriteLocks();
-  }
+    enterNonExWrite(sectionKey, "critical section", localSections, mySections);
+  }
 
   /** Leave a named, non-exclusive write critical section (NOT a lock).  Critical sections never cross JVM boundaries.
   * Critical section names do not collide with lock names; they have a distinct namespace.
   *@param sectionKey is the name of the section to leave.  Only one thread can be in any given named
   * section at a time.
   */
-  public void leaveNonExWriteCriticalSection(String sectionKey)
+  @Override
+  public final void leaveNonExWriteCriticalSection(String sectionKey)
     throws ManifoldCFException
   {
-    LocalLock ll = getLocalSection(sectionKey);
-
-    ll.decrementNonExWriteLocks();
-    // See if we no longer have a write lock for the object.
-    // If we retain the stronger exclusive lock, we still do not need to
-    // change the status of the global lock.
-    if (!(ll.hasNonExWriteLock() || ll.hasWriteLock()))
-    {
-      while (true)
-      {
-        LockObject lo = mySections.getObject(sectionKey);
-        try
-        {
-          lo.leaveNonExWriteLock();
-          break;
-        }
-        catch (InterruptedException e)
-        {
-          // try one more time
-          try
-          {
-            lo.leaveNonExWriteLock();
-            throw new ManifoldCFException("Interrupted",e,ManifoldCFException.INTERRUPTED);
-          }
-          catch (InterruptedException e2)
-          {
-            ll.incrementNonExWriteLocks();
-            throw new ManifoldCFException("Interrupted",e2,ManifoldCFException.INTERRUPTED);
-          }
-          catch (ExpiredObjectException e2)
-          {
-            ll.incrementNonExWriteLocks();
-            throw new ManifoldCFException("Interrupted",e,ManifoldCFException.INTERRUPTED);
-          }
-        }
-        catch (ExpiredObjectException e)
-        {
-          // Try again
-        }
-      }
-
-      releaseLocalSection(sectionKey);
-    }
+    leaveNonExWrite(sectionKey, "critical section", localSections, mySections);
   }
-
+  
   /** Enter a named, exclusive critical section (NOT a lock).  Critical sections never cross JVM boundaries.
   * Critical section names should be distinct from all lock names.
   *@param sectionKey is the name of the section to enter.  Only one thread can be in any given named
   * section at a time.
   */
-  public void enterWriteCriticalSection(String sectionKey)
+  @Override
+  public final void enterWriteCriticalSection(String sectionKey)
     throws ManifoldCFException
   {
-    LocalLock ll = getLocalSection(sectionKey);
-
-
-    // See if we already own the write lock for the object
-    if (ll.hasWriteLock())
-    {
-      ll.incrementWriteLocks();
-      return;
-    }
-
-    // Check for illegalities
-    if (ll.hasReadLock() || ll.hasNonExWriteLock())
-    {
-      throw new ManifoldCFException("Illegal lock sequence: Write lock can't be within read lock or non-ex write lock",ManifoldCFException.GENERAL_ERROR);
-    }
-
-    // We don't own a local write lock.  Get one.  The global lock will need
-    // to know if we already have a non-exclusive lock or a read lock, which we don't because
-    // it's illegal.
-    while (true)
-    {
-      LockObject lo = mySections.getObject(sectionKey);
-      try
-      {
-        lo.enterWriteLock();
-        break;
-      }
-      catch (InterruptedException e)
-      {
-        throw new ManifoldCFException("Interrupted",e,ManifoldCFException.INTERRUPTED);
-      }
-      catch (ExpiredObjectException e)
-      {
-        // Try again
-      }
-    }
-    ll.incrementWriteLocks();
-
+    enterWrite(sectionKey, "critical section", localSections, mySections);
   }
-
+  
   /** Leave a named, exclusive critical section (NOT a lock).  Critical sections never cross JVM boundaries.
   * Critical section names should be distinct from all lock names.
   *@param sectionKey is the name of the section to leave.  Only one thread can be in any given named
   * section at a time.
   */
-  public void leaveWriteCriticalSection(String sectionKey)
+  @Override
+  public final void leaveWriteCriticalSection(String sectionKey)
     throws ManifoldCFException
   {
-    LocalLock ll = getLocalSection(sectionKey);
-
-    ll.decrementWriteLocks();
-    if (!ll.hasWriteLock())
-    {
-      while (true)
-      {
-        LockObject lo = mySections.getObject(sectionKey);
-        try
-        {
-          lo.leaveWriteLock();
-          break;
-        }
-        catch (InterruptedException e)
-        {
-          // try one more time
-          try
-          {
-            lo.leaveWriteLock();
-            throw new ManifoldCFException("Interrupted",e,ManifoldCFException.INTERRUPTED);
-          }
-          catch (InterruptedException e2)
-          {
-            ll.incrementWriteLocks();
-            throw new ManifoldCFException("Interrupted",e2,ManifoldCFException.INTERRUPTED);
-          }
-          catch (ExpiredObjectException e2)
-          {
-            ll.incrementWriteLocks();
-            throw new ManifoldCFException("Interrupted",e,ManifoldCFException.INTERRUPTED);
-          }
-        }
-        catch (ExpiredObjectException e)
-        {
-          // Try again
-        }
-      }
-
-      releaseLocalSection(sectionKey);
-    }
+    leaveWrite(sectionKey, "critical section", localSections, mySections);
   }
 
   /** Enter multiple critical sections simultaneously.
@@ -1547,157 +1267,11 @@ public class LockManager implements ILoc
   *@param nonExSectionKeys is an array of non-ex write section descriptors, or null if none desired.
   *@param writeSectionKeys is an array of write section descriptors, or null if there are none desired.
   */
-  public void enterCriticalSections(String[] readSectionKeys, String[] nonExSectionKeys, String[] writeSectionKeys)
+  @Override
+  public final void enterCriticalSections(String[] readSectionKeys, String[] nonExSectionKeys, String[] writeSectionKeys)
     throws ManifoldCFException
   {
-    // Sort the locks.  This improves the chances of making it through the locking process without
-    // contention!
-    LockDescription lds[] = getSortedUniqueLocks(readSectionKeys,nonExSectionKeys,writeSectionKeys);
-    int locksProcessed = 0;
-    try
-    {
-      while (locksProcessed < lds.length)
-      {
-        LockDescription ld = lds[locksProcessed];
-        int lockType = ld.getType();
-        String lockKey = ld.getKey();
-        LocalLock ll;
-        switch (lockType)
-        {
-        case TYPE_WRITE:
-          ll = getLocalSection(lockKey);
-          // Check for illegalities
-          if ((ll.hasReadLock() || ll.hasNonExWriteLock()) && !ll.hasWriteLock())
-          {
-            throw new ManifoldCFException("Illegal lock sequence: Write critical section can't be within read critical section or non-ex write critical section",ManifoldCFException.GENERAL_ERROR);
-          }
-
-          // See if we already own the write lock for the object
-          if (!ll.hasWriteLock())
-          {
-            // We don't own a local write lock.  Get one.
-            while (true)
-            {
-              LockObject lo = mySections.getObject(lockKey);
-              try
-              {
-                lo.enterWriteLock();
-                break;
-              }
-              catch (ExpiredObjectException e)
-              {
-                // Try again
-              }
-            }
-          }
-          ll.incrementWriteLocks();
-          break;
-        case TYPE_WRITENONEX:
-          ll = getLocalSection(lockKey);
-          // Check for illegalities
-          if (ll.hasReadLock() && !(ll.hasNonExWriteLock() || ll.hasWriteLock()))
-          {
-            throw new ManifoldCFException("Illegal lock sequence: NonExWrite critical section can't be within read critical section",ManifoldCFException.GENERAL_ERROR);
-          }
-
-          // See if we already own the write lock for the object
-          if (!(ll.hasNonExWriteLock() || ll.hasWriteLock()))
-          {
-            // We don't own a local write lock.  Get one.
-            while (true)
-            {
-              LockObject lo = mySections.getObject(lockKey);
-              try
-              {
-                lo.enterNonExWriteLock();
-                break;
-              }
-              catch (ExpiredObjectException e)
-              {
-                // Try again
-              }
-            }
-          }
-          ll.incrementNonExWriteLocks();
-          break;
-        case TYPE_READ:
-          ll = getLocalSection(lockKey);
-          if (!(ll.hasReadLock() || ll.hasNonExWriteLock() || ll.hasWriteLock()))
-          {
-            // We don't own a local read lock.  Get one.
-            while (true)
-            {
-              LockObject lo = mySections.getObject(lockKey);
-              try
-              {
-                lo.enterReadLock();
-                break;
-              }
-              catch (ExpiredObjectException e)
-              {
-                // Try again
-              }
-            }
-          }
-          ll.incrementReadLocks();
-          break;
-        }
-        locksProcessed++;
-      }
-      // Got all; we are done!
-      return;
-    }
-    catch (Throwable ex)
-    {
-      // No matter what, undo the locks we've taken
-      ManifoldCFException ae = null;
-      int errno = 0;
-
-      while (--locksProcessed >= 0)
-      {
-        LockDescription ld = lds[locksProcessed];
-        int lockType = ld.getType();
-        String lockKey = ld.getKey();
-        try
-        {
-          switch (lockType)
-          {
-          case TYPE_READ:
-            leaveReadCriticalSection(lockKey);
-            break;
-          case TYPE_WRITENONEX:
-            leaveNonExWriteCriticalSection(lockKey);
-            break;
-          case TYPE_WRITE:
-            leaveWriteCriticalSection(lockKey);
-            break;
-          }
-        }
-        catch (ManifoldCFException e)
-        {
-          ae = e;
-        }
-      }
-
-      if (ae != null)
-      {
-        throw ae;
-      }
-      if (ex instanceof ManifoldCFException)
-      {
-        throw (ManifoldCFException)ex;
-      }
-      if (ex instanceof InterruptedException)
-      {
-        // It's InterruptedException
-        throw new ManifoldCFException("Interrupted",ex,ManifoldCFException.INTERRUPTED);
-      }
-      if (!(ex instanceof Error))
-      {
-        throw new Error("Unexpected exception",ex);
-      }
-      throw (Error)ex;
-    }
+    enter(readSectionKeys, nonExSectionKeys, writeSectionKeys, "critical section", localSections, mySections);
   }
 
   /** Leave multiple critical sections simultaneously.
@@ -1705,84 +1279,20 @@ public class LockManager implements ILoc
   *@param nonExSectionKeys is an array of non-ex write section descriptors, or null if none desired.
   *@param writeSectionKeys is an array of write section descriptors, or null if there are none desired.
   */
-  public void leaveCriticalSections(String[] readSectionKeys, String[] nonExSectionKeys, String[] writeSectionKeys)
+  @Override
+  public final void leaveCriticalSections(String[] readSectionKeys, String[] nonExSectionKeys, String[] writeSectionKeys)
     throws ManifoldCFException
   {
-    LockDescription[] lds = getSortedUniqueLocks(readSectionKeys,nonExSectionKeys,writeSectionKeys);
-    // Free them all... one at a time is fine
-    ManifoldCFException ae = null;
-    int i = lds.length;
-    while (--i >= 0)
-    {
-      LockDescription ld = lds[i];
-      String lockKey = ld.getKey();
-      int lockType = ld.getType();
-      try
-      {
-        switch (lockType)
-        {
-        case TYPE_READ:
-          leaveReadCriticalSection(lockKey);
-          break;
-        case TYPE_WRITENONEX:
-          leaveNonExWriteCriticalSection(lockKey);
-          break;
-        case TYPE_WRITE:
-          leaveWriteCriticalSection(lockKey);
-          break;
-        }
-      }
-      catch (ManifoldCFException e)
-      {
-        ae = e;
-      }
-    }
-
-    if (ae != null)
-    {
-      throw ae;
-    }
-  }
-
-  protected LocalLock getLocalLock(String lockKey)
-  {
-    LocalLock ll = (LocalLock)localLocks.get(lockKey);
-    if (ll == null)
-    {
-      ll = new LocalLock();
-      localLocks.put(lockKey,ll);
-    }
-    return ll;
-  }
-
-  protected void releaseLocalLock(String lockKey)
-  {
-    localLocks.remove(lockKey);
-  }
-
-  protected LocalLock getLocalSection(String sectionKey)
-  {
-    LocalLock ll = (LocalLock)localSections.get(sectionKey);
-    if (ll == null)
-    {
-      ll = new LocalLock();
-      localSections.put(sectionKey,ll);
-    }
-    return ll;
-  }
-
-  protected void releaseLocalSection(String sectionKey)
-  {
-    localSections.remove(sectionKey);
+    leave(readSectionKeys, nonExSectionKeys, writeSectionKeys, "critical section", localSections, mySections);
   }
 
   /** Process inbound locks into a sorted vector of most-restrictive unique locks
   */
-  protected LockDescription[] getSortedUniqueLocks(String[] readLocks, String[] writeNonExLocks,
+  protected static LockDescription[] getSortedUniqueLocks(String[] readLocks, String[] writeNonExLocks,
     String[] writeLocks)
   {
     // First build a unique hash of lock descriptions
-    HashMap ht = new HashMap();
+    Map<String,LockDescription> ht = new HashMap<String,LockDescription>();
     int i;
     if (readLocks != null)
     {
@@ -1790,7 +1300,7 @@ public class LockManager implements ILoc
       while (i < readLocks.length)
       {
         String key = readLocks[i++];
-        LockDescription ld = (LockDescription)ht.get(key);
+        LockDescription ld = ht.get(key);
         if (ld == null)
         {
           ld = new LockDescription(TYPE_READ,key);
@@ -1806,7 +1316,7 @@ public class LockManager implements ILoc
       while (i < writeNonExLocks.length)
       {
         String key = writeNonExLocks[i++];
-        LockDescription ld = (LockDescription)ht.get(key);
+        LockDescription ld = ht.get(key);
         if (ld == null)
         {
           ld = new LockDescription(TYPE_WRITENONEX,key);
@@ -1822,7 +1332,7 @@ public class LockManager implements ILoc
       while (i < writeLocks.length)
       {
         String key = writeLocks[i++];
-        LockDescription ld = (LockDescription)ht.get(key);
+        LockDescription ld = ht.get(key);
         if (ld == null)
         {
           ld = new LockDescription(TYPE_WRITE,key);
@@ -1837,39 +1347,20 @@ public class LockManager implements ILoc
     LockDescription[] rval = new LockDescription[ht.size()];
     String[] sortarray = new String[ht.size()];
     i = 0;
-    Iterator iter = ht.keySet().iterator();
-    while (iter.hasNext())
+    for (String key : ht.keySet())
     {
-      String key = (String)iter.next();
       sortarray[i++] = key;
     }
     java.util.Arrays.sort(sortarray);
     i = 0;
-    while (i < sortarray.length)
+    for (String key : sortarray)
     {
-      rval[i] = (LockDescription)ht.get(sortarray[i]);
-      i++;
+      rval[i++] = ht.get(key);
     }
     return rval;
   }
 
-  /** Create a file path given a key name.
-  *@param key is the key name.
-  *@return the file path.
-  */
-  protected String makeFilePath(String key)
-  {
-    int hashcode = key.hashCode();
-    int outerDirNumber = (hashcode & (1023));
-    int innerDirNumber = ((hashcode >> 10) & (1023));
-    String fullDir = synchDirectory.toString();
-    if (fullDir.length() == 0 || !fullDir.endsWith("/"))
-      fullDir = fullDir + "/";
-    fullDir = fullDir + Integer.toString(outerDirNumber)+"/"+Integer.toString(innerDirNumber);
-    return fullDir;
-  }
-
-  protected class LockDescription
+  protected static class LockDescription
   {
     protected int lockType;
     protected String lockKey;
@@ -1897,92 +1388,5 @@ public class LockManager implements ILoc
     }
   }
 
-  protected class LocalLock
-  {
-    private int readCount = 0;
-    private int writeCount = 0;
-    private int nonExWriteCount = 0;
-
-    public LocalLock()
-    {
-    }
-
-    public boolean hasWriteLock()
-    {
-      return (writeCount > 0);
-    }
-
-    public boolean hasReadLock()
-    {
-      return (readCount > 0);
-    }
-
-    public boolean hasNonExWriteLock()
-    {
-      return (nonExWriteCount > 0);
-    }
-
-    public void incrementReadLocks()
-    {
-      readCount++;
-    }
-
-    public void incrementNonExWriteLocks()
-    {
-      nonExWriteCount++;
-    }
-
-    public void incrementWriteLocks()
-    {
-      writeCount++;
-    }
-
-    public void decrementReadLocks()
-    {
-      readCount--;
-    }
-
-    public void decrementNonExWriteLocks()
-    {
-      nonExWriteCount--;
-    }
-
-    public void decrementWriteLocks()
-    {
-      writeCount--;
-    }
-  }
-  
-  protected static final int BASE_SIZE = 128;
-  
-  protected static class ByteArrayBuffer
-  {
-    protected byte[] buffer;
-    protected int length;
-    
-    public ByteArrayBuffer()
-    {
-      buffer = new byte[BASE_SIZE];
-      length = 0;
-    }
-    
-    public void add(byte b)
-    {
-      if (length == buffer.length)
-      {
-        byte[] oldbuffer = buffer;
-        buffer = new byte[length * 2];
-        System.arraycopy(oldbuffer,0,buffer,0,length);
-      }
-      buffer[length++] = b;
-    }
-    
-    public byte[] toArray()
-    {
-      byte[] rval = new byte[length];
-      System.arraycopy(buffer,0,rval,0,length);
-      return rval;
-    }
-  }
 
 }

Added: manifoldcf/branches/CONNECTORS-13/framework/core/src/main/java/org/apache/manifoldcf/core/lockmanager/LocalLock.java
URL: http://svn.apache.org/viewvc/manifoldcf/branches/CONNECTORS-13/framework/core/src/main/java/org/apache/manifoldcf/core/lockmanager/LocalLock.java?rev=1539701&view=auto
==============================================================================
--- manifoldcf/branches/CONNECTORS-13/framework/core/src/main/java/org/apache/manifoldcf/core/lockmanager/LocalLock.java (added)
+++ manifoldcf/branches/CONNECTORS-13/framework/core/src/main/java/org/apache/manifoldcf/core/lockmanager/LocalLock.java Thu Nov  7 16:29:47 2013
@@ -0,0 +1,81 @@
+/* $Id$ */
+
+/**
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+package org.apache.manifoldcf.core.lockmanager;
+
+import java.util.*;
+import java.io.*;
+
+/** This class describes a local lock, which can have various nested levels
+* of depth.
+*/
+public class LocalLock
+{
+  private int readCount = 0;
+  private int writeCount = 0;
+  private int nonExWriteCount = 0;
+
+  public LocalLock()
+  {
+  }
+
+  public boolean hasWriteLock()
+  {
+    return (writeCount > 0);
+  }
+
+  public boolean hasReadLock()
+  {
+    return (readCount > 0);
+  }
+
+  public boolean hasNonExWriteLock()
+  {
+    return (nonExWriteCount > 0);
+  }
+
+  public void incrementReadLocks()
+  {
+    readCount++;
+  }
+
+  public void incrementNonExWriteLocks()
+  {
+    nonExWriteCount++;
+  }
+  
+  public void incrementWriteLocks()
+  {
+    writeCount++;
+  }
+
+  public void decrementReadLocks()
+  {
+    readCount--;
+  }
+  
+  public void decrementNonExWriteLocks()
+  {
+    nonExWriteCount--;
+  }
+
+  public void decrementWriteLocks()
+  {
+    writeCount--;
+  }
+}

Propchange: manifoldcf/branches/CONNECTORS-13/framework/core/src/main/java/org/apache/manifoldcf/core/lockmanager/LocalLock.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: manifoldcf/branches/CONNECTORS-13/framework/core/src/main/java/org/apache/manifoldcf/core/lockmanager/LocalLock.java
------------------------------------------------------------------------------
    svn:keywords = Id

Added: manifoldcf/branches/CONNECTORS-13/framework/core/src/main/java/org/apache/manifoldcf/core/lockmanager/LocalLockPool.java
URL: http://svn.apache.org/viewvc/manifoldcf/branches/CONNECTORS-13/framework/core/src/main/java/org/apache/manifoldcf/core/lockmanager/LocalLockPool.java?rev=1539701&view=auto
==============================================================================
--- manifoldcf/branches/CONNECTORS-13/framework/core/src/main/java/org/apache/manifoldcf/core/lockmanager/LocalLockPool.java (added)
+++ manifoldcf/branches/CONNECTORS-13/framework/core/src/main/java/org/apache/manifoldcf/core/lockmanager/LocalLockPool.java Thu Nov  7 16:29:47 2013
@@ -0,0 +1,57 @@
+/* $Id$ */
+
+/**
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+package org.apache.manifoldcf.core.lockmanager;
+
+import java.util.*;
+import java.io.*;
+
+/** Pool of local locks, designed to gate access within a single thread.
+* Since it is within a single thread, synchronization is not necessary.
+*/
+public class LocalLockPool
+{
+  public static final String _rcsid = "@(#)$Id$";
+
+  protected final Map<String,LocalLock> localLocks = new HashMap<String,LocalLock>();
+  
+  public LocalLockPool()
+  {
+  }
+  
+  public LocalLock getLocalLock(String lockKey)
+  {
+    LocalLock ll = localLocks.get(lockKey);
+    if (ll == null)
+    {
+      ll = new LocalLock();
+      localLocks.put(lockKey,ll);
+    }
+    return ll;
+  }
+
+  public void releaseLocalLock(String lockKey)
+  {
+    localLocks.remove(lockKey);
+  }
+
+  public Set<String> keySet()
+  {
+    return localLocks.keySet();
+  }
+}

Propchange: manifoldcf/branches/CONNECTORS-13/framework/core/src/main/java/org/apache/manifoldcf/core/lockmanager/LocalLockPool.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: manifoldcf/branches/CONNECTORS-13/framework/core/src/main/java/org/apache/manifoldcf/core/lockmanager/LocalLockPool.java
------------------------------------------------------------------------------
    svn:keywords = Id



Mime
View raw message