/* * JBoss, Home of Professional Open Source * Copyright 2009 Red Hat Inc. and/or its affiliates and other * contributors as indicated by the @author tags. All rights reserved. * 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.infinispan.util.concurrent.locks; import org.infinispan.container.entries.CacheEntry; import org.infinispan.context.InvocationContext; import org.infinispan.util.concurrent.TimeoutException; import java.util.Collection; /** * An interface to deal with all aspects of acquiring and releasing locks for cache entries. * * @author Manik Surtani (<a href="mailto:manik@jboss.org">manik@jboss.org</a>) * @author Mircea.Markus@jboss.com * @author Pedro Ruivo * @since 4.0 */ public interface LockManager { /** * Acquires a lock of type lockType, on a specific entry in the cache. 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.infinispan.config.Configuration#getLockAcquisitionTimeout()}. * <p/> * * * @param key key to lock * @param ctx invocation context associated with this invocation * @param timeoutMillis * @return true if the lock was acquired, false otherwise. * @throws InterruptedException if interrupted */ boolean lockAndRecord(Object key, InvocationContext ctx, long timeoutMillis) throws InterruptedException; boolean shareLockAndRecord(Object key, InvocationContext ctx, long timeoutMillis) throws InterruptedException; /** * Releases the lock passed in. * @param lockOwner */ void unlock(Collection<Object> lockedKeys, Object lockOwner); /** * 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/> * * @param ctx invocation context to inspect */ void unlockAll(InvocationContext ctx); /** * Tests whether a given owner owns a lock of lockType on a particular cache entry. * * @param key * @param owner owner * @return true if the owner does own the specified lock type on the specified cache entry, false otherwise. */ boolean ownsLock(Object key, Object owner); /** * Returns true if the cache entry is locked (either for reading or writing) by anyone, and false otherwise. * * @param key * @return true of locked; false if not. */ boolean isLocked(Object key); /** * Retrieves the write lock owner, if any, for the specified cache entry. * * @param key * @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(); /** * Inspects the entry for signs that it is possibly locked, and hence would need to be unlocked. Note that this is * not deterministic, and is pessimistic in that even if an entry is not locked but *might* be locked, this will * return true. * <p/> * As such, this should only be used to determine whether *unlocking* is necessary, not whether locking is necessary. * Unlocking an entry that has not been locked has no effect, so this is just an optimisation. * <p/> * * @param entry entry to inspect * @return true if the entry *might* be locked, false if the entry definitely is *not* locked. */ boolean possiblyLocked(CacheEntry entry); /** * Retrieves the number of locks currently held. * @return an integer */ int getNumberOfLocksHeld(); /** * Returns the 'id' of the lock that will be used to guard access to a given key in the cache. Particularly useful * if Lock Striping is used and locks may guard more than one key. This mechanism can be used to check whether * keys may end up sharing the same lock. * <p /> * If lock-striping is not used, the identity hash code of the lock created for this specific key is returned. While * this may not be of much value, it is done to maintain API compatibility of this method regardless of underlying * locking scheme. * * @param key key to test for * @return the ID of the lock. */ int getLockId(Object key); /** * Attempts to lock an entry if the lock isn't already held in the current scope, and records the lock in the * context. * * @param ctx context * @param key Key to lock * @return true if a lock was needed and acquired, false if it didn't need to acquire the lock (i.e., lock was * already held) * @throws InterruptedException if interrupted * @throws org.infinispan.util.concurrent.TimeoutException * if we are unable to acquire the lock after a specified timeout. */ boolean acquireLock(InvocationContext ctx, Object key, boolean share) throws InterruptedException, TimeoutException; boolean acquireLock(InvocationContext ctx, Object key, long timeoutMillis, boolean share) throws InterruptedException, TimeoutException; /** * Same as {@link #acquireLock(org.infinispan.context.InvocationContext, Object)}, but doesn't check whether the * lock is already acquired by the caller. Useful in the case of transactions that use {@link OwnableReentrantLock}s * ,as these locks already perform this check internally. * @param ctx * @param key * @return * @throws InterruptedException * @throws org.infinispan.util.concurrent.TimeoutException */ boolean acquireLockNoCheck(InvocationContext ctx, Object key) throws InterruptedException, TimeoutException; }