You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@manifoldcf.apache.org by kw...@apache.org on 2013/11/06 16:26:32 UTC
svn commit: r1539362 - in /manifoldcf/branches/CONNECTORS-13:
connectors/solr/pom.xml framework/build.xml framework/core/pom.xml
framework/core/src/main/java/org/apache/manifoldcf/core/lockmanager/ZookeeperLockManager.java
pom.xml
Author: kwright
Date: Wed Nov 6 15:26:32 2013
New Revision: 1539362
URL: http://svn.apache.org/r1539362
Log:
Add zookeeper to the build infrastructure.
Added:
manifoldcf/branches/CONNECTORS-13/framework/core/src/main/java/org/apache/manifoldcf/core/lockmanager/ZookeeperLockManager.java
- copied, changed from r1539323, manifoldcf/branches/CONNECTORS-13/framework/core/src/main/java/org/apache/manifoldcf/core/lockmanager/LockManager.java
Modified:
manifoldcf/branches/CONNECTORS-13/connectors/solr/pom.xml
manifoldcf/branches/CONNECTORS-13/framework/build.xml
manifoldcf/branches/CONNECTORS-13/framework/core/pom.xml
manifoldcf/branches/CONNECTORS-13/pom.xml
Modified: manifoldcf/branches/CONNECTORS-13/connectors/solr/pom.xml
URL: http://svn.apache.org/viewvc/manifoldcf/branches/CONNECTORS-13/connectors/solr/pom.xml?rev=1539362&r1=1539361&r2=1539362&view=diff
==============================================================================
--- manifoldcf/branches/CONNECTORS-13/connectors/solr/pom.xml (original)
+++ manifoldcf/branches/CONNECTORS-13/connectors/solr/pom.xml Wed Nov 6 15:26:32 2013
@@ -92,6 +92,11 @@
<version>${solr.version}</version>
</dependency>
<dependency>
+ <groupId>org.apache.zookeeper</groupId>
+ <artifactId>zookeeper</artifactId>
+ <version>${zookeeper.version}</version>
+ </dependency>
+ <dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>${httpcomponent.httpclient.version}</version>
Modified: manifoldcf/branches/CONNECTORS-13/framework/build.xml
URL: http://svn.apache.org/viewvc/manifoldcf/branches/CONNECTORS-13/framework/build.xml?rev=1539362&r1=1539361&r2=1539362&view=diff
==============================================================================
--- manifoldcf/branches/CONNECTORS-13/framework/build.xml (original)
+++ manifoldcf/branches/CONNECTORS-13/framework/build.xml Wed Nov 6 15:26:32 2013
@@ -32,6 +32,7 @@
<path id="framework-classpath">
<fileset dir="../lib">
+ <include name="zookeeper*.jar"/>
<include name="json*.jar"/>
<include name="commons-codec*.jar"/>
<include name="commons-collections*.jar"/>
@@ -308,6 +309,7 @@
<mkdir dir="build/webapp/authority-service/WEB-INF/lib"/>
<copy todir="build/webapp/authority-service/WEB-INF/lib">
<fileset dir="../lib">
+ <include name="zookeeper*.jar"/>
<include name="json*.jar"/>
<include name="commons-codec*.jar"/>
<include name="commons-collections*.jar"/>
@@ -346,6 +348,7 @@
<mkdir dir="build/webapp/authority-service-proprietary/WEB-INF/lib"/>
<copy todir="build/webapp/authority-service-proprietary/WEB-INF/lib">
<fileset dir="../lib">
+ <include name="zookeeper*.jar"/>
<include name="json*.jar"/>
<include name="commons-codec*.jar"/>
<include name="commons-collections*.jar"/>
@@ -389,6 +392,7 @@
<mkdir dir="build/webapp/api-service/WEB-INF/lib"/>
<copy todir="build/webapp/api-service/WEB-INF/lib">
<fileset dir="../lib">
+ <include name="zookeeper*.jar"/>
<include name="json*.jar"/>
<include name="commons-codec*.jar"/>
<include name="commons-collections*.jar"/>
@@ -428,6 +432,7 @@
<mkdir dir="build/webapp/api-service-proprietary/WEB-INF/lib"/>
<copy todir="build/webapp/api-service-proprietary/WEB-INF/lib">
<fileset dir="../lib">
+ <include name="zookeeper*.jar"/>
<include name="json*.jar"/>
<include name="commons-codec*.jar"/>
<include name="commons-collections*.jar"/>
@@ -473,6 +478,7 @@
<copy todir="build/webapp/crawler-ui/WEB-INF/lib">
<fileset dir="../lib">
<include name="jstl*.jar"/>
+ <include name="zookeeper*.jar"/>
<include name="json*.jar"/>
<include name="commons-codec*.jar"/>
<include name="commons-collections*.jar"/>
@@ -520,6 +526,7 @@
<copy todir="build/webapp/crawler-ui-proprietary/WEB-INF/lib">
<fileset dir="../lib">
<include name="jstl*.jar"/>
+ <include name="zookeeper*.jar"/>
<include name="json*.jar"/>
<include name="commons-codec*.jar"/>
<include name="commons-collections*.jar"/>
@@ -574,6 +581,7 @@
<copy todir="build/webapp/combined-service/WEB-INF/lib">
<fileset dir="../lib">
<include name="jstl*.jar"/>
+ <include name="zookeeper*.jar"/>
<include name="json*.jar"/>
<include name="commons-codec*.jar"/>
<include name="commons-collections*.jar"/>
@@ -623,6 +631,7 @@
<copy todir="build/webapp/combined-service-proprietary/WEB-INF/lib">
<fileset dir="../lib">
<include name="jstl*.jar"/>
+ <include name="zookeeper*.jar"/>
<include name="json*.jar"/>
<include name="commons-codec*.jar"/>
<include name="commons-collections*.jar"/>
@@ -740,6 +749,7 @@
<mkdir dir="dist/multiprocess-example/processes/lib"/>
<copy todir="dist/multiprocess-example/processes/lib">
<fileset dir="../lib">
+ <include name="zookeeper*.jar"/>
<include name="json*.jar"/>
<include name="commons-codec*.jar"/>
<include name="commons-collections*.jar"/>
@@ -780,6 +790,7 @@
<mkdir dir="dist/multiprocess-example-proprietary/processes/lib"/>
<copy todir="dist/multiprocess-example-proprietary/processes/lib">
<fileset dir="../lib">
+ <include name="zookeeper*.jar"/>
<include name="json*.jar"/>
<include name="commons-codec*.jar"/>
<include name="commons-collections*.jar"/>
@@ -836,6 +847,7 @@
<mkdir dir="dist/multiprocess-example/lib"/>
<copy todir="dist/multiprocess-example/lib">
<fileset dir="../lib">
+ <include name="zookeeper*.jar"/>
<include name="json*.jar"/>
<include name="commons-logging*.jar"/>
<include name="log4j*.jar"/>
@@ -876,6 +888,7 @@
<mkdir dir="dist/multiprocess-example-proprietary/lib"/>
<copy todir="dist/multiprocess-example-proprietary/lib">
<fileset dir="../lib">
+ <include name="zookeeper*.jar"/>
<include name="json*.jar"/>
<include name="commons-logging*.jar"/>
<include name="log4j*.jar"/>
@@ -932,6 +945,7 @@
<mkdir dir="dist/example/lib"/>
<copy todir="dist/example/lib">
<fileset dir="../lib">
+ <include name="zookeeper*.jar"/>
<include name="json*.jar"/>
<include name="commons-codec*.jar"/>
<include name="commons-collections*.jar"/>
@@ -1059,6 +1073,7 @@
<mkdir dir="dist/example-proprietary/lib"/>
<copy todir="dist/example-proprietary/lib">
<fileset dir="../lib">
+ <include name="zookeeper*.jar"/>
<include name="json*.jar"/>
<include name="commons-codec*.jar"/>
<include name="commons-collections*.jar"/>
Modified: manifoldcf/branches/CONNECTORS-13/framework/core/pom.xml
URL: http://svn.apache.org/viewvc/manifoldcf/branches/CONNECTORS-13/framework/core/pom.xml?rev=1539362&r1=1539361&r2=1539362&view=diff
==============================================================================
--- manifoldcf/branches/CONNECTORS-13/framework/core/pom.xml (original)
+++ manifoldcf/branches/CONNECTORS-13/framework/core/pom.xml Wed Nov 6 15:26:32 2013
@@ -87,5 +87,10 @@
<artifactId>velocity</artifactId>
<version>${velocity.version}</version>
</dependency>
+ <dependency>
+ <groupId>org.apache.zookeeper</groupId>
+ <artifactId>zookeeper</artifactId>
+ <version>${zookeeper.version}</version>
+ </dependency>
</dependencies>
</project>
Copied: manifoldcf/branches/CONNECTORS-13/framework/core/src/main/java/org/apache/manifoldcf/core/lockmanager/ZookeeperLockManager.java (from r1539323, 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/ZookeeperLockManager.java?p2=manifoldcf/branches/CONNECTORS-13/framework/core/src/main/java/org/apache/manifoldcf/core/lockmanager/ZookeeperLockManager.java&p1=manifoldcf/branches/CONNECTORS-13/framework/core/src/main/java/org/apache/manifoldcf/core/lockmanager/LockManager.java&r1=1539323&r2=1539362&rev=1539362&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/ZookeeperLockManager.java Wed Nov 6 15:26:32 2013
@@ -21,206 +21,85 @@ package org.apache.manifoldcf.core.lockm
import org.apache.manifoldcf.core.interfaces.*;
import org.apache.manifoldcf.core.system.Logging;
import org.apache.manifoldcf.core.system.ManifoldCF;
+
+import org.apache.zookeeper.*;
+
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.
+/** The lock manager manages locks across all threads and JVMs and cluster members, using Zookeeper.
+* There should be no more than ONE instance of this class per thread!!! The factory should enforce this.
+* Note well: This class extends LockManager because zookeeper implementations of some features (e.g.
+* critical sections) do not need to be overridden.
*/
-public class LockManager implements ILockManager
+public class ZookeeperLockManager extends LockManager 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 HashMap localLocks = new HashMap();
- protected static LockPool myLocks = new LockPool();
-
- // These are for critical sections (which do not cross JVM boundaries)
- protected HashMap localSections = new HashMap();
- protected static LockPool mySections = new LockPool();
-
- // This is the directory used for cross-JVM synchronization, or null if off
- protected File synchDirectory = null;
-
- public LockManager()
+ /** Constructor */
+ public ZookeeperLockManager()
throws ManifoldCFException
{
- 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);
- }
+ // MHL
}
-
- /** 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
{
- // Local implementation vectors through to system property file, which is shared in this case
- return ManifoldCF.getConfiguration();
+ // MHL
+ return null;
}
/** Raise a flag. Use this method to assert a condition, or send a global signal. The flag will be reset when the
* 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)
- {
- 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);
- }
- }
+ // MHL
}
/** 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
- {
- String resourceName = getFlagResourceName(flagName);
- File f = new File(makeFilePath(resourceName),ManifoldCF.safeFileName(resourceName));
- f.delete();
- }
+ // MHL
}
/** Check the condition of a specified flag.
*@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
- {
- String resourceName = getFlagResourceName(flagName);
- File f = new File(makeFilePath(resourceName),ManifoldCF.safeFileName(resourceName));
- return f.exists();
- }
+ // MHL
+ return false;
}
- /** 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
- {
- 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);
- }
- }
+ // MHL
+ return null;
}
/** Write data to a shared data resource. Use this method to write a body of data into a shared resource.
@@ -228,1753 +107,181 @@ 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
- {
- 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);
- }
- }
+ // MHL
}
- /** Wait for a time before retrying a lock.
+ /** Enter a write locked code area (i.e., block out both readers and other writers).
+ * Write locks permit only ONE thread to be in the named section, across JVM's
+ * as well. In order to guarantee this, the current thread may wait until all other
+ * threads have left the section.
+ *@param lockKey is the name of the lock.
*/
- public void timedWait(int time)
+ @Override
+ public void enterWriteLock(String lockKey)
throws ManifoldCFException
{
-
- if (Logging.lock.isDebugEnabled())
- {
- Logging.lock.debug("Waiting for time "+Integer.toString(time));
- }
-
- try
- {
- ManifoldCF.sleep(time);
- }
- catch (InterruptedException e)
- {
- throw new ManifoldCFException("Interrupted",e,ManifoldCFException.INTERRUPTED);
- }
+ // MHL
}
- /** Enter a non-exclusive write-locked area (blocking out all readers, but letting in other "writers").
- * This kind of lock is designed to be used in conjunction with read locks. It is used typically in
- * a situation where the read lock represents a query and the non-exclusive write lock represents a modification
- * 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).
+ /** Enter a write locked code area (i.e., block out both readers and other writers),
+ * but do not wait if the lock cannot be obtained.
+ * Write locks permit only ONE thread to be in the named section, across JVM's
+ * as well. In order to guarantee this, an exception (LockException) will be
+ * thrown if the lock condition cannot be met immediately.
+ *@param lockKey is the name of the lock.
*/
- public void enterNonExWriteLock(String lockKey)
- throws ManifoldCFException
- {
-
- if (Logging.lock.isDebugEnabled())
- {
- Logging.lock.debug("Entering non-ex write lock '"+lockKey+"'");
- }
-
- LocalLock ll = 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!");
- return;
- }
-
- // Check for illegalities
- if (ll.hasReadLock())
- {
- throw new ManifoldCFException("Illegal lock sequence: NonExWrite lock can't be within read lock",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,synchDirectory);
- try
- {
- lo.enterNonExWriteLock();
- break;
- }
- catch (InterruptedException e)
- {
- throw new ManifoldCFException("Interrupted",e,ManifoldCFException.INTERRUPTED);
- }
- catch (ExpiredObjectException e)
- {
- // Try again to get a valid object
- }
- }
- ll.incrementNonExWriteLocks();
- Logging.lock.debug(" Successfully obtained lock!");
- }
-
- public void enterNonExWriteLockNoWait(String lockKey)
+ @Override
+ public void enterWriteLockNoWait(String lockKey)
throws ManifoldCFException, LockException
{
-
- if (Logging.lock.isDebugEnabled())
- {
- Logging.lock.debug("Entering non-ex write lock no wait '"+lockKey+"'");
- }
-
- LocalLock ll = 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!");
- return;
- }
-
- // Check for illegalities
- if (ll.hasReadLock())
- {
- throw new ManifoldCFException("Illegal lock sequence: NonExWrite lock can't be within read lock",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,synchDirectory);
- try
- {
- synchronized (lo)
- {
- lo.enterNonExWriteLockNoWait();
- break;
- }
- }
- catch (LocalLockException e)
- {
-
- if (Logging.lock.isDebugEnabled())
- {
- Logging.lock.debug(" Could not non-ex write lock '"+lockKey+"', lock exception");
- }
-
- // Throw LockException instead
- throw new LockException(e.getMessage());
- }
- catch (InterruptedException e)
- {
- throw new ManifoldCFException("Interrupted",e,ManifoldCFException.INTERRUPTED);
- }
- catch (ExpiredObjectException e)
- {
- // Try again to get a valid object
- }
- }
- ll.incrementNonExWriteLocks();
- Logging.lock.debug(" Successfully obtained lock!");
+ // MHL
}
- /** Leave a non-exclusive write lock.
+ /** Leave a write locked code area. Use this method to exit a write-locked section. The lockKey
+ * parameter must correspond to the key used for the enter method.
+ * @param lockKey is the name of the lock.
*/
- public void leaveNonExWriteLock(String lockKey)
+ @Override
+ public void leaveWriteLock(String lockKey)
throws ManifoldCFException
{
-
- if (Logging.lock.isDebugEnabled())
- {
- Logging.lock.debug("Leaving non-ex write lock '"+lockKey+"'");
- }
-
- LocalLock ll = getLocalLock(lockKey);
-
- 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 = myLocks.getObject(lockKey,synchDirectory);
- 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 to get a valid object
- }
- }
-
- releaseLocalLock(lockKey);
- }
+ // MHL
}
- /** Enter a write locked area (i.e., block out both readers and other writers)
- * NOTE: Can't enter until all readers have left.
+ /** Enter a non-exclusive write-locked area (blocking out all readers, but letting in other "writers").
+ * This kind of lock is designed to be used in conjunction with read locks. It is used typically in
+ * a situation where the read lock represents a query and the non-exclusive write lock represents a modification
+ * 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).
+ * This method works across JVMs, and may wait if the required lock cannot be immediately obtained.
+ *@param lockKey is the name of the lock.
*/
- public void enterWriteLock(String lockKey)
+ @Override
+ public void enterNonExWriteLock(String lockKey)
throws ManifoldCFException
{
-
- if (Logging.lock.isDebugEnabled())
- {
- Logging.lock.debug("Entering write lock '"+lockKey+"'");
- }
-
- LocalLock ll = getLocalLock(lockKey);
-
-
- // See if we already own the write lock for the object
- if (ll.hasWriteLock())
- {
- ll.incrementWriteLocks();
- Logging.lock.debug(" Successfully obtained lock!");
- 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 = myLocks.getObject(lockKey,synchDirectory);
- try
- {
- lo.enterWriteLock();
- break;
- }
- catch (InterruptedException e)
- {
- throw new ManifoldCFException("Interrupted",e,ManifoldCFException.INTERRUPTED);
- }
- catch (ExpiredObjectException e)
- {
- // Try again
- }
- }
- ll.incrementWriteLocks();
- Logging.lock.debug(" Successfully obtained lock!");
+ // MHL
}
- public void enterWriteLockNoWait(String lockKey)
+ /** Enter a non-exclusive write-locked area (blocking out all readers, but letting in other "writers").
+ * This kind of lock is designed to be used in conjunction with read locks. It is used typically in
+ * a situation where the read lock represents a query and the non-exclusive write lock represents a modification
+ * 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).
+ * This method works across JVMs, and will throw LockException if the lock condition cannot be immediately met.
+ *@param lockKey is the name of the lock.
+ */
+ @Override
+ public void enterNonExWriteLockNoWait(String lockKey)
throws ManifoldCFException, LockException
{
-
- if (Logging.lock.isDebugEnabled())
- {
- Logging.lock.debug("Entering write lock no wait '"+lockKey+"'");
- }
-
- LocalLock ll = getLocalLock(lockKey);
-
-
- // See if we already own the write lock for the object
- if (ll.hasWriteLock())
- {
- ll.incrementWriteLocks();
- Logging.lock.debug(" Successfully obtained lock!");
- 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 = myLocks.getObject(lockKey,synchDirectory);
- try
- {
- synchronized (lo)
- {
- lo.enterWriteLockNoWait();
- break;
- }
- }
- catch (LocalLockException e)
- {
-
- if (Logging.lock.isDebugEnabled())
- {
- Logging.lock.debug(" Could not write lock '"+lockKey+"', lock exception");
- }
-
- throw new LockException(e.getMessage());
- }
- catch (InterruptedException e)
- {
- throw new ManifoldCFException("Interrupted",e,ManifoldCFException.INTERRUPTED);
- }
- catch (ExpiredObjectException e)
- {
- // Try again
- }
- }
-
- ll.incrementWriteLocks();
- Logging.lock.debug(" Successfully obtained lock!");
+ // MHL
}
- public void leaveWriteLock(String lockKey)
+ /** Leave a non-exclusive write locked code area. Use this method to exit a non-ex-write-locked section.
+ * The lockKey
+ * parameter must correspond to the key used for the enter method.
+ *@param lockKey is the name of the lock.
+ */
+ @Override
+ public void leaveNonExWriteLock(String lockKey)
throws ManifoldCFException
{
-
- if (Logging.lock.isDebugEnabled())
- {
- Logging.lock.debug("Leaving write lock '"+lockKey+"'");
- }
-
- LocalLock ll = getLocalLock(lockKey);
-
- ll.decrementWriteLocks();
- if (!ll.hasWriteLock())
- {
- while (true)
- {
- LockObject lo = myLocks.getObject(lockKey,synchDirectory);
- 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
- }
- }
-
- releaseLocalLock(lockKey);
- }
+ // MHL
}
- /** Enter a read-only locked area (i.e., block ONLY if there's a writer)
+ /** Enter a read-only locked area (i.e., block ONLY if there's a writer). This kind of lock
+ * permits multiple threads inside the same code area, but only if there is no "writer" in the
+ * same section at the same time.
+ * This method works across JVMs, and may wait if the required lock cannot be immediately obtained.
+ *@param lockKey is the name of the lock.
*/
+ @Override
public void enterReadLock(String lockKey)
throws ManifoldCFException
{
-
- if (Logging.lock.isDebugEnabled())
- {
- Logging.lock.debug("Entering read lock '"+lockKey+"'");
- }
-
-
- LocalLock ll = 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!");
- return;
- }
-
- // We don't own a local read lock. Get one.
- while (true)
- {
- LockObject lo = myLocks.getObject(lockKey,synchDirectory);
- try
- {
- lo.enterReadLock();
- break;
- }
- catch (InterruptedException e)
- {
- throw new ManifoldCFException("Interrupted",e,ManifoldCFException.INTERRUPTED);
- }
- catch (ExpiredObjectException e)
- {
- // Try again
- }
- }
- ll.incrementReadLocks();
- Logging.lock.debug(" Successfully obtained lock!");
+ // MHL
}
+ /** Enter a read-only locked area (i.e., block ONLY if there's a writer). This kind of lock
+ * permits multiple threads inside the same code area, but only if there is no "writer" in the
+ * same section at the same time.
+ * This method works across JVMs, and will throw LockException if the required lock cannot be immediately met.
+ *@param lockKey is the name of the lock.
+ */
+ @Override
public void enterReadLockNoWait(String lockKey)
throws ManifoldCFException, LockException
{
-
- if (Logging.lock.isDebugEnabled())
- {
- Logging.lock.debug("Entering read lock no wait '"+lockKey+"'");
- }
-
- LocalLock ll = 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!");
- return;
- }
-
- // We don't own a local read lock. Get one.
- while (true)
- {
- LockObject lo = myLocks.getObject(lockKey,synchDirectory);
- try
- {
- synchronized (lo)
- {
- lo.enterReadLockNoWait();
- break;
- }
- }
- catch (LocalLockException e)
- {
-
- if (Logging.lock.isDebugEnabled())
- {
- Logging.lock.debug(" Could not read lock '"+lockKey+"', lock exception");
- }
-
- throw new LockException(e.getMessage());
- }
- catch (InterruptedException e)
- {
- throw new ManifoldCFException("Interrupted",e,ManifoldCFException.INTERRUPTED);
- }
- catch (ExpiredObjectException e)
- {
- // Try again
- }
- }
-
- ll.incrementReadLocks();
- Logging.lock.debug(" Successfully obtained lock!");
+ // MHL
}
+ /** Leave a read-locked code area. Use this method to exit a read-locked section. The lockKey
+ * parameter must correspond to the key used for the enter method.
+ *@param lockKey is the name of the lock.
+ */
+ @Override
public void leaveReadLock(String lockKey)
throws ManifoldCFException
{
-
- if (Logging.lock.isDebugEnabled())
- {
- Logging.lock.debug("Leaving read lock '"+lockKey+"'");
- }
-
- LocalLock ll = getLocalLock(lockKey);
-
- ll.decrementReadLocks();
- if (!(ll.hasReadLock() || ll.hasNonExWriteLock() || ll.hasWriteLock()))
- {
- while (true)
- {
- LockObject lo = myLocks.getObject(lockKey,synchDirectory);
- 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
- }
- }
- releaseLocalLock(lockKey);
- }
- }
-
- public void clearLocks()
- throws ManifoldCFException
- {
-
- if (Logging.lock.isDebugEnabled())
- {
- Logging.lock.debug("Clearing all locks");
- }
-
-
- Iterator e = localLocks.keySet().iterator();
- while (e.hasNext())
- {
- String keyValue = (String)e.next();
- LocalLock ll = (LocalLock)localLocks.get(keyValue);
- while (ll.hasWriteLock())
- leaveWriteLock(keyValue);
- while (ll.hasNonExWriteLock())
- leaveNonExWriteLock(keyValue);
- while (ll.hasReadLock())
- leaveReadLock(keyValue);
- }
+ // MHL
}
- /** Enter multiple locks
+ /** Enter multiple locks simultaneously. Use this method if a series or set of locks needs to be
+ * thrown for an operation to take place. This operation will avoid deadlock if all the locks are
+ * thrown at the start of the area using this method.
+ * This method works cross-JVM, and will wait if the required locks are not available.
+ *@param readLocks is an array of read lock names, or null if there are no read locks desired.
+ *@param nonExWriteLocks is an array of non-ex write lock names, or null if none desired.
+ *@param writeLocks is an array of write lock names, or null if there are none desired.
*/
+ @Override
public void enterLocks(String[] readLocks, String[] nonExWriteLocks, String[] writeLocks)
throws ManifoldCFException
{
-
- if (Logging.lock.isDebugEnabled())
- {
- Logging.lock.debug("Entering multiple locks:");
- int i;
- if (readLocks != null)
- {
- i = 0;
- while (i < readLocks.length)
- {
- Logging.lock.debug(" Read lock '"+readLocks[i++]+"'");
- }
- }
- if (nonExWriteLocks != null)
- {
- i = 0;
- while (i < nonExWriteLocks.length)
- {
- Logging.lock.debug(" Non-ex write lock '"+nonExWriteLocks[i++]+"'");
- }
- }
- if (writeLocks != null)
- {
- i = 0;
- while (i < writeLocks.length)
- {
- Logging.lock.debug(" Write lock '"+writeLocks[i++]+"'");
- }
- }
- }
-
-
- // Sort the locks. This improves the chances of making it through the locking process without
- // contention!
- LockDescription lds[] = getSortedUniqueLocks(readLocks,nonExWriteLocks,writeLocks);
- 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 = 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);
- }
-
- // 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 = myLocks.getObject(lockKey,synchDirectory);
- try
- {
- lo.enterWriteLock();
- break;
- }
- catch (ExpiredObjectException e)
- {
- // Try again
- }
- }
- }
- ll.incrementWriteLocks();
- break;
- case TYPE_WRITENONEX:
- ll = 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);
- }
-
- // 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 = myLocks.getObject(lockKey,synchDirectory);
- try
- {
- lo.enterNonExWriteLock();
- break;
- }
- catch (ExpiredObjectException e)
- {
- // Try again
- }
- }
- }
- ll.incrementNonExWriteLocks();
- break;
- case TYPE_READ:
- ll = 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,synchDirectory);
- try
- {
- lo.enterReadLock();
- break;
- }
- catch (ExpiredObjectException e)
- {
- // Try again
- }
- }
- }
- ll.incrementReadLocks();
- break;
- }
- locksProcessed++;
- }
- // Got all; we are done!
- Logging.lock.debug(" Successfully obtained multiple locks!");
- 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:
- leaveReadLock(lockKey);
- break;
- case TYPE_WRITENONEX:
- leaveNonExWriteLock(lockKey);
- break;
- case TYPE_WRITE:
- leaveWriteLock(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;
- }
+ // MHL
}
+ /** Enter multiple locks simultaneously. Use this method if a series or set of locks needs to be
+ * thrown for an operation to take place. This operation will avoid deadlock if all the locks are
+ * thrown at the start of the area using this method.
+ * This method works cross-JVM, and will throw LockException if the required locks are not available.
+ *@param readLocks is an array of read lock names, or null if there are no read locks desired.
+ *@param nonExWriteLocks is an array of non-ex write lock names, or null if none desired.
+ *@param writeLocks is an array of write lock names, or null if there are none desired.
+ */
+ @Override
public void enterLocksNoWait(String[] readLocks, String[] nonExWriteLocks, String[] writeLocks)
throws ManifoldCFException, LockException
{
-
- if (Logging.lock.isDebugEnabled())
- {
- Logging.lock.debug("Entering multiple locks no wait:");
- int i;
- if (readLocks != null)
- {
- i = 0;
- while (i < readLocks.length)
- {
- Logging.lock.debug(" Read lock '"+readLocks[i++]+"'");
- }
- }
- if (nonExWriteLocks != null)
- {
- i = 0;
- while (i < nonExWriteLocks.length)
- {
- Logging.lock.debug(" Non-ex write lock '"+nonExWriteLocks[i++]+"'");
- }
- }
- if (writeLocks != null)
- {
- i = 0;
- while (i < writeLocks.length)
- {
- Logging.lock.debug(" Write lock '"+writeLocks[i++]+"'");
- }
- }
- }
-
-
- // Sort the locks. This improves the chances of making it through the locking process without
- // contention!
- LockDescription lds[] = getSortedUniqueLocks(readLocks,nonExWriteLocks,writeLocks);
- 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 = 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);
- }
-
- // 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 = myLocks.getObject(lockKey,synchDirectory);
- synchronized (lo)
- {
- try
- {
- lo.enterWriteLockNoWait();
- break;
- }
- catch (ExpiredObjectException e)
- {
- // Try again
- }
- }
- }
- }
- ll.incrementWriteLocks();
- break;
- case TYPE_WRITENONEX:
- ll = 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);
- }
-
- // 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 = myLocks.getObject(lockKey,synchDirectory);
- synchronized (lo)
- {
- try
- {
- lo.enterNonExWriteLockNoWait();
- break;
- }
- catch (ExpiredObjectException e)
- {
- // Try again
- }
- }
- }
- }
- ll.incrementNonExWriteLocks();
- break;
- case TYPE_READ:
- ll = 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,synchDirectory);
- synchronized (lo)
- {
- try
- {
- lo.enterReadLockNoWait();
- break;
- }
- catch (ExpiredObjectException e)
- {
- // Try again
- }
- }
- }
- }
- ll.incrementReadLocks();
- break;
- }
- locksProcessed++;
- }
- // Got all; we are done!
- Logging.lock.debug(" Successfully obtained multiple locks!");
- 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:
- leaveReadLock(lockKey);
- break;
- case TYPE_WRITENONEX:
- leaveNonExWriteLock(lockKey);
- break;
- case TYPE_WRITE:
- leaveWriteLock(lockKey);
- break;
- }
- }
- catch (ManifoldCFException e)
- {
- ae = e;
- }
- }
-
- if (ae != null)
- {
- throw ae;
- }
- if (ex instanceof ManifoldCFException)
- {
- throw (ManifoldCFException)ex;
- }
- if (ex instanceof LockException || ex instanceof LocalLockException)
- {
- Logging.lock.debug(" Couldn't get lock; throwing LockException");
- // It's either LockException or LocalLockException
- throw new LockException(ex.getMessage());
- }
- if (ex instanceof InterruptedException)
- {
- throw new ManifoldCFException("Interrupted",ex,ManifoldCFException.INTERRUPTED);
- }
- if (!(ex instanceof Error))
- {
- throw new Error("Unexpected exception",ex);
- }
- throw (Error)ex;
-
- }
-
- }
-
- /** Leave multiple locks
- */
- public void leaveLocks(String[] readLocks, String[] writeNonExLocks, String[] writeLocks)
- throws ManifoldCFException
- {
- LockDescription[] lds = getSortedUniqueLocks(readLocks,writeNonExLocks,writeLocks);
- // 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:
- leaveReadLock(lockKey);
- break;
- case TYPE_WRITENONEX:
- leaveNonExWriteLock(lockKey);
- break;
- case TYPE_WRITE:
- leaveWriteLock(lockKey);
- break;
- }
- }
- catch (ManifoldCFException e)
- {
- ae = e;
- }
- }
-
- if (ae != null)
- {
- throw ae;
- }
- }
-
- /** Enter a named, read 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 enter. Only one thread can be in any given named
- * section at a time.
- */
- public 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,null);
- try
- {
- lo.enterReadLock();
- break;
- }
- catch (InterruptedException e)
- {
- throw new ManifoldCFException("Interrupted",e,ManifoldCFException.INTERRUPTED);
- }
- catch (ExpiredObjectException e)
- {
- // Try again
- }
- }
- ll.incrementReadLocks();
- }
-
- /** Leave a named, read 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 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,null);
- 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);
- }
- }
-
- /** Enter 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 enter. Only one thread can be in any given named
- * section at a time.
- */
- public 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,null);
- try
- {
- lo.enterNonExWriteLock();
- break;
- }
- catch (InterruptedException e)
- {
- throw new ManifoldCFException("Interrupted",e,ManifoldCFException.INTERRUPTED);
- }
- catch (ExpiredObjectException e)
- {
- // Try again
- }
- }
- ll.incrementNonExWriteLocks();
- }
-
- /** 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)
- 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,null);
- 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);
- }
+ // MHL
}
- /** 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.
+ /** Leave multiple locks. Use this method to leave a section started with enterLocks() or
+ * enterLocksNoWait(). The parameters must correspond to those passed to the enter method.
+ *@param readLocks is an array of read lock names, or null if there are no read locks desired.
+ *@param nonExWriteLocks is an array of non-ex write lock names, or null if none desired.
+ *@param writeLocks is an array of write lock names, or null if there are none desired.
*/
- public void enterWriteCriticalSection(String sectionKey)
+ @Override
+ public void leaveLocks(String[] readLocks, String[] nonExWriteLocks, String[] writeLocks)
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,null);
- try
- {
- lo.enterWriteLock();
- break;
- }
- catch (InterruptedException e)
- {
- throw new ManifoldCFException("Interrupted",e,ManifoldCFException.INTERRUPTED);
- }
- catch (ExpiredObjectException e)
- {
- // Try again
- }
- }
- ll.incrementWriteLocks();
-
- }
-
- /** 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)
- throws ManifoldCFException
- {
- LocalLock ll = getLocalSection(sectionKey);
-
- ll.decrementWriteLocks();
- if (!ll.hasWriteLock())
- {
- while (true)
- {
- LockObject lo = mySections.getObject(sectionKey,null);
- 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);
- }
+ // MHL
}
- /** Enter multiple critical sections simultaneously.
- *@param readSectionKeys is an array of read section descriptors, or null if there are no read sections desired.
- *@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.
+ /** Clear all outstanding locks in the system.
+ * This is a very dangerous method to use (obviously)...
*/
- public 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,null);
- 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,null);
- 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,null);
- 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;
- }
- }
-
- /** Leave multiple critical sections simultaneously.
- *@param readSectionKeys is an array of read section descriptors, or null if there are no read sections desired.
- *@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 void clearLocks()
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);
- }
-
- /** Process inbound locks into a sorted vector of most-restrictive unique locks
- */
- protected LockDescription[] getSortedUniqueLocks(String[] readLocks, String[] writeNonExLocks,
- String[] writeLocks)
- {
- // First build a unique hash of lock descriptions
- HashMap ht = new HashMap();
- int i;
- if (readLocks != null)
- {
- i = 0;
- while (i < readLocks.length)
- {
- String key = readLocks[i++];
- LockDescription ld = (LockDescription)ht.get(key);
- if (ld == null)
- {
- ld = new LockDescription(TYPE_READ,key);
- ht.put(key,ld);
- }
- else
- ld.set(TYPE_READ);
- }
- }
- if (writeNonExLocks != null)
- {
- i = 0;
- while (i < writeNonExLocks.length)
- {
- String key = writeNonExLocks[i++];
- LockDescription ld = (LockDescription)ht.get(key);
- if (ld == null)
- {
- ld = new LockDescription(TYPE_WRITENONEX,key);
- ht.put(key,ld);
- }
- else
- ld.set(TYPE_WRITENONEX);
- }
- }
- if (writeLocks != null)
- {
- i = 0;
- while (i < writeLocks.length)
- {
- String key = writeLocks[i++];
- LockDescription ld = (LockDescription)ht.get(key);
- if (ld == null)
- {
- ld = new LockDescription(TYPE_WRITE,key);
- ht.put(key,ld);
- }
- else
- ld.set(TYPE_WRITE);
- }
- }
-
- // Now, sort by key name
- LockDescription[] rval = new LockDescription[ht.size()];
- String[] sortarray = new String[ht.size()];
- i = 0;
- Iterator iter = ht.keySet().iterator();
- while (iter.hasNext())
- {
- String key = (String)iter.next();
- sortarray[i++] = key;
- }
- java.util.Arrays.sort(sortarray);
- i = 0;
- while (i < sortarray.length)
- {
- rval[i] = (LockDescription)ht.get(sortarray[i]);
- i++;
- }
- 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 int lockType;
- protected String lockKey;
-
- public LockDescription(int lockType, String lockKey)
- {
- this.lockType = lockType;
- this.lockKey = lockKey;
- }
-
- public void set(int lockType)
- {
- if (lockType > this.lockType)
- this.lockType = lockType;
- }
-
- public int getType()
- {
- return lockType;
- }
-
- public String getKey()
- {
- return lockKey;
- }
- }
-
- 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;
- }
+ // MHL
}
}
Modified: manifoldcf/branches/CONNECTORS-13/pom.xml
URL: http://svn.apache.org/viewvc/manifoldcf/branches/CONNECTORS-13/pom.xml?rev=1539362&r1=1539361&r2=1539362&view=diff
==============================================================================
--- manifoldcf/branches/CONNECTORS-13/pom.xml (original)
+++ manifoldcf/branches/CONNECTORS-13/pom.xml Wed Nov 6 15:26:32 2013
@@ -66,7 +66,8 @@
<json.version>20090211</json.version>
<velocity.version>1.7</velocity.version>
<slf4j.version>1.6.6</slf4j.version>
- <jaxb.version>2.2.6</jaxb.version>
+ <jaxb.version>2.2.6</jaxb.version>
+ <zookeeper.version>3.4.5</zookeeper.version>
</properties>
<modules>