You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@turbine.apache.org by tv...@apache.org on 2007/05/05 08:58:51 UTC

svn commit: r535465 [41/49] - in /jakarta/turbine/fulcrum/trunk: ./ bsf/ bsf/src/java/org/apache/fulcrum/bsf/ bsf/src/test/ bsf/xdocs/ cache/ cache/src/java/org/apache/fulcrum/cache/ cache/src/java/org/apache/fulcrum/cache/impl/ cache/src/test/ cache/s...

Modified: jakarta/turbine/fulcrum/trunk/yaafi/src/java/org/apache/fulcrum/yaafi/framework/locking/GenericLock.java
URL: http://svn.apache.org/viewvc/jakarta/turbine/fulcrum/trunk/yaafi/src/java/org/apache/fulcrum/yaafi/framework/locking/GenericLock.java?view=diff&rev=535465&r1=535464&r2=535465
==============================================================================
--- jakarta/turbine/fulcrum/trunk/yaafi/src/java/org/apache/fulcrum/yaafi/framework/locking/GenericLock.java (original)
+++ jakarta/turbine/fulcrum/trunk/yaafi/src/java/org/apache/fulcrum/yaafi/framework/locking/GenericLock.java Fri May  4 23:58:06 2007
@@ -1,639 +1,635 @@
-/*
- * $Header: /usr/local/cvsroot/it20one/service/it20one-service-framework/src/java/org/apache/fulcrum/yaafi/framework/locking/GenericLock.java,v 1.1 2005/09/22 11:04:12 sigi Exp $
- * $Revision: 1.1 $
- * $Date: 2005/09/22 11:04:12 $
- *
- * ====================================================================
- *
- * Copyright 1999-2004 The Apache Software Foundation 
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-package org.apache.fulcrum.yaafi.framework.locking;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-
-/**
- * 
- * A generic implementaion of a simple multi level lock.
- * 
- * <p>
- * The idea is to have an ascending number of lock levels ranging from
- * <code>0</code> to <code>maxLockLevel</code> as specified in
- * {@link #GenericLock(Object, int, LoggerFacade)}: the higher the lock level
- * the stronger and more restrictive the lock. To determine which lock may
- * coexist with other locks you have to imagine matching pairs of lock levels.
- * For each pair both parts allow for all lock levels less than or equal to the
- * matching other part. Pairs are composed by the lowest and highest level not
- * yet part of a pair and successively applying this method until no lock level
- * is left. For an even amount of levels each level is part of exactly one pair.
- * For an odd amount the middle level is paired with itself. The highst lock
- * level may coexist with the lowest one (<code>0</code>) which by
- * definition means <code>NO LOCK</code>. This implies that you will have to
- * specify at least one other lock level and thus set <code>maxLockLevel</code>
- * to at least <code>1</code>.
- * </p>
- * 
- * <p>
- * Although this may sound complicated, in practice this is quite simple. Let us
- * imagine you have three lock levels:
- * <ul>
- * <li><code>0</code>:<code>NO LOCK</code> (always needed by the
- * implementation of this lock)
- * <li><code>1</code>:<code>SHARED</code>
- * <li><code>2</code>:<code>EXCLUSIVE</code>
- * </ul>
- * Accordingly, you will have to set <code>maxLockLevel</code> to
- * <code>2</code>. Now, there are two pairs of levels
- * <ul>
- * <li><code>NO LOCK</code> with <code>EXCLUSIVE</code>
- * <li><code>SHARED</code> with <code>SHARED</code>
- * </ul>
- * This means when the current highest lock level is <code>NO LOCK</code>
- * everything less or equal to <code>EXCLUSIVE</code> is allowed - which means
- * every other lock level. On the other side <code>EXCLUSIVE</code> allows
- * exacly for <code>NO LOCK</code>- which means nothing else. In conclusion,
- * <code>SHARED</code> allows for <code>SHARED</code> or <code>NO
- * LOCK</code>,
- * but not for <code>EXCLUSIVE</code>. To make this very clear have a look at
- * this table, where <code>o</code> means compatible or can coexist and
- * <code>x</code> means incompatible or can not coexist:
- * </p>
- * <table><tbody>
- * <tr>
- * <td align="center"></td>
- * <td align="center">NO LOCK</td>
- * <td align="center">SHARED</td>
- * <td align="center">EXCLUSIVE</td>
- * </tr>
- * <tr>
- * <td align="center">NO LOCK</td>
- * <td align="center">o</td>
- * <td align="center">o</td>
- * <td align="center">o</td>
- * </tr>
- * <tr>
- * <td align="center">SHARED</td>
- * <td align="center">o</td>
- * <td align="center">o</td>
- * <td align="center">x</td>
- * </tr>
- * <tr>
- * <td align="center">EXCLUSIVE</td>
- * <td align="center" align="center">o</td>
- * <td align="center">x</td>
- * <td align="center">x</td>
- * </tr>
- * </tbody> </table>
- * 
- * </p>
- * <p>
- * Additionally, there are preferences for specific locks you can pass to
- * {@link #acquire(Object, int, boolean, int, boolean, long)}. 
- * This means whenever more thanone party
- * waits for a lock you can specify which one is to be preferred. This gives you
- * every freedom you might need to specifcy e.g. 
- * <ul>
- * <li>priority to parties either applying for higher or lower lock levels
- * <li>priority not only to higher or lower locks, but to a specific level
- * <li>completely random preferences
- * </ul>
- * </p>
- * 
- * @version $Revision: 1.1 $
- */
-public class GenericLock implements MultiLevelLock2 {
-
-    protected Object resourceId;
-    // XXX needs to be synchronized to allow for unsynchronized access for deadlock detection
-    // in getConflictingOwners to avoid deadlocks between lock to acquire and lock to check for
-    // deadlocks
-    protected Map owners = Collections.synchronizedMap(new HashMap());
-    // XXX needs to be synchronized to allow for unsynchronized access for deadlock detection
-    // in getConflictingWaiters to avoid deadlocks between lock to acquire and lock to check for
-    // deadlocks
-    // Note: having this as a list allows for fair mechanisms in sub classes
-    protected List waitingOwners = Collections.synchronizedList(new ArrayList());
-    private int maxLockLevel;
-    protected LoggerFacade logger;
-    protected int waiters = 0;
-    
-    /**
-     * Creates a new lock.
-     * 
-     * @param resourceId identifier for the resource associated to this lock
-     * @param maxLockLevel highest allowed lock level as described in class intro 
-     * @param logger generic logger used for all kind of debug logging
-     */
-    public GenericLock(Object resourceId, int maxLockLevel, LoggerFacade logger) {
-        if (maxLockLevel < 1)
-            throw new IllegalArgumentException(
-                "The maximum lock level must be at least 1 (" + maxLockLevel + " was specified)");
-        this.resourceId = resourceId;
-        this.maxLockLevel = maxLockLevel;
-        this.logger = logger;
-    }
-
-    public boolean equals(Object o) {
-        if (o instanceof GenericLock) {
-            return ((GenericLock)o).resourceId.equals(resourceId);
-        }
-        return false;
-    }
-
-    public int hashCode() {
-        return resourceId.hashCode();
-    }
-
-    /**
-     * @see MultiLevelLock2#test(Object, int, int)
-     */
-    public boolean test(Object ownerId, int targetLockLevel, int compatibility) {
-        boolean success = tryLock(ownerId, targetLockLevel, compatibility, false, true);
-        return success;
-    }
-    
-    /**
-     * @see MultiLevelLock2#has(Object, int)
-     */
-    public boolean has(Object ownerId, int lockLevel) {
-        int level = getLockLevel(ownerId);
-        return (lockLevel <= level);
-    }
-    
-    /**
-     * @see org.apache.fulcrum.yaafi.framework.locking.MultiLevelLock#acquire(java.lang.Object,
-     *      int, boolean, boolean, long)
-     */
-    public synchronized boolean acquire(Object ownerId, int targetLockLevel, boolean wait,
-            boolean reentrant, long timeoutMSecs) throws InterruptedException {
-        return acquire(ownerId, targetLockLevel, wait, reentrant ? COMPATIBILITY_REENTRANT
-                : COMPATIBILITY_NONE, timeoutMSecs);
-    }
-
-    /**
-     * @see #acquire(Object, int, boolean, int, boolean, long)
-     */
-    public synchronized boolean acquire(Object ownerId, int targetLockLevel, boolean wait,
-            int compatibility, long timeoutMSecs) throws InterruptedException {
-        return acquire(ownerId, targetLockLevel, wait, compatibility, false, timeoutMSecs);
-    }
-    
-    /**
-     * Tries to blockingly acquire a lock which can be preferred.
-     * 
-     * @see #acquire(Object, int, boolean, int, boolean, long) 
-     * @since 1.1 
-     */
-    public synchronized boolean acquire(Object ownerId, int targetLockLevel, boolean preferred,
-            long timeoutMSecs) throws InterruptedException {
-        return acquire(ownerId, targetLockLevel, true, COMPATIBILITY_REENTRANT, preferred,
-                timeoutMSecs);
-    }
-    
-    /**
-     * @see org.apache.fulcrum.yaafi.framework.locking.MultiLevelLock2#acquire(Object,
-     *      int, boolean, int, boolean, long)
-     * @since 1.1 
-     */
-    public synchronized boolean acquire(
-        Object ownerId,
-        int targetLockLevel,
-        boolean wait,
-        int compatibility,
-        boolean preferred,
-        long timeoutMSecs)
-        throws InterruptedException {
-
-        if (logger.isFinerEnabled()) {
-	        logger.logFiner(
-	            ownerId.toString()
-	                + " trying to acquire lock for "
-	                + resourceId.toString()
-	                + " at level "
-	                + targetLockLevel
-	                + " at "
-	                + System.currentTimeMillis());
-        }
-
-        if (tryLock(ownerId, targetLockLevel, compatibility, preferred)) {
-            
-            if (logger.isFinerEnabled()) {
-	            logger.logFiner(
-	                ownerId.toString()
-	                    + " actually acquired lock for "
-	                    + resourceId.toString()
-	                    + " at "
-	                    + System.currentTimeMillis());
-            }
-
-            return true;
-        } else {
-            if (!wait) {
-                return false;
-            } else {
-                long started = System.currentTimeMillis();
-                for (long remaining = timeoutMSecs;
-                    remaining > 0;
-                    remaining = timeoutMSecs - (System.currentTimeMillis() - started)) {
-
-                    if (logger.isFinerEnabled()) {
-	                    logger.logFiner(
-	                        ownerId.toString()
-	                            + " waiting on "
-	                            + resourceId.toString()
-	                            + " for msecs "
-	                            + timeoutMSecs
-	                            + " at "
-	                            + System.currentTimeMillis());
-                    }
-
-                    LockOwner waitingOwner = new LockOwner(ownerId, targetLockLevel, compatibility,
-                            preferred);
-                    try {
-                        registerWaiter(waitingOwner);
-                        if (preferred) {
-                            // while waiting we already make our claim we are next
-                            LockOwner oldLock = null;
-                            try {
-                                // we need to remember it to restore it after waiting
-                                oldLock = (LockOwner) owners.get(ownerId);
-                                // this creates a new owner, so we do not need to
-                                // copy the old one
-                                setLockLevel(ownerId, null, targetLockLevel, compatibility,
-                                        preferred);
-    
-                                // finally wait
-                                wait(remaining);
-                                
-                            } finally {
-                                // we need to restore the old lock in order not to
-                                // interfere with the intention lock in the
-                                // following check
-                                // and not to have it in case of success either
-                                // as there will be an ordinary lock then
-                                if (oldLock != null) {
-                                    owners.put(ownerId, oldLock);
-                                } else {
-                                    owners.remove(ownerId);
-                                }
-                            }
-    
-                        } else {
-                            wait(remaining);
-                        }
-                    } finally {
-                        unregisterWaiter(waitingOwner);
-                    }
-                    
-                    if (tryLock(ownerId, targetLockLevel, compatibility, preferred)) {
-
-                        if (logger.isFinerEnabled()) {
-	                        logger.logFiner(
-	                            ownerId.toString()
-	                                + " waiting on "
-	                                + resourceId.toString()
-	                                + " eventually got the lock at "
-	                                + System.currentTimeMillis());
-                        }
-
-                        return true;
-                    }
-                }
-                return false;
-            }
-        }
-    }
-
-    protected void registerWaiter(LockOwner waitingOwner) {
-        synchronized (waitingOwners) {
-            unregisterWaiter(waitingOwner);
-            waiters++;
-            waitingOwners.add(waitingOwner);
-        }
-    }
-
-    protected void unregisterWaiter(LockOwner waitingOwner) {
-        synchronized (waitingOwners) {
-            if (waitingOwners.remove(waitingOwner))
-                waiters--;
-        }
-    }
-    
-    /**
-     * @see org.apache.fulcrum.yaafi.framework.locking.MultiLevelLock#release(Object)
-     */
-    public synchronized boolean release(Object ownerId) {
-        if (owners.remove(ownerId) != null) {
-            if (logger.isFinerEnabled()) {
-	            logger.logFiner(
-	                ownerId.toString()
-	                    + " releasing lock for "
-	                    + resourceId.toString()
-	                    + " at "
-	                    + System.currentTimeMillis());
-            }
-            notifyAll();
-            return true;
-        }
-        return false;
-    }
-
-    /**
-     * @see org.apache.fulcrum.yaafi.framework.locking.MultiLevelLock#getLockLevel(Object)
-     */
-    public int getLockLevel(Object ownerId) {
-        LockOwner owner = (LockOwner) owners.get(ownerId);
-        if (owner == null) {
-            return 0;
-        } else {
-            return owner.lockLevel;
-        }
-    }
-
-    /**
-     * Gets the resource assotiated to this lock. 
-     * 
-     * @return identifier for the resource associated to this lock 
-     */
-    public Object getResourceId() {
-        return resourceId;
-    }
-
-    /**
-     * Gets the lowest lock level possible.
-     * 
-     * @return minimum lock level
-     */
-    public int getLevelMinLock() {
-        return 0;
-    }
-
-    /**
-     * Gets the highst lock level possible.
-     * 
-     * @return maximum lock level
-     */
-    public int getLevelMaxLock() {
-        return maxLockLevel;
-    }
-
-    public Object getOwner() {
-        LockOwner owner = getMaxLevelOwner();
-        if (owner == null)
-            return null;
-        return owner.ownerId;
-    }
-
-    public synchronized String toString() {
-        StringBuffer buf = new StringBuffer();
-        buf.append(resourceId.toString()).append(":\n");
-
-        for (Iterator it = owners.values().iterator(); it.hasNext();) {
-            LockOwner owner = (LockOwner) it.next();
-            buf.append("- ").append(owner.toString()).append("\n");
-        }
-
-        if (waiters != 0) {
-            buf.append(waiters).append(" waiting:\n");
-            for (Iterator it = waitingOwners.iterator(); it.hasNext();) {
-                LockOwner owner = (LockOwner) it.next();
-                buf.append("- ").append(owner.toString()).append("\n");
-            }
-        }
-        
-        return buf.toString();
-    }
-
-    protected synchronized LockOwner getMaxLevelOwner() {
-        return getMaxLevelOwner(null, -1, false);
-    }
-
-    protected synchronized LockOwner getMaxLevelOwner(LockOwner reentrantOwner, boolean preferred) {
-        return getMaxLevelOwner(reentrantOwner, -1, preferred);
-    }
-
-    protected synchronized LockOwner getMaxLevelOwner(int supportLockLevel, boolean preferred) {
-        return getMaxLevelOwner(null, supportLockLevel, preferred);
-    }
-
-    protected synchronized LockOwner getMaxLevelOwner(LockOwner reentrantOwner,
-            int supportLockLevel, boolean preferred) {
-        LockOwner maxOwner = null;
-        for (Iterator it = owners.values().iterator(); it.hasNext();) {
-            LockOwner owner = (LockOwner) it.next();
-            if (owner.lockLevel != supportLockLevel && !owner.equals(reentrantOwner)
-                    && (maxOwner == null || maxOwner.lockLevel < owner.lockLevel)
-                    // if we are a preferred lock we must not interfere with other intention
-                    // locks as we otherwise might mututally lock without resolvation
-                    && !(preferred && owner.intention)) {
-                maxOwner = owner;
-            }
-        }
-        return maxOwner;
-    }
-    
-    protected synchronized void setLockLevel(Object ownerId, LockOwner lock, int targetLockLevel,
-            int compatibility, boolean intention) {
-        // be sure there exists at most one lock per owner
-        if (lock != null) {
-            if (logger.isFinestEnabled()) {
-	            logger.logFinest(
-	                ownerId.toString()
-	                    + " upgrading lock for "
-	                    + resourceId.toString()
-	                    + " to level "
-	                    + targetLockLevel
-	                    + " at "
-	                    + System.currentTimeMillis());
-            }
-        } else {
-            if (logger.isFinestEnabled()) {
-	            logger.logFinest(
-	                ownerId.toString()
-	                    + " getting new lock for "
-	                    + resourceId.toString()
-	                    + " at level "
-	                    + targetLockLevel
-	                    + " at "
-	                    + System.currentTimeMillis());
-            }
-        }
-        owners.put(ownerId, new LockOwner(ownerId, targetLockLevel, compatibility, intention));
-    }
-
-    protected boolean tryLock(Object ownerId, int targetLockLevel, int compatibility,
-            boolean preferred) {
-        return tryLock(ownerId, targetLockLevel, compatibility, preferred, false);
-    }
-
-    protected synchronized boolean tryLock(Object ownerId, int targetLockLevel, int compatibility,
-            boolean preferred, boolean tryOnly) {
-
-        LockOwner myLock = (LockOwner) owners.get(ownerId);
-
-        // determine highest owner        
-        LockOwner highestOwner;
-        if (compatibility == COMPATIBILITY_REENTRANT) {
-            if (myLock != null && targetLockLevel <= myLock.lockLevel) {
-                // we already have it
-                return true;
-            } else {
-                // our own lock will not be compromised by ourself
-                highestOwner = getMaxLevelOwner(myLock, preferred);
-            }
-        } else if (compatibility == COMPATIBILITY_SUPPORT) {
-            // we are compatible with any other lock owner holding
-            // the same lock level
-            highestOwner = getMaxLevelOwner(targetLockLevel, preferred);
-
-        } else if (compatibility == COMPATIBILITY_REENTRANT_AND_SUPPORT) {
-            if (myLock != null && targetLockLevel <= myLock.lockLevel) {
-                // we already have it
-                return true;
-            } else {
-                // our own lock will not be compromised by ourself and same lock level 
-                highestOwner = getMaxLevelOwner(myLock, targetLockLevel, preferred);
-            }
-        } else {
-            highestOwner = getMaxLevelOwner();
-        }
-
-        // what is our current lock level?
-        int currentLockLevel;
-        if (highestOwner != null) {
-            currentLockLevel = highestOwner.lockLevel;
-        } else {
-            currentLockLevel = getLevelMinLock();
-        }
-
-        // we are only allowed to acquire our locks if we do not compromise locks of any other lock owner
-        if (isCompatible(targetLockLevel, currentLockLevel)) {
-            if (!tryOnly) {
-                // if we really have the lock, it no longer is an intention
-                setLockLevel(ownerId, myLock, targetLockLevel, compatibility, false);
-            }
-            return true;
-        } else {
-            return false;
-        }
-    }
-
-    protected boolean isCompatible(int targetLockLevel, int currentLockLevel) {
-        return (targetLockLevel <= getLevelMaxLock() - currentLockLevel);
-    }
-    
-    protected Set getConflictingOwners(Object ownerId, int targetLockLevel, int compatibility) {
-
-        LockOwner myLock = (LockOwner) owners.get(ownerId);
-        if (myLock != null && targetLockLevel <= myLock.lockLevel) {
-            // shortcut as we already have the lock
-            return null;
-        }
-        
-        LockOwner testLock = new LockOwner(ownerId, targetLockLevel, compatibility, false);
-        List ownersCopy;
-        synchronized (owners) {
-            ownersCopy = new ArrayList(owners.values());
-        }
-        return getConflictingOwners(testLock, ownersCopy);
-        
-    }
-
-    protected Collection getConflictingWaiters(Object ownerId) {
-        LockOwner owner = (LockOwner) owners.get(ownerId);
-        if (owner != null) {
-            List waiterCopy;
-            synchronized (waitingOwners) {
-                waiterCopy = new ArrayList(waitingOwners);
-            }
-            Collection conflicts = getConflictingOwners(owner, waiterCopy);
-            return conflicts;
-        }
-        return null;
-    }
-    
-    protected Set getConflictingOwners(LockOwner myOwner, Collection ownersToTest) {
-
-        if (myOwner == null) return null;
-        
-        Set conflicts = new HashSet();
-
-        // check if any locks conflict with ours
-        for (Iterator it = ownersToTest.iterator(); it.hasNext();) {
-            LockOwner owner = (LockOwner) it.next();
-            
-            // we do not interfere with ourselves, except when explicitely said so
-            if ((myOwner.compatibility == COMPATIBILITY_REENTRANT || myOwner.compatibility == COMPATIBILITY_REENTRANT_AND_SUPPORT)
-                    && owner.ownerId.equals(myOwner.ownerId))
-                continue;
-            
-            // otherwise find out the lock level of the owner and see if we conflict with it
-            int onwerLockLevel = owner.lockLevel;
-           
-            if (myOwner.compatibility == COMPATIBILITY_SUPPORT
-                    || myOwner.compatibility == COMPATIBILITY_REENTRANT_AND_SUPPORT
-                    && myOwner.lockLevel == onwerLockLevel)
-                continue;
-            
-            if (!isCompatible(myOwner.lockLevel, onwerLockLevel)) {
-                conflicts.add(owner.ownerId);
-            }
-        }
-        return (conflicts.isEmpty() ? null : conflicts);
-    }
-
-    protected static class LockOwner {
-        public final Object ownerId;
-        public final int lockLevel;
-        public final boolean intention;
-        public final int compatibility;
-
-        public LockOwner(Object ownerId, int lockLevel, int compatibility, boolean intention) {
-            this.ownerId = ownerId;
-            this.lockLevel = lockLevel;
-            this.intention = intention;
-            this.compatibility = compatibility;
-        }
-
-        public String toString() {
-            StringBuffer buf = new StringBuffer();
-            buf.append(ownerId.toString()).append(": level ").append(lockLevel).append(", complevel ")
-                    .append(compatibility).append(intention ? ", intention/preferred" : "");
-            return buf.toString();
-        }
-        
-        public boolean equals(Object o) {
-            if (o instanceof LockOwner) {
-                return ((LockOwner)o).ownerId.equals(ownerId);
-            }
-            return false;
-        }
-        
-        public int hashCode() {
-            return ownerId.hashCode();
-        }
-    }
-
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.fulcrum.yaafi.framework.locking;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+
+/**
+ *
+ * A generic implementaion of a simple multi level lock.
+ *
+ * <p>
+ * The idea is to have an ascending number of lock levels ranging from
+ * <code>0</code> to <code>maxLockLevel</code> as specified in
+ * {@link #GenericLock(Object, int, LoggerFacade)}: the higher the lock level
+ * the stronger and more restrictive the lock. To determine which lock may
+ * coexist with other locks you have to imagine matching pairs of lock levels.
+ * For each pair both parts allow for all lock levels less than or equal to the
+ * matching other part. Pairs are composed by the lowest and highest level not
+ * yet part of a pair and successively applying this method until no lock level
+ * is left. For an even amount of levels each level is part of exactly one pair.
+ * For an odd amount the middle level is paired with itself. The highst lock
+ * level may coexist with the lowest one (<code>0</code>) which by
+ * definition means <code>NO LOCK</code>. This implies that you will have to
+ * specify at least one other lock level and thus set <code>maxLockLevel</code>
+ * to at least <code>1</code>.
+ * </p>
+ *
+ * <p>
+ * Although this may sound complicated, in practice this is quite simple. Let us
+ * imagine you have three lock levels:
+ * <ul>
+ * <li><code>0</code>:<code>NO LOCK</code> (always needed by the
+ * implementation of this lock)
+ * <li><code>1</code>:<code>SHARED</code>
+ * <li><code>2</code>:<code>EXCLUSIVE</code>
+ * </ul>
+ * Accordingly, you will have to set <code>maxLockLevel</code> to
+ * <code>2</code>. Now, there are two pairs of levels
+ * <ul>
+ * <li><code>NO LOCK</code> with <code>EXCLUSIVE</code>
+ * <li><code>SHARED</code> with <code>SHARED</code>
+ * </ul>
+ * This means when the current highest lock level is <code>NO LOCK</code>
+ * everything less or equal to <code>EXCLUSIVE</code> is allowed - which means
+ * every other lock level. On the other side <code>EXCLUSIVE</code> allows
+ * exacly for <code>NO LOCK</code>- which means nothing else. In conclusion,
+ * <code>SHARED</code> allows for <code>SHARED</code> or <code>NO
+ * LOCK</code>,
+ * but not for <code>EXCLUSIVE</code>. To make this very clear have a look at
+ * this table, where <code>o</code> means compatible or can coexist and
+ * <code>x</code> means incompatible or can not coexist:
+ * </p>
+ * <table><tbody>
+ * <tr>
+ * <td align="center"></td>
+ * <td align="center">NO LOCK</td>
+ * <td align="center">SHARED</td>
+ * <td align="center">EXCLUSIVE</td>
+ * </tr>
+ * <tr>
+ * <td align="center">NO LOCK</td>
+ * <td align="center">o</td>
+ * <td align="center">o</td>
+ * <td align="center">o</td>
+ * </tr>
+ * <tr>
+ * <td align="center">SHARED</td>
+ * <td align="center">o</td>
+ * <td align="center">o</td>
+ * <td align="center">x</td>
+ * </tr>
+ * <tr>
+ * <td align="center">EXCLUSIVE</td>
+ * <td align="center" align="center">o</td>
+ * <td align="center">x</td>
+ * <td align="center">x</td>
+ * </tr>
+ * </tbody> </table>
+ *
+ * </p>
+ * <p>
+ * Additionally, there are preferences for specific locks you can pass to
+ * {@link #acquire(Object, int, boolean, int, boolean, long)}.
+ * This means whenever more thanone party
+ * waits for a lock you can specify which one is to be preferred. This gives you
+ * every freedom you might need to specifcy e.g.
+ * <ul>
+ * <li>priority to parties either applying for higher or lower lock levels
+ * <li>priority not only to higher or lower locks, but to a specific level
+ * <li>completely random preferences
+ * </ul>
+ * </p>
+ *
+ * @version $Revision: 1.1 $
+ */
+public class GenericLock implements MultiLevelLock2 {
+
+    protected Object resourceId;
+    // XXX needs to be synchronized to allow for unsynchronized access for deadlock detection
+    // in getConflictingOwners to avoid deadlocks between lock to acquire and lock to check for
+    // deadlocks
+    protected Map owners = Collections.synchronizedMap(new HashMap());
+    // XXX needs to be synchronized to allow for unsynchronized access for deadlock detection
+    // in getConflictingWaiters to avoid deadlocks between lock to acquire and lock to check for
+    // deadlocks
+    // Note: having this as a list allows for fair mechanisms in sub classes
+    protected List waitingOwners = Collections.synchronizedList(new ArrayList());
+    private int maxLockLevel;
+    protected LoggerFacade logger;
+    protected int waiters = 0;
+
+    /**
+     * Creates a new lock.
+     *
+     * @param resourceId identifier for the resource associated to this lock
+     * @param maxLockLevel highest allowed lock level as described in class intro
+     * @param logger generic logger used for all kind of debug logging
+     */
+    public GenericLock(Object resourceId, int maxLockLevel, LoggerFacade logger) {
+        if (maxLockLevel < 1)
+            throw new IllegalArgumentException(
+                "The maximum lock level must be at least 1 (" + maxLockLevel + " was specified)");
+        this.resourceId = resourceId;
+        this.maxLockLevel = maxLockLevel;
+        this.logger = logger;
+    }
+
+    public boolean equals(Object o) {
+        if (o instanceof GenericLock) {
+            return ((GenericLock)o).resourceId.equals(resourceId);
+        }
+        return false;
+    }
+
+    public int hashCode() {
+        return resourceId.hashCode();
+    }
+
+    /**
+     * @see MultiLevelLock2#test(Object, int, int)
+     */
+    public boolean test(Object ownerId, int targetLockLevel, int compatibility) {
+        boolean success = tryLock(ownerId, targetLockLevel, compatibility, false, true);
+        return success;
+    }
+
+    /**
+     * @see MultiLevelLock2#has(Object, int)
+     */
+    public boolean has(Object ownerId, int lockLevel) {
+        int level = getLockLevel(ownerId);
+        return (lockLevel <= level);
+    }
+
+    /**
+     * @see org.apache.fulcrum.yaafi.framework.locking.MultiLevelLock#acquire(java.lang.Object,
+     *      int, boolean, boolean, long)
+     */
+    public synchronized boolean acquire(Object ownerId, int targetLockLevel, boolean wait,
+            boolean reentrant, long timeoutMSecs) throws InterruptedException {
+        return acquire(ownerId, targetLockLevel, wait, reentrant ? COMPATIBILITY_REENTRANT
+                : COMPATIBILITY_NONE, timeoutMSecs);
+    }
+
+    /**
+     * @see #acquire(Object, int, boolean, int, boolean, long)
+     */
+    public synchronized boolean acquire(Object ownerId, int targetLockLevel, boolean wait,
+            int compatibility, long timeoutMSecs) throws InterruptedException {
+        return acquire(ownerId, targetLockLevel, wait, compatibility, false, timeoutMSecs);
+    }
+
+    /**
+     * Tries to blockingly acquire a lock which can be preferred.
+     *
+     * @see #acquire(Object, int, boolean, int, boolean, long)
+     * @since 1.1
+     */
+    public synchronized boolean acquire(Object ownerId, int targetLockLevel, boolean preferred,
+            long timeoutMSecs) throws InterruptedException {
+        return acquire(ownerId, targetLockLevel, true, COMPATIBILITY_REENTRANT, preferred,
+                timeoutMSecs);
+    }
+
+    /**
+     * @see org.apache.fulcrum.yaafi.framework.locking.MultiLevelLock2#acquire(Object,
+     *      int, boolean, int, boolean, long)
+     * @since 1.1
+     */
+    public synchronized boolean acquire(
+        Object ownerId,
+        int targetLockLevel,
+        boolean wait,
+        int compatibility,
+        boolean preferred,
+        long timeoutMSecs)
+        throws InterruptedException {
+
+        if (logger.isFinerEnabled()) {
+	        logger.logFiner(
+	            ownerId.toString()
+	                + " trying to acquire lock for "
+	                + resourceId.toString()
+	                + " at level "
+	                + targetLockLevel
+	                + " at "
+	                + System.currentTimeMillis());
+        }
+
+        if (tryLock(ownerId, targetLockLevel, compatibility, preferred)) {
+
+            if (logger.isFinerEnabled()) {
+	            logger.logFiner(
+	                ownerId.toString()
+	                    + " actually acquired lock for "
+	                    + resourceId.toString()
+	                    + " at "
+	                    + System.currentTimeMillis());
+            }
+
+            return true;
+        } else {
+            if (!wait) {
+                return false;
+            } else {
+                long started = System.currentTimeMillis();
+                for (long remaining = timeoutMSecs;
+                    remaining > 0;
+                    remaining = timeoutMSecs - (System.currentTimeMillis() - started)) {
+
+                    if (logger.isFinerEnabled()) {
+	                    logger.logFiner(
+	                        ownerId.toString()
+	                            + " waiting on "
+	                            + resourceId.toString()
+	                            + " for msecs "
+	                            + timeoutMSecs
+	                            + " at "
+	                            + System.currentTimeMillis());
+                    }
+
+                    LockOwner waitingOwner = new LockOwner(ownerId, targetLockLevel, compatibility,
+                            preferred);
+                    try {
+                        registerWaiter(waitingOwner);
+                        if (preferred) {
+                            // while waiting we already make our claim we are next
+                            LockOwner oldLock = null;
+                            try {
+                                // we need to remember it to restore it after waiting
+                                oldLock = (LockOwner) owners.get(ownerId);
+                                // this creates a new owner, so we do not need to
+                                // copy the old one
+                                setLockLevel(ownerId, null, targetLockLevel, compatibility,
+                                        preferred);
+
+                                // finally wait
+                                wait(remaining);
+
+                            } finally {
+                                // we need to restore the old lock in order not to
+                                // interfere with the intention lock in the
+                                // following check
+                                // and not to have it in case of success either
+                                // as there will be an ordinary lock then
+                                if (oldLock != null) {
+                                    owners.put(ownerId, oldLock);
+                                } else {
+                                    owners.remove(ownerId);
+                                }
+                            }
+
+                        } else {
+                            wait(remaining);
+                        }
+                    } finally {
+                        unregisterWaiter(waitingOwner);
+                    }
+
+                    if (tryLock(ownerId, targetLockLevel, compatibility, preferred)) {
+
+                        if (logger.isFinerEnabled()) {
+	                        logger.logFiner(
+	                            ownerId.toString()
+	                                + " waiting on "
+	                                + resourceId.toString()
+	                                + " eventually got the lock at "
+	                                + System.currentTimeMillis());
+                        }
+
+                        return true;
+                    }
+                }
+                return false;
+            }
+        }
+    }
+
+    protected void registerWaiter(LockOwner waitingOwner) {
+        synchronized (waitingOwners) {
+            unregisterWaiter(waitingOwner);
+            waiters++;
+            waitingOwners.add(waitingOwner);
+        }
+    }
+
+    protected void unregisterWaiter(LockOwner waitingOwner) {
+        synchronized (waitingOwners) {
+            if (waitingOwners.remove(waitingOwner))
+                waiters--;
+        }
+    }
+
+    /**
+     * @see org.apache.fulcrum.yaafi.framework.locking.MultiLevelLock#release(Object)
+     */
+    public synchronized boolean release(Object ownerId) {
+        if (owners.remove(ownerId) != null) {
+            if (logger.isFinerEnabled()) {
+	            logger.logFiner(
+	                ownerId.toString()
+	                    + " releasing lock for "
+	                    + resourceId.toString()
+	                    + " at "
+	                    + System.currentTimeMillis());
+            }
+            notifyAll();
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * @see org.apache.fulcrum.yaafi.framework.locking.MultiLevelLock#getLockLevel(Object)
+     */
+    public int getLockLevel(Object ownerId) {
+        LockOwner owner = (LockOwner) owners.get(ownerId);
+        if (owner == null) {
+            return 0;
+        } else {
+            return owner.lockLevel;
+        }
+    }
+
+    /**
+     * Gets the resource assotiated to this lock.
+     *
+     * @return identifier for the resource associated to this lock
+     */
+    public Object getResourceId() {
+        return resourceId;
+    }
+
+    /**
+     * Gets the lowest lock level possible.
+     *
+     * @return minimum lock level
+     */
+    public int getLevelMinLock() {
+        return 0;
+    }
+
+    /**
+     * Gets the highst lock level possible.
+     *
+     * @return maximum lock level
+     */
+    public int getLevelMaxLock() {
+        return maxLockLevel;
+    }
+
+    public Object getOwner() {
+        LockOwner owner = getMaxLevelOwner();
+        if (owner == null)
+            return null;
+        return owner.ownerId;
+    }
+
+    public synchronized String toString() {
+        StringBuffer buf = new StringBuffer();
+        buf.append(resourceId.toString()).append(":\n");
+
+        for (Iterator it = owners.values().iterator(); it.hasNext();) {
+            LockOwner owner = (LockOwner) it.next();
+            buf.append("- ").append(owner.toString()).append("\n");
+        }
+
+        if (waiters != 0) {
+            buf.append(waiters).append(" waiting:\n");
+            for (Iterator it = waitingOwners.iterator(); it.hasNext();) {
+                LockOwner owner = (LockOwner) it.next();
+                buf.append("- ").append(owner.toString()).append("\n");
+            }
+        }
+
+        return buf.toString();
+    }
+
+    protected synchronized LockOwner getMaxLevelOwner() {
+        return getMaxLevelOwner(null, -1, false);
+    }
+
+    protected synchronized LockOwner getMaxLevelOwner(LockOwner reentrantOwner, boolean preferred) {
+        return getMaxLevelOwner(reentrantOwner, -1, preferred);
+    }
+
+    protected synchronized LockOwner getMaxLevelOwner(int supportLockLevel, boolean preferred) {
+        return getMaxLevelOwner(null, supportLockLevel, preferred);
+    }
+
+    protected synchronized LockOwner getMaxLevelOwner(LockOwner reentrantOwner,
+            int supportLockLevel, boolean preferred) {
+        LockOwner maxOwner = null;
+        for (Iterator it = owners.values().iterator(); it.hasNext();) {
+            LockOwner owner = (LockOwner) it.next();
+            if (owner.lockLevel != supportLockLevel && !owner.equals(reentrantOwner)
+                    && (maxOwner == null || maxOwner.lockLevel < owner.lockLevel)
+                    // if we are a preferred lock we must not interfere with other intention
+                    // locks as we otherwise might mututally lock without resolvation
+                    && !(preferred && owner.intention)) {
+                maxOwner = owner;
+            }
+        }
+        return maxOwner;
+    }
+
+    protected synchronized void setLockLevel(Object ownerId, LockOwner lock, int targetLockLevel,
+            int compatibility, boolean intention) {
+        // be sure there exists at most one lock per owner
+        if (lock != null) {
+            if (logger.isFinestEnabled()) {
+	            logger.logFinest(
+	                ownerId.toString()
+	                    + " upgrading lock for "
+	                    + resourceId.toString()
+	                    + " to level "
+	                    + targetLockLevel
+	                    + " at "
+	                    + System.currentTimeMillis());
+            }
+        } else {
+            if (logger.isFinestEnabled()) {
+	            logger.logFinest(
+	                ownerId.toString()
+	                    + " getting new lock for "
+	                    + resourceId.toString()
+	                    + " at level "
+	                    + targetLockLevel
+	                    + " at "
+	                    + System.currentTimeMillis());
+            }
+        }
+        owners.put(ownerId, new LockOwner(ownerId, targetLockLevel, compatibility, intention));
+    }
+
+    protected boolean tryLock(Object ownerId, int targetLockLevel, int compatibility,
+            boolean preferred) {
+        return tryLock(ownerId, targetLockLevel, compatibility, preferred, false);
+    }
+
+    protected synchronized boolean tryLock(Object ownerId, int targetLockLevel, int compatibility,
+            boolean preferred, boolean tryOnly) {
+
+        LockOwner myLock = (LockOwner) owners.get(ownerId);
+
+        // determine highest owner
+        LockOwner highestOwner;
+        if (compatibility == COMPATIBILITY_REENTRANT) {
+            if (myLock != null && targetLockLevel <= myLock.lockLevel) {
+                // we already have it
+                return true;
+            } else {
+                // our own lock will not be compromised by ourself
+                highestOwner = getMaxLevelOwner(myLock, preferred);
+            }
+        } else if (compatibility == COMPATIBILITY_SUPPORT) {
+            // we are compatible with any other lock owner holding
+            // the same lock level
+            highestOwner = getMaxLevelOwner(targetLockLevel, preferred);
+
+        } else if (compatibility == COMPATIBILITY_REENTRANT_AND_SUPPORT) {
+            if (myLock != null && targetLockLevel <= myLock.lockLevel) {
+                // we already have it
+                return true;
+            } else {
+                // our own lock will not be compromised by ourself and same lock level
+                highestOwner = getMaxLevelOwner(myLock, targetLockLevel, preferred);
+            }
+        } else {
+            highestOwner = getMaxLevelOwner();
+        }
+
+        // what is our current lock level?
+        int currentLockLevel;
+        if (highestOwner != null) {
+            currentLockLevel = highestOwner.lockLevel;
+        } else {
+            currentLockLevel = getLevelMinLock();
+        }
+
+        // we are only allowed to acquire our locks if we do not compromise locks of any other lock owner
+        if (isCompatible(targetLockLevel, currentLockLevel)) {
+            if (!tryOnly) {
+                // if we really have the lock, it no longer is an intention
+                setLockLevel(ownerId, myLock, targetLockLevel, compatibility, false);
+            }
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    protected boolean isCompatible(int targetLockLevel, int currentLockLevel) {
+        return (targetLockLevel <= getLevelMaxLock() - currentLockLevel);
+    }
+
+    protected Set getConflictingOwners(Object ownerId, int targetLockLevel, int compatibility) {
+
+        LockOwner myLock = (LockOwner) owners.get(ownerId);
+        if (myLock != null && targetLockLevel <= myLock.lockLevel) {
+            // shortcut as we already have the lock
+            return null;
+        }
+
+        LockOwner testLock = new LockOwner(ownerId, targetLockLevel, compatibility, false);
+        List ownersCopy;
+        synchronized (owners) {
+            ownersCopy = new ArrayList(owners.values());
+        }
+        return getConflictingOwners(testLock, ownersCopy);
+
+    }
+
+    protected Collection getConflictingWaiters(Object ownerId) {
+        LockOwner owner = (LockOwner) owners.get(ownerId);
+        if (owner != null) {
+            List waiterCopy;
+            synchronized (waitingOwners) {
+                waiterCopy = new ArrayList(waitingOwners);
+            }
+            Collection conflicts = getConflictingOwners(owner, waiterCopy);
+            return conflicts;
+        }
+        return null;
+    }
+
+    protected Set getConflictingOwners(LockOwner myOwner, Collection ownersToTest) {
+
+        if (myOwner == null) return null;
+
+        Set conflicts = new HashSet();
+
+        // check if any locks conflict with ours
+        for (Iterator it = ownersToTest.iterator(); it.hasNext();) {
+            LockOwner owner = (LockOwner) it.next();
+
+            // we do not interfere with ourselves, except when explicitely said so
+            if ((myOwner.compatibility == COMPATIBILITY_REENTRANT || myOwner.compatibility == COMPATIBILITY_REENTRANT_AND_SUPPORT)
+                    && owner.ownerId.equals(myOwner.ownerId))
+                continue;
+
+            // otherwise find out the lock level of the owner and see if we conflict with it
+            int onwerLockLevel = owner.lockLevel;
+
+            if (myOwner.compatibility == COMPATIBILITY_SUPPORT
+                    || myOwner.compatibility == COMPATIBILITY_REENTRANT_AND_SUPPORT
+                    && myOwner.lockLevel == onwerLockLevel)
+                continue;
+
+            if (!isCompatible(myOwner.lockLevel, onwerLockLevel)) {
+                conflicts.add(owner.ownerId);
+            }
+        }
+        return (conflicts.isEmpty() ? null : conflicts);
+    }
+
+    protected static class LockOwner {
+        public final Object ownerId;
+        public final int lockLevel;
+        public final boolean intention;
+        public final int compatibility;
+
+        public LockOwner(Object ownerId, int lockLevel, int compatibility, boolean intention) {
+            this.ownerId = ownerId;
+            this.lockLevel = lockLevel;
+            this.intention = intention;
+            this.compatibility = compatibility;
+        }
+
+        public String toString() {
+            StringBuffer buf = new StringBuffer();
+            buf.append(ownerId.toString()).append(": level ").append(lockLevel).append(", complevel ")
+                    .append(compatibility).append(intention ? ", intention/preferred" : "");
+            return buf.toString();
+        }
+
+        public boolean equals(Object o) {
+            if (o instanceof LockOwner) {
+                return ((LockOwner)o).ownerId.equals(ownerId);
+            }
+            return false;
+        }
+
+        public int hashCode() {
+            return ownerId.hashCode();
+        }
+    }
+
+}

Modified: jakarta/turbine/fulcrum/trunk/yaafi/src/java/org/apache/fulcrum/yaafi/framework/locking/LockException.java
URL: http://svn.apache.org/viewvc/jakarta/turbine/fulcrum/trunk/yaafi/src/java/org/apache/fulcrum/yaafi/framework/locking/LockException.java?view=diff&rev=535465&r1=535464&r2=535465
==============================================================================
--- jakarta/turbine/fulcrum/trunk/yaafi/src/java/org/apache/fulcrum/yaafi/framework/locking/LockException.java (original)
+++ jakarta/turbine/fulcrum/trunk/yaafi/src/java/org/apache/fulcrum/yaafi/framework/locking/LockException.java Fri May  4 23:58:06 2007
@@ -1,88 +1,84 @@
-/*
- * $Header: /usr/local/cvsroot/it20one/service/it20one-service-framework/src/java/org/apache/fulcrum/yaafi/framework/locking/LockException.java,v 1.1 2005/09/22 11:04:12 sigi Exp $
- * $Revision: 1.1 $
- * $Date: 2005/09/22 11:04:12 $
- *
- * ====================================================================
- *
- * Copyright 1999-2002 The Apache Software Foundation 
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-package org.apache.fulcrum.yaafi.framework.locking;
-
-/**
- * Exception displaying a lock problem.
- * 
- * @version $Revision: 1.1 $
- * @since 1.1
- */
-public class LockException extends RuntimeException {
-
-    /**
-     * Thread has been interrupted while waiting for lock.
-     */
-    public static final int CODE_INTERRUPTED = 1;
-
-    /**
-     * Maximum wait time for a lock has been exceeded.
-     */
-    public static final int CODE_TIMED_OUT = 2;
-
-    /**
-     * Locking request canceled because of deadlock.
-     */
-    public static final int CODE_DEADLOCK_VICTIM = 3;
-
-    protected Object resourceId;
-
-    protected String reason;
-
-    protected int code;
-
-    public LockException(String reason, int code, Object resourceId) {
-        this.reason = reason;
-        this.code = code;
-        this.resourceId = resourceId;
-    }
-
-    /**
-     * Returns the formal reason for the exception.
-     * 
-     * @return one of {@link #CODE_INTERRUPTED},{@link #CODE_TIMED_OUT}or
-     *         {@link #CODE_DEADLOCK_VICTIM}.
-     */
-    public int getCode() {
-        return code;
-    }
-
-    /**
-     * Returns the resource the lock was tried on.
-     * 
-     * @return the resource or <code>null</code> if not applicable
-     */
-    public Object getResourceId() {
-        return resourceId;
-    }
-
-    /**
-     * Returns the verbose for the exception.
-     * 
-     * @return the reason message
-     */
-    public String getReason() {
-        return reason;
-    }
-}
\ No newline at end of file
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.fulcrum.yaafi.framework.locking;
+
+/**
+ * Exception displaying a lock problem.
+ *
+ * @version $Revision: 1.1 $
+ * @since 1.1
+ */
+public class LockException extends RuntimeException {
+
+    /**
+     * Thread has been interrupted while waiting for lock.
+     */
+    public static final int CODE_INTERRUPTED = 1;
+
+    /**
+     * Maximum wait time for a lock has been exceeded.
+     */
+    public static final int CODE_TIMED_OUT = 2;
+
+    /**
+     * Locking request canceled because of deadlock.
+     */
+    public static final int CODE_DEADLOCK_VICTIM = 3;
+
+    protected Object resourceId;
+
+    protected String reason;
+
+    protected int code;
+
+    public LockException(String reason, int code, Object resourceId) {
+        this.reason = reason;
+        this.code = code;
+        this.resourceId = resourceId;
+    }
+
+    /**
+     * Returns the formal reason for the exception.
+     *
+     * @return one of {@link #CODE_INTERRUPTED},{@link #CODE_TIMED_OUT}or
+     *         {@link #CODE_DEADLOCK_VICTIM}.
+     */
+    public int getCode() {
+        return code;
+    }
+
+    /**
+     * Returns the resource the lock was tried on.
+     *
+     * @return the resource or <code>null</code> if not applicable
+     */
+    public Object getResourceId() {
+        return resourceId;
+    }
+
+    /**
+     * Returns the verbose for the exception.
+     *
+     * @return the reason message
+     */
+    public String getReason() {
+        return reason;
+    }
+}

Modified: jakarta/turbine/fulcrum/trunk/yaafi/src/java/org/apache/fulcrum/yaafi/framework/locking/LoggerFacade.java
URL: http://svn.apache.org/viewvc/jakarta/turbine/fulcrum/trunk/yaafi/src/java/org/apache/fulcrum/yaafi/framework/locking/LoggerFacade.java?view=diff&rev=535465&r1=535464&r2=535465
==============================================================================
--- jakarta/turbine/fulcrum/trunk/yaafi/src/java/org/apache/fulcrum/yaafi/framework/locking/LoggerFacade.java (original)
+++ jakarta/turbine/fulcrum/trunk/yaafi/src/java/org/apache/fulcrum/yaafi/framework/locking/LoggerFacade.java Fri May  4 23:58:06 2007
@@ -1,47 +1,43 @@
-/*
- * $Header: /usr/local/cvsroot/it20one/service/it20one-service-framework/src/java/org/apache/fulcrum/yaafi/framework/locking/LoggerFacade.java,v 1.1 2005/09/22 11:04:12 sigi Exp $
- * $Revision: 1.1 $
- * $Date: 2005/09/22 11:04:12 $
- *
- * ====================================================================
- *
- * Copyright 1999-2002 The Apache Software Foundation 
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-package org.apache.fulcrum.yaafi.framework.locking;
-
-
-/**
- * Facade for all kinds of logging engines.
- *   
- * @version $Revision: 1.1 $
- */
-public interface LoggerFacade {
-
-    public LoggerFacade createLogger(String name);
-
-    public void logInfo(String message);
-    public void logFine(String message);
-    public boolean isFineEnabled();
-    public void logFiner(String message);
-    public boolean isFinerEnabled();
-    public void logFinest(String message);
-    public boolean isFinestEnabled();
-    public void logWarning(String message);
-    public void logWarning(String message, Throwable t);
-    public void logSevere(String message);
-    public void logSevere(String message, Throwable t);
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.fulcrum.yaafi.framework.locking;
+
+
+/**
+ * Facade for all kinds of logging engines.
+ *
+ * @version $Revision: 1.1 $
+ */
+public interface LoggerFacade {
+
+    public LoggerFacade createLogger(String name);
+
+    public void logInfo(String message);
+    public void logFine(String message);
+    public boolean isFineEnabled();
+    public void logFiner(String message);
+    public boolean isFinerEnabled();
+    public void logFinest(String message);
+    public boolean isFinestEnabled();
+    public void logWarning(String message);
+    public void logWarning(String message, Throwable t);
+    public void logSevere(String message);
+    public void logSevere(String message, Throwable t);
+}

Modified: jakarta/turbine/fulcrum/trunk/yaafi/src/java/org/apache/fulcrum/yaafi/framework/locking/MultiLevelLock.java
URL: http://svn.apache.org/viewvc/jakarta/turbine/fulcrum/trunk/yaafi/src/java/org/apache/fulcrum/yaafi/framework/locking/MultiLevelLock.java?view=diff&rev=535465&r1=535464&r2=535465
==============================================================================
--- jakarta/turbine/fulcrum/trunk/yaafi/src/java/org/apache/fulcrum/yaafi/framework/locking/MultiLevelLock.java (original)
+++ jakarta/turbine/fulcrum/trunk/yaafi/src/java/org/apache/fulcrum/yaafi/framework/locking/MultiLevelLock.java Fri May  4 23:58:06 2007
@@ -1,65 +1,61 @@
-/*
- * $Header: /usr/local/cvsroot/it20one/service/it20one-service-framework/src/java/org/apache/fulcrum/yaafi/framework/locking/MultiLevelLock.java,v 1.2 2005/11/11 10:48:17 sigi Exp $
- * $Revision: 1.2 $
- * $Date: 2005/11/11 10:48:17 $
- *
- * ====================================================================
- *
- * Copyright 1999-2004 The Apache Software Foundation 
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-package org.apache.fulcrum.yaafi.framework.locking;
-
-/**
- * 
- * A multi level lock. Depending on the implementation more than one owner may own a certain lock level on the same lock.
- * 
- * @version $Revision: 1.2 $
- */
-public interface MultiLevelLock {
-
-    /**
-     * Tries to acquire a certain lock level on this lock.
-     * 
-     * @param ownerId a unique id identifying the entity that wants to acquire a certain lock level on this lock
-     * @param targetLockLevel the lock level to acquire
-     * @param wait <code>true</code> if this method shall block when the desired lock level can not be acquired
-     * @param reentrant <code>true</code> if lock levels of the same entity acquired earlier 
-     * should not restrict compatibility with the lock level desired now   
-     * @param timeoutMSecs if blocking is enabled by the <code>wait</code> parameter this specifies the maximum wait time in milliseconds
-     * @return <code>true</code> if the lock actually was acquired 
-     * @throws InterruptedException when the thread waiting on this method is interrupted
-     */
-    public boolean acquire(Object ownerId, int targetLockLevel, boolean wait, boolean reentrant, long timeoutMSecs)
-        throws InterruptedException;
-
-    /**
-     * Releases any lock levels the specified owner may hold on this lock.
-     * 
-     * @param ownerId a unique id identifying the entity that wants to release all lock levels
-     * @return <code>true</code> if the lock actually was released, <code>false</code> in case
-     * there was no lock held by the owner
-     */
-    public boolean release(Object ownerId);
-
-   /**
-    * Retuns the highest lock level the specified owner holds on this lock or <code>0</code> if it holds no locks at all. 
-    * 
-    * @param ownerId a unique id identifying the entity that wants to know its highest lock level
-    * @return the highest lock level
-    */
-    public int getLockLevel(Object ownerId);
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.fulcrum.yaafi.framework.locking;
+
+/**
+ *
+ * A multi level lock. Depending on the implementation more than one owner may own a certain lock level on the same lock.
+ *
+ * @version $Revision: 1.2 $
+ */
+public interface MultiLevelLock {
+
+    /**
+     * Tries to acquire a certain lock level on this lock.
+     *
+     * @param ownerId a unique id identifying the entity that wants to acquire a certain lock level on this lock
+     * @param targetLockLevel the lock level to acquire
+     * @param wait <code>true</code> if this method shall block when the desired lock level can not be acquired
+     * @param reentrant <code>true</code> if lock levels of the same entity acquired earlier
+     * should not restrict compatibility with the lock level desired now
+     * @param timeoutMSecs if blocking is enabled by the <code>wait</code> parameter this specifies the maximum wait time in milliseconds
+     * @return <code>true</code> if the lock actually was acquired
+     * @throws InterruptedException when the thread waiting on this method is interrupted
+     */
+    public boolean acquire(Object ownerId, int targetLockLevel, boolean wait, boolean reentrant, long timeoutMSecs)
+        throws InterruptedException;
+
+    /**
+     * Releases any lock levels the specified owner may hold on this lock.
+     *
+     * @param ownerId a unique id identifying the entity that wants to release all lock levels
+     * @return <code>true</code> if the lock actually was released, <code>false</code> in case
+     * there was no lock held by the owner
+     */
+    public boolean release(Object ownerId);
+
+   /**
+    * Retuns the highest lock level the specified owner holds on this lock or <code>0</code> if it holds no locks at all.
+    *
+    * @param ownerId a unique id identifying the entity that wants to know its highest lock level
+    * @return the highest lock level
+    */
+    public int getLockLevel(Object ownerId);
+}

Modified: jakarta/turbine/fulcrum/trunk/yaafi/src/java/org/apache/fulcrum/yaafi/framework/locking/MultiLevelLock2.java
URL: http://svn.apache.org/viewvc/jakarta/turbine/fulcrum/trunk/yaafi/src/java/org/apache/fulcrum/yaafi/framework/locking/MultiLevelLock2.java?view=diff&rev=535465&r1=535464&r2=535465
==============================================================================
--- jakarta/turbine/fulcrum/trunk/yaafi/src/java/org/apache/fulcrum/yaafi/framework/locking/MultiLevelLock2.java (original)
+++ jakarta/turbine/fulcrum/trunk/yaafi/src/java/org/apache/fulcrum/yaafi/framework/locking/MultiLevelLock2.java Fri May  4 23:58:06 2007
@@ -1,134 +1,130 @@
-/*
- * $Header: /usr/local/cvsroot/it20one/service/it20one-service-framework/src/java/org/apache/fulcrum/yaafi/framework/locking/MultiLevelLock2.java,v 1.2 2005/11/11 10:48:17 sigi Exp $
- * $Revision: 1.2 $
- * $Date: 2005/11/11 10:48:17 $
- *
- * ====================================================================
- *
- * Copyright 1999-2004 The Apache Software Foundation 
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-package org.apache.fulcrum.yaafi.framework.locking;
-
-/**
- * 
- * Extended multi level lock. Compared to basic {@link MultiLevelLock} allows for more flexible
- * locking including preference and more compatibility modes.
- * 
- * @version $Revision: 1.2 $
- * @see MultiLevelLock
- * @see GenericLock
- * @since 1.1
- */
-public interface MultiLevelLock2 extends MultiLevelLock {
-
-    /**
-     * Compatibility mode: none reentrant. Lock level by the same owner <em>shall</em>
-     * affect compatibility.
-     */
-    public static final int COMPATIBILITY_NONE = 0;
-
-    /**
-     * Compatibility mode: reentrant. Lock level by the same owner <em>shall not</em>
-     * affect compatibility.
-     */
-    public static final int COMPATIBILITY_REENTRANT = 1;
-    
-    /**
-     * Compatibility mode: supporting. Lock levels that are the same as the
-     * desired <em>shall not</em> affect compatibility, but lock level held by the same
-     * owner <em>shall</em>.
-     */
-    public static final int COMPATIBILITY_SUPPORT = 2;
-
-    /**
-     * Compatibility mode: reentrant and supporting. Lock levels that are the same as the
-     * desired and lock levels held by the same
-     * owner <em>shall not</em> affect compatibility.
-     */
-    public static final int COMPATIBILITY_REENTRANT_AND_SUPPORT = 3;
-    
-    /**
-     * Tests if a certain lock level is owned by an owner. 
-     * 
-     * @param ownerId
-     *            a unique id identifying the entity that wants to check a
-     *            certain lock level on this lock
-     * @param lockLevel
-     *            the lock level to test
-     * @return <code>true</code> if the lock could be acquired at the time
-     *         this method was called
-     */
-    public boolean has(Object ownerId, int lockLevel);
-    
-    /**
-     * Tests if a certain lock level <em>could</em> be acquired. This method
-     * tests only and does <em>not actually acquire</em> the lock.
-     * 
-     * @param ownerId
-     *            a unique id identifying the entity that wants to test a
-     *            certain lock level on this lock
-     * @param targetLockLevel
-     *            the lock level to acquire
-     * @param compatibility
-     *            {@link #COMPATIBILITY_NONE}if no additional compatibility is
-     *            desired (same as reentrant set to false) ,
-     *            {@link #COMPATIBILITY_REENTRANT}if lock level by the same
-     *            owner shall not affect compatibility (same as reentrant set to
-     *            true), or {@link #COMPATIBILITY_SUPPORT}if lock levels that
-     *            are the same as the desired shall not affect compatibility, or
-     *            finally {@link #COMPATIBILITY_REENTRANT_AND_SUPPORT}which is
-     *            a combination of reentrant and support
-     * @return <code>true</code> if the lock could be acquired at the time
-     *         this method was called
-     */
-    public boolean test(Object ownerId, int targetLockLevel, int compatibility);
-    
-    /**
-     * Tries to acquire a certain lock level on this lock. Does the same as
-     * {@link org.apache.fulcrum.yaafi.framework.locking.MultiLevelLock#acquire(java.lang.Object, int, boolean, boolean, long)}
-     * except that it allows for different compatibility settings. There is an
-     * additional compatibility mode {@link #COMPATIBILITY_SUPPORT}that allows
-     * equal lock levels not to interfere with each other. This is like an
-     * additional shared compatibility and useful when you only want to make
-     * sure not to interfer with lowe levels, but are fine with the same.
-     * 
-     * @param ownerId a unique id identifying the entity that wants to acquire a certain lock level on this lock
-     * @param targetLockLevel the lock level to acquire
-     * @param wait <code>true</code> if this method shall block when the desired lock level can not be acquired
-     * @param compatibility
-     *            {@link #COMPATIBILITY_NONE}if no additional compatibility is
-     *            desired (same as reentrant set to false) ,
-     *            {@link #COMPATIBILITY_REENTRANT}if lock level by the same
-     *            owner shall not affect compatibility (same as reentrant set to
-     *            true), or {@link #COMPATIBILITY_SUPPORT}if lock levels that
-     *            are the same as the desired shall not affect compatibility, or
-     *            finally {@link #COMPATIBILITY_REENTRANT_AND_SUPPORT}which is
-     *            a combination of reentrant and support
-     * 
-     * @param preferred
-     *            in case this lock request is incompatible with existing ones
-     *            and we wait, it shall be granted before other waiting requests
-     *            that are not preferred
-     * @param timeoutMSecs if blocking is enabled by the <code>wait</code> parameter this specifies the maximum wait time in milliseconds
-     * @return <code>true</code> if the lock actually was acquired 
-     * @throws InterruptedException when the thread waiting on this method is interrupted
-     * 
-     */
-    public boolean acquire(Object ownerId, int targetLockLevel, boolean wait, int compatibility,
-            boolean preferred, long timeoutMSecs) throws InterruptedException;
-
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.fulcrum.yaafi.framework.locking;
+
+/**
+ *
+ * Extended multi level lock. Compared to basic {@link MultiLevelLock} allows for more flexible
+ * locking including preference and more compatibility modes.
+ *
+ * @version $Revision: 1.2 $
+ * @see MultiLevelLock
+ * @see GenericLock
+ * @since 1.1
+ */
+public interface MultiLevelLock2 extends MultiLevelLock {
+
+    /**
+     * Compatibility mode: none reentrant. Lock level by the same owner <em>shall</em>
+     * affect compatibility.
+     */
+    public static final int COMPATIBILITY_NONE = 0;
+
+    /**
+     * Compatibility mode: reentrant. Lock level by the same owner <em>shall not</em>
+     * affect compatibility.
+     */
+    public static final int COMPATIBILITY_REENTRANT = 1;
+
+    /**
+     * Compatibility mode: supporting. Lock levels that are the same as the
+     * desired <em>shall not</em> affect compatibility, but lock level held by the same
+     * owner <em>shall</em>.
+     */
+    public static final int COMPATIBILITY_SUPPORT = 2;
+
+    /**
+     * Compatibility mode: reentrant and supporting. Lock levels that are the same as the
+     * desired and lock levels held by the same
+     * owner <em>shall not</em> affect compatibility.
+     */
+    public static final int COMPATIBILITY_REENTRANT_AND_SUPPORT = 3;
+
+    /**
+     * Tests if a certain lock level is owned by an owner.
+     *
+     * @param ownerId
+     *            a unique id identifying the entity that wants to check a
+     *            certain lock level on this lock
+     * @param lockLevel
+     *            the lock level to test
+     * @return <code>true</code> if the lock could be acquired at the time
+     *         this method was called
+     */
+    public boolean has(Object ownerId, int lockLevel);
+
+    /**
+     * Tests if a certain lock level <em>could</em> be acquired. This method
+     * tests only and does <em>not actually acquire</em> the lock.
+     *
+     * @param ownerId
+     *            a unique id identifying the entity that wants to test a
+     *            certain lock level on this lock
+     * @param targetLockLevel
+     *            the lock level to acquire
+     * @param compatibility
+     *            {@link #COMPATIBILITY_NONE}if no additional compatibility is
+     *            desired (same as reentrant set to false) ,
+     *            {@link #COMPATIBILITY_REENTRANT}if lock level by the same
+     *            owner shall not affect compatibility (same as reentrant set to
+     *            true), or {@link #COMPATIBILITY_SUPPORT}if lock levels that
+     *            are the same as the desired shall not affect compatibility, or
+     *            finally {@link #COMPATIBILITY_REENTRANT_AND_SUPPORT}which is
+     *            a combination of reentrant and support
+     * @return <code>true</code> if the lock could be acquired at the time
+     *         this method was called
+     */
+    public boolean test(Object ownerId, int targetLockLevel, int compatibility);
+
+    /**
+     * Tries to acquire a certain lock level on this lock. Does the same as
+     * {@link org.apache.fulcrum.yaafi.framework.locking.MultiLevelLock#acquire(java.lang.Object, int, boolean, boolean, long)}
+     * except that it allows for different compatibility settings. There is an
+     * additional compatibility mode {@link #COMPATIBILITY_SUPPORT}that allows
+     * equal lock levels not to interfere with each other. This is like an
+     * additional shared compatibility and useful when you only want to make
+     * sure not to interfer with lowe levels, but are fine with the same.
+     *
+     * @param ownerId a unique id identifying the entity that wants to acquire a certain lock level on this lock
+     * @param targetLockLevel the lock level to acquire
+     * @param wait <code>true</code> if this method shall block when the desired lock level can not be acquired
+     * @param compatibility
+     *            {@link #COMPATIBILITY_NONE}if no additional compatibility is
+     *            desired (same as reentrant set to false) ,
+     *            {@link #COMPATIBILITY_REENTRANT}if lock level by the same
+     *            owner shall not affect compatibility (same as reentrant set to
+     *            true), or {@link #COMPATIBILITY_SUPPORT}if lock levels that
+     *            are the same as the desired shall not affect compatibility, or
+     *            finally {@link #COMPATIBILITY_REENTRANT_AND_SUPPORT}which is
+     *            a combination of reentrant and support
+     *
+     * @param preferred
+     *            in case this lock request is incompatible with existing ones
+     *            and we wait, it shall be granted before other waiting requests
+     *            that are not preferred
+     * @param timeoutMSecs if blocking is enabled by the <code>wait</code> parameter this specifies the maximum wait time in milliseconds
+     * @return <code>true</code> if the lock actually was acquired
+     * @throws InterruptedException when the thread waiting on this method is interrupted
+     *
+     */
+    public boolean acquire(Object ownerId, int targetLockLevel, boolean wait, int compatibility,
+            boolean preferred, long timeoutMSecs) throws InterruptedException;
+
+}

Modified: jakarta/turbine/fulcrum/trunk/yaafi/src/java/org/apache/fulcrum/yaafi/framework/locking/ReadWriteLock.java
URL: http://svn.apache.org/viewvc/jakarta/turbine/fulcrum/trunk/yaafi/src/java/org/apache/fulcrum/yaafi/framework/locking/ReadWriteLock.java?view=diff&rev=535465&r1=535464&r2=535465
==============================================================================
--- jakarta/turbine/fulcrum/trunk/yaafi/src/java/org/apache/fulcrum/yaafi/framework/locking/ReadWriteLock.java (original)
+++ jakarta/turbine/fulcrum/trunk/yaafi/src/java/org/apache/fulcrum/yaafi/framework/locking/ReadWriteLock.java Fri May  4 23:58:06 2007
@@ -1,104 +1,100 @@
-/*
- * $Header: /usr/local/cvsroot/it20one/service/it20one-service-framework/src/java/org/apache/fulcrum/yaafi/framework/locking/ReadWriteLock.java,v 1.1 2005/09/22 11:04:12 sigi Exp $
- * $Revision: 1.1 $
- * $Date: 2005/09/22 11:04:12 $
- *
- * ====================================================================
- *
- * Copyright 2004 The Apache Software Foundation 
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-package org.apache.fulcrum.yaafi.framework.locking;
-
-
-/**
- * Convenience implementation of a read/write lock based on {@link GenericLock}.
- * <br>
- * <br>
- * Reads are shared which means there can be any number of concurrent read
- * accesses allowed by this lock. Writes are exclusive. This means when there is
- * a write access no other access neither read nor write are allowed by this
- * lock. Additionally, writes are preferred over reads in order to avoid starvation. The idea
- * is that there are many readers, but few writers and if things work out bad the writer would
- * never be served at all. That's why it is preferred.<br>
- * <br>
- * Calls to both {@link #acquireRead(Object, long)}and
- * {@link #acquireWrite(Object, long)}are blocking and reentrant. Blocking
- * means they will wait if they can not acquire the descired access, reentrant means that a lock
- * request by a specific owner will always be compatible with other accesses on this lock by the
- * same owner. E.g. if you already have a lock for writing and you try to acquire write access 
- * again you will not be blocked by this first lock, while others of course will be. This is the
- * natural way you already know from Java monitors and synchronized blocks.
- * 
- * @version $Revision: 1.1 $
- * @see GenericLock
- */
-public class ReadWriteLock extends GenericLock {
-
-    public static final int NO_LOCK = 0;
-
-    public static final int READ_LOCK = 1;
-
-    public static final int WRITE_LOCK = 2;
-
-    /**
-     * Creates a new read/write lock.
-     * 
-     * @param resourceId
-     *            identifier for the resource associated to this lock
-     * @param logger
-     *            generic logger used for all kind of debug logging
-     */
-    public ReadWriteLock(Object resourceId, LoggerFacade logger) {
-        super(resourceId, WRITE_LOCK, logger);
-    }
-
-    /**
-     * Tries to acquire a blocking, reentrant read lock. A read lock is
-     * compatible with other read locks, but not with a write lock.
-     * 
-     * @param ownerId
-     *            a unique id identifying the entity that wants to acquire a
-     *            certain lock level on this lock
-     * @param timeoutMSecs
-     *            if blocking is enabled by the <code>wait</code> parameter
-     *            this specifies the maximum wait time in milliseconds
-     * @return <code>true</code> if the lock actually was acquired
-     * @throws InterruptedException
-     *             when the thread waiting on this method is interrupted
-     */
-    public boolean acquireRead(Object ownerId, long timeoutMSecs) throws InterruptedException {
-        return acquire(ownerId, READ_LOCK, false, timeoutMSecs);
-    }
-
-    /**
-     * Tries to acquire a blocking, reentrant write lock. A write lock is
-     * incompatible with any another read or write lock and is thus exclusive.
-     * 
-     * @param ownerId
-     *            a unique id identifying the entity that wants to acquire a
-     *            certain lock level on this lock
-     * @param timeoutMSecs
-     *            if blocking is enabled by the <code>wait</code> parameter
-     *            this specifies the maximum wait time in milliseconds
-     * @return <code>true</code> if the lock actually was acquired
-     * @throws InterruptedException
-     *             when the thread waiting on this method is interrupted
-     */
-    public boolean acquireWrite(Object ownerId, long timeoutMSecs) throws InterruptedException {
-        return acquire(ownerId, WRITE_LOCK, true, timeoutMSecs);
-    }
-}
\ No newline at end of file
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.fulcrum.yaafi.framework.locking;
+
+
+/**
+ * Convenience implementation of a read/write lock based on {@link GenericLock}.
+ * <br>
+ * <br>
+ * Reads are shared which means there can be any number of concurrent read
+ * accesses allowed by this lock. Writes are exclusive. This means when there is
+ * a write access no other access neither read nor write are allowed by this
+ * lock. Additionally, writes are preferred over reads in order to avoid starvation. The idea
+ * is that there are many readers, but few writers and if things work out bad the writer would
+ * never be served at all. That's why it is preferred.<br>
+ * <br>
+ * Calls to both {@link #acquireRead(Object, long)}and
+ * {@link #acquireWrite(Object, long)}are blocking and reentrant. Blocking
+ * means they will wait if they can not acquire the descired access, reentrant means that a lock
+ * request by a specific owner will always be compatible with other accesses on this lock by the
+ * same owner. E.g. if you already have a lock for writing and you try to acquire write access
+ * again you will not be blocked by this first lock, while others of course will be. This is the
+ * natural way you already know from Java monitors and synchronized blocks.
+ *
+ * @version $Revision: 1.1 $
+ * @see GenericLock
+ */
+public class ReadWriteLock extends GenericLock {
+
+    public static final int NO_LOCK = 0;
+
+    public static final int READ_LOCK = 1;
+
+    public static final int WRITE_LOCK = 2;
+
+    /**
+     * Creates a new read/write lock.
+     *
+     * @param resourceId
+     *            identifier for the resource associated to this lock
+     * @param logger
+     *            generic logger used for all kind of debug logging
+     */
+    public ReadWriteLock(Object resourceId, LoggerFacade logger) {
+        super(resourceId, WRITE_LOCK, logger);
+    }
+
+    /**
+     * Tries to acquire a blocking, reentrant read lock. A read lock is
+     * compatible with other read locks, but not with a write lock.
+     *
+     * @param ownerId
+     *            a unique id identifying the entity that wants to acquire a
+     *            certain lock level on this lock
+     * @param timeoutMSecs
+     *            if blocking is enabled by the <code>wait</code> parameter
+     *            this specifies the maximum wait time in milliseconds
+     * @return <code>true</code> if the lock actually was acquired
+     * @throws InterruptedException
+     *             when the thread waiting on this method is interrupted
+     */
+    public boolean acquireRead(Object ownerId, long timeoutMSecs) throws InterruptedException {
+        return acquire(ownerId, READ_LOCK, false, timeoutMSecs);
+    }
+
+    /**
+     * Tries to acquire a blocking, reentrant write lock. A write lock is
+     * incompatible with any another read or write lock and is thus exclusive.
+     *
+     * @param ownerId
+     *            a unique id identifying the entity that wants to acquire a
+     *            certain lock level on this lock
+     * @param timeoutMSecs
+     *            if blocking is enabled by the <code>wait</code> parameter
+     *            this specifies the maximum wait time in milliseconds
+     * @return <code>true</code> if the lock actually was acquired
+     * @throws InterruptedException
+     *             when the thread waiting on this method is interrupted
+     */
+    public boolean acquireWrite(Object ownerId, long timeoutMSecs) throws InterruptedException {
+        return acquire(ownerId, WRITE_LOCK, true, timeoutMSecs);
+    }
+}



---------------------------------------------------------------------
To unsubscribe, e-mail: turbine-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: turbine-dev-help@jakarta.apache.org