From jbosscache-commits at lists.jboss.org Wed Oct 8 05:30:07 2008 Content-Type: multipart/mixed; boundary="===============3602965195230389912==" MIME-Version: 1.0 From: jbosscache-commits at lists.jboss.org To: jbosscache-commits at lists.jboss.org Subject: [jbosscache-commits] JBoss Cache SVN: r6858 - in core/branches/flat/src/main/java/org/jboss/starobrno: lock and 1 other directory. Date: Wed, 08 Oct 2008 05:30:07 -0400 Message-ID: --===============3602965195230389912== Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Author: manik.surtani(a)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.ja= va core/branches/flat/src/main/java/org/jboss/starobrno/lock/StripedLockMan= ager.java Log: Updated lock manager Added: core/branches/flat/src/main/java/org/jboss/starobrno/lock/LockManage= r.java =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- core/branches/flat/src/main/java/org/jboss/starobrno/lock/LockManager.j= ava (rev 0) +++ core/branches/flat/src/main/java/org/jboss/starobrno/lock/LockManager.j= ava 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 contribut= ors + * 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 (manik(a)jbo= ss.org) + * @since 2.2.0 + */ +public interface LockManager +{ + /** + * Determines the owner to be used when obtaining locks, given an invoc= ation context. This is typically a {@link org.jboss.cache.transaction.Glob= alTransaction} 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 N= ode in the cache, denoted by fqn. This + * method will try for {@link org.jboss.cache.config.Configuration#getL= ockAcquisitionTimeout()} milliseconds and give up if it is unable to acquir= e 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 N= ode 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 Interrupted= Exception; + + /** + * Acquires a lock of type lockType, on a specific Node in the cache, d= enoted 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#getLockAcquisit= ionTimeout()} and, if this is unset, the default timeout + * set in {@link org.jboss.cache.config.Configuration#getLockAcquisitio= nTimeout()} is used. + *

+ * In addition, any locks acquired are added to the context OR transact= ion entry using {@link org.jboss.cache.InvocationContext#addLock(Object)}. + *

+ * The owner for the lock is determined by passing the invocation conte= xt to {@link #getLockOwner(org.jboss.cache.InvocationContext)}. + *

+ * + * @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 Interru= ptedException; + + /** + * 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 entr= y, if one is available. + *

+ * Locks are released in reverse order of which they are acquired and r= egistered. + *

+ * Lock owner is determined by passing the invocation context to {@link= #getLockOwner(org.jboss.cache.InvocationContext)} + *

+ * + * @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 sp= ecified node, false otherwise. + */ + boolean ownsLock(Object key, Object owner); + + /** + * Returns true if the node is locked (either for reading or writing) b= y 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/StripedLoc= kManager.java =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- core/branches/flat/src/main/java/org/jboss/starobrno/lock/StripedLockMa= nager.java (rev 0) +++ core/branches/flat/src/main/java/org/jboss/starobrno/lock/StripedLockMa= nager.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 (manik(a)jbo= ss.org) + * @since 3.0 + */ +public class StripedLockManager implements LockManager +{ + protected Configuration configuration; + protected long lockAcquisitionTimeout; + LockContainer lockContainer; + private TransactionManager transactionManager; + private InvocationContextContainer invocationContextContainer; + private static final Log log =3D LogFactory.getLog(MVCCLockManager.clas= s); + private static final boolean trace =3D log.isTraceEnabled(); + + @Inject + public void injectDependencies(Configuration configuration, Transaction= Manager transactionManager, InvocationContextContainer invocationContextCon= tainer) + { + this.configuration =3D configuration; + this.transactionManager =3D transactionManager; + this.invocationContextContainer =3D invocationContextContainer; + } + + @Start + public void startLockManager() + { + this.lockAcquisitionTimeout =3D configuration.getLockAcquisitionTime= out(); + lockContainer =3D transactionManager =3D=3D null ? new ReentrantLock= Container(configuration.getConcurrencyLevel()) : new OwnableReentra= ntLockContainer(configuration.getConcurrencyLevel(), invocationCont= extContainer); + } + + public Object getLockOwner(InvocationContext ctx) + { + return ctx.getGlobalTransaction() !=3D null ? ctx.getGlobalTransacti= on() : Thread.currentThread(); + } + + public boolean lock(Object key, Object owner) throws InterruptedExcepti= on + { + if (trace) log.trace("Attempting to lock " + key); + Lock lock =3D lockContainer.getLock(key); + return lock.tryLock(lockAcquisitionTimeout, MILLISECONDS); + } + + public boolean lock(Object key, Object owner, long timeoutMillis) throw= s InterruptedException + { + if (trace) log.trace("Attempting to lock " + key); + Lock lock =3D 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 =3D lockContainer.getLock(key); + if (lock.tryLock(ctx.getLockAcquisitionTimeout(lockAcquisitionTimeou= t), 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 =3D lockContainer.getLock(key); + lock.unlock(); + } + + @SuppressWarnings("unchecked") + public void unlock(InvocationContext ctx) + { + List locks =3D ctx.getKeysLocked(); + if (!locks.isEmpty()) + { + // unlocking needs to be done in reverse order. + ListIterator it =3D locks.listIterator(locks.size()); + while (it.hasPrevious()) + { + Object k =3D 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 =3D 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(); + } +} --===============3602965195230389912==--