001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *     http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.commons.transaction.locking;
018
019/**
020 * 
021 * Extended multi level lock. Compared to basic {@link MultiLevelLock} allows for more flexible
022 * locking including preference and more compatibility modes.
023 * 
024 * @version $Id: MultiLevelLock2.java 493628 2007-01-07 01:42:48Z joerg $
025 * @see LockManager2
026 * @see MultiLevelLock
027 * @see GenericLock
028 * @since 1.1
029 */
030public interface MultiLevelLock2 extends MultiLevelLock {
031
032    /**
033     * Compatibility mode: none reentrant. Lock level by the same owner <em>shall</em>
034     * affect compatibility.
035     */
036    public static final int COMPATIBILITY_NONE = 0;
037
038    /**
039     * Compatibility mode: reentrant. Lock level by the same owner <em>shall not</em>
040     * affect compatibility.
041     */
042    public static final int COMPATIBILITY_REENTRANT = 1;
043    
044    /**
045     * Compatibility mode: supporting. Lock levels that are the same as the
046     * desired <em>shall not</em> affect compatibility, but lock level held by the same
047     * owner <em>shall</em>.
048     */
049    public static final int COMPATIBILITY_SUPPORT = 2;
050
051    /**
052     * Compatibility mode: reentrant and supporting. Lock levels that are the same as the
053     * desired and lock levels held by the same
054     * owner <em>shall not</em> affect compatibility.
055     */
056    public static final int COMPATIBILITY_REENTRANT_AND_SUPPORT = 3;
057    
058    /**
059     * Tests if a certain lock level is owned by an owner. 
060     * 
061     * @param ownerId
062     *            a unique id identifying the entity that wants to check a
063     *            certain lock level on this lock
064     * @param lockLevel
065     *            the lock level to test
066     * @return <code>true</code> if the lock could be acquired at the time
067     *         this method was called
068     */
069    public boolean has(Object ownerId, int lockLevel);
070    
071    /**
072     * Tests if a certain lock level <em>could</em> be acquired. This method
073     * tests only and does <em>not actually acquire</em> the lock.
074     * 
075     * @param ownerId
076     *            a unique id identifying the entity that wants to test a
077     *            certain lock level on this lock
078     * @param targetLockLevel
079     *            the lock level to acquire
080     * @param compatibility
081     *            {@link #COMPATIBILITY_NONE}if no additional compatibility is
082     *            desired (same as reentrant set to false) ,
083     *            {@link #COMPATIBILITY_REENTRANT}if lock level by the same
084     *            owner shall not affect compatibility (same as reentrant set to
085     *            true), or {@link #COMPATIBILITY_SUPPORT}if lock levels that
086     *            are the same as the desired shall not affect compatibility, or
087     *            finally {@link #COMPATIBILITY_REENTRANT_AND_SUPPORT}which is
088     *            a combination of reentrant and support
089     * @return <code>true</code> if the lock could be acquired at the time
090     *         this method was called
091     */
092    public boolean test(Object ownerId, int targetLockLevel, int compatibility);
093    
094    /**
095     * Tries to acquire a certain lock level on this lock. Does the same as
096     * {@link org.apache.commons.transaction.locking.MultiLevelLock#acquire(java.lang.Object, int, boolean, boolean, long)}
097     * except that it allows for different compatibility settings. There is an
098     * additional compatibility mode {@link #COMPATIBILITY_SUPPORT}that allows
099     * equal lock levels not to interfere with each other. This is like an
100     * additional shared compatibility and useful when you only want to make
101     * sure not to interfer with lowe levels, but are fine with the same.
102     * 
103     * @param ownerId a unique id identifying the entity that wants to acquire a certain lock level on this lock
104     * @param targetLockLevel the lock level to acquire
105     * @param wait <code>true</code> if this method shall block when the desired lock level can not be acquired
106     * @param compatibility
107     *            {@link #COMPATIBILITY_NONE}if no additional compatibility is
108     *            desired (same as reentrant set to false) ,
109     *            {@link #COMPATIBILITY_REENTRANT}if lock level by the same
110     *            owner shall not affect compatibility (same as reentrant set to
111     *            true), or {@link #COMPATIBILITY_SUPPORT}if lock levels that
112     *            are the same as the desired shall not affect compatibility, or
113     *            finally {@link #COMPATIBILITY_REENTRANT_AND_SUPPORT}which is
114     *            a combination of reentrant and support
115     * 
116     * @param preferred
117     *            in case this lock request is incompatible with existing ones
118     *            and we wait, it shall be granted before other waiting requests
119     *            that are not preferred
120     * @param timeoutMSecs if blocking is enabled by the <code>wait</code> parameter this specifies the maximum wait time in milliseconds
121     * @return <code>true</code> if the lock actually was acquired 
122     * @throws InterruptedException when the thread waiting on this method is interrupted
123     * 
124     */
125    public boolean acquire(Object ownerId, int targetLockLevel, boolean wait, int compatibility,
126            boolean preferred, long timeoutMSecs) throws InterruptedException;
127
128}