[jbosscache-commits] JBoss Cache SVN: r6858 - in core/branches/flat/src/main/java/org/jboss/starobrno: lock and 1 other directory.

jbosscache-commits at lists.jboss.org jbosscache-commits at lists.jboss.org
Wed Oct 8 05:30:07 EDT 2008


Author: manik.surtani at jboss.com
Date: 2008-10-08 05:30:07 -0400 (Wed, 08 Oct 2008)
New Revision: 6858

Added:
   core/branches/flat/src/main/java/org/jboss/starobrno/lock/
   core/branches/flat/src/main/java/org/jboss/starobrno/lock/LockManager.java
   core/branches/flat/src/main/java/org/jboss/starobrno/lock/StripedLockManager.java
Log:
Updated lock manager

Added: core/branches/flat/src/main/java/org/jboss/starobrno/lock/LockManager.java
===================================================================
--- core/branches/flat/src/main/java/org/jboss/starobrno/lock/LockManager.java	                        (rev 0)
+++ core/branches/flat/src/main/java/org/jboss/starobrno/lock/LockManager.java	2008-10-08 09:30:07 UTC (rev 6858)
@@ -0,0 +1,136 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2000 - 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.starobrno.lock;
+
+import org.jboss.starobrno.context.InvocationContext;
+
+/**
+ * An interface to deal with all aspects of acquiring and releasing locks for nodes in the cache.
+ *
+ * @author Manik Surtani (<a href="mailto:manik at jboss.org">manik at jboss.org</a>)
+ * @since 2.2.0
+ */
+public interface LockManager
+{
+   /**
+    * Determines the owner to be used when obtaining locks, given an invocation context.  This is typically a {@link org.jboss.cache.transaction.GlobalTransaction} if one
+    * is present in the context, or {@link Thread#currentThread()} if one is not present.
+    *
+    * @param ctx invocation context
+    * @return owner to be used for acquiring locks.
+    */
+   Object getLockOwner(InvocationContext ctx);
+
+   /**
+    * Acquires a lock of type lockType, for a given owner, on a specific Node in the cache, denoted by fqn.  This
+    * method will try for {@link org.jboss.cache.config.Configuration#getLockAcquisitionTimeout()} milliseconds and give up if it is unable to acquire the required lock.
+    *
+    * @param fqn      Fqn to lock
+    * @param lockType type of lock to acquire
+    * @param owner    owner to acquire the lock for
+    * @return true if the lock was acquired, false otherwise.
+    */
+   boolean lock(Object key, Object owner) throws InterruptedException;
+
+   /**
+    * Acquires a lock of type lockType, for a given owner, on a specific Node in the cache, denoted by fqn.  This
+    * method will try for timeout milliseconds and give up if it is unable to acquire the required lock.
+    *
+    * @param fqn      Fqn to lock
+    * @param lockType type of lock to acquire
+    * @param owner    owner to acquire the lock for
+    * @param timeout  maximum length of time to wait for (in millis)
+    * @return true if the lock was acquired, false otherwise.
+    */
+   boolean lock(Object key, Object owner, long timeout) throws InterruptedException;
+
+   /**
+    * Acquires a lock of type lockType, on a specific Node in the cache, denoted by fqn.  This
+    * method will try for a period of time and give up if it is unable to acquire the required lock.  The period of time
+    * is specified in {@link org.jboss.cache.config.Option#getLockAcquisitionTimeout()} and, if this is unset, the default timeout
+    * set in {@link org.jboss.cache.config.Configuration#getLockAcquisitionTimeout()} is used.
+    * <p/>
+    * In addition, any locks acquired are added to the context OR transaction entry using {@link org.jboss.cache.InvocationContext#addLock(Object)}.
+    * <p/>
+    * The owner for the lock is determined by passing the invocation context to {@link #getLockOwner(org.jboss.cache.InvocationContext)}.
+    * <p/>
+    *
+    * @param fqn      Fqn to lock
+    * @param lockType type of lock to acquire
+    * @param ctx      invocation context associated with this invocation
+    * @return true if the lock was acquired, false otherwise.
+    */
+   boolean lockAndRecord(Object key, InvocationContext ctx) throws InterruptedException;
+
+   /**
+    * Releases the lock passed in, held by the specified owner
+    *
+    * @param fqn   Fqn of the node to unlock
+    * @param owner lock owner
+    */
+   void unlock(Object key, Object owner);
+
+   /**
+    * Releases locks present in an invocation context and transaction entry, if one is available.
+    * <p/>
+    * Locks are released in reverse order of which they are acquired and registered.
+    * <p/>
+    * Lock owner is determined by passing the invocation context to {@link #getLockOwner(org.jboss.cache.InvocationContext)}
+    * <p/>
+    *
+    * @param ctx invocation context to inspect
+    */
+   void unlock(InvocationContext ctx);
+
+   /**
+    * Tests whether a given owner owns a lock of lockType on a particular Fqn.
+    *
+    * @param fqn      fqn to test
+    * @param lockType type of lock to test for
+    * @param owner    owner
+    * @return true if the owner does own the specified lock type on the specified node, false otherwise.
+    */
+   boolean ownsLock(Object key, Object owner);
+
+   /**
+    * Returns true if the node is locked (either for reading or writing) by anyone, and false otherwise.
+    *
+    * @param n node to inspect
+    * @return true of locked; false if not.
+    */
+   boolean isLocked(Object key);
+
+   /**
+    * Retrieves the write lock owner, if any, for the current Fqn.
+    *
+    * @param f Fqn to inspect
+    * @return the owner of the lock, or null if not locked.
+    */
+   Object getOwner(Object key);
+
+   /**
+    * Prints lock information for all locks.
+    *
+    * @return lock information
+    */
+   String printLockInfo();
+}

Added: core/branches/flat/src/main/java/org/jboss/starobrno/lock/StripedLockManager.java
===================================================================
--- core/branches/flat/src/main/java/org/jboss/starobrno/lock/StripedLockManager.java	                        (rev 0)
+++ core/branches/flat/src/main/java/org/jboss/starobrno/lock/StripedLockManager.java	2008-10-08 09:30:07 UTC (rev 6858)
@@ -0,0 +1,164 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.starobrno.lock;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.jboss.cache.config.Configuration;
+import org.jboss.cache.factories.annotations.Inject;
+import org.jboss.cache.factories.annotations.Start;
+import org.jboss.cache.invocation.InvocationContextContainer;
+import org.jboss.cache.lock.MVCCLockManager;
+import org.jboss.cache.util.concurrent.locks.LockContainer;
+import org.jboss.cache.util.concurrent.locks.OwnableReentrantLock;
+import org.jboss.cache.util.concurrent.locks.OwnableReentrantLockContainer;
+import org.jboss.cache.util.concurrent.locks.ReentrantLockContainer;
+import org.jboss.starobrno.context.InvocationContext;
+
+import javax.transaction.TransactionManager;
+import java.util.List;
+import java.util.ListIterator;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import java.util.concurrent.locks.Lock;
+
+/**
+ * // TODO: MANIK: Document this
+ *
+ * @author Manik Surtani (<a href="mailto:manik at jboss.org">manik at jboss.org</a>)
+ * @since 3.0
+ */
+public class StripedLockManager implements LockManager
+{
+   protected Configuration configuration;
+   protected long lockAcquisitionTimeout;
+   LockContainer<Object> lockContainer;
+   private TransactionManager transactionManager;
+   private InvocationContextContainer invocationContextContainer;
+   private static final Log log = LogFactory.getLog(MVCCLockManager.class);
+   private static final boolean trace = log.isTraceEnabled();
+
+   @Inject
+   public void injectDependencies(Configuration configuration, TransactionManager transactionManager, InvocationContextContainer invocationContextContainer)
+   {
+      this.configuration = configuration;
+      this.transactionManager = transactionManager;
+      this.invocationContextContainer = invocationContextContainer;
+   }
+
+   @Start
+   public void startLockManager()
+   {
+      this.lockAcquisitionTimeout = configuration.getLockAcquisitionTimeout();
+      lockContainer = transactionManager == null ? new ReentrantLockContainer<Object>(configuration.getConcurrencyLevel()) : new OwnableReentrantLockContainer<Object>(configuration.getConcurrencyLevel(), invocationContextContainer);
+   }
+
+   public Object getLockOwner(InvocationContext ctx)
+   {
+      return ctx.getGlobalTransaction() != null ? ctx.getGlobalTransaction() : Thread.currentThread();
+   }
+
+   public boolean lock(Object key, Object owner) throws InterruptedException
+   {
+      if (trace) log.trace("Attempting to lock " + key);
+      Lock lock = lockContainer.getLock(key);
+      return lock.tryLock(lockAcquisitionTimeout, MILLISECONDS);
+   }
+
+   public boolean lock(Object key, Object owner, long timeoutMillis) throws InterruptedException
+   {
+      if (trace) log.trace("Attempting to lock " + key);
+      Lock lock = lockContainer.getLock(key);
+      return lock.tryLock(timeoutMillis, MILLISECONDS);
+   }
+
+   public boolean lockAndRecord(Object key, InvocationContext ctx) throws InterruptedException
+   {
+      if (trace) log.trace("Attempting to lock " + key);
+      Lock lock = lockContainer.getLock(key);
+      if (lock.tryLock(ctx.getLockAcquisitionTimeout(lockAcquisitionTimeout), MILLISECONDS))
+      {
+         ctx.addKeyLocked(key);
+         return true;
+      }
+
+      // couldn't acquire lock!
+      return false;
+   }
+
+   public void unlock(Object key, Object owner)
+   {
+      if (trace) log.trace("Attempting to unlock " + key);
+      Lock lock = lockContainer.getLock(key);
+      lock.unlock();
+   }
+
+   @SuppressWarnings("unchecked")
+   public void unlock(InvocationContext ctx)
+   {
+      List<Object> locks = ctx.getKeysLocked();
+      if (!locks.isEmpty())
+      {
+         // unlocking needs to be done in reverse order.
+         ListIterator<Object> it = locks.listIterator(locks.size());
+         while (it.hasPrevious())
+         {
+            Object k = it.previous();
+            if (trace) log.trace("Attempting to unlock " + k);
+            lockContainer.getLock(k).unlock();
+         }
+      }
+   }
+
+   public boolean ownsLock(Object key, Object owner)
+   {
+      return lockContainer.ownsLock(key, owner);
+   }
+
+   public boolean isLocked(Object key)
+   {
+      return lockContainer.isLocked(key);
+   }
+
+   public Object getOwner(Object key)
+   {
+      if (lockContainer.isLocked(key))
+      {
+         Lock l = lockContainer.getLock(key);
+
+         if (l instanceof OwnableReentrantLock)
+         {
+            return ((OwnableReentrantLock) l).getOwner();
+         }
+         else
+         {
+            // cannot determine owner.
+            return null;
+         }
+      }
+      else return null;
+   }
+
+   public String printLockInfo()
+   {
+      return lockContainer.toString();
+   }
+}




More information about the jbosscache-commits mailing list