/* Wotonomy: OpenStep design patterns for pure Java applications. Copyright (C) 2002 Israfil consulting Services Corporation This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see http://www.gnu.org $Id: NSRecursiveLock.java 893 2006-02-16 13:22:23Z cgruber $ */ package net.wotonomy.foundation; import EDU.oswego.cs.dl.util.concurrent.ReentrantLock; /** * A lock class that allows a thread to re-acquire it's lock * recursively. Currently an API-compliance wrapper around Doug Lea's * ReentrantLock, conforming to the API and behavior of * com.webobjects.foundation.NSRecursiveLock. * * @author cgruber@israfil.net * @author $Author: cgruber $ * @version $Revision: 893 $ */ public class NSRecursiveLock extends ReentrantLock implements NSLocking { public NSRecursiveLock() { } /** Acquire the lock, catching the thrown exception to mirror the * behavior of com.webobjects.foundation.NSRecursiveLock. Note that * ReentrantLock.acquire() performs a notify() when it's interrupted. * * @see edu.oswego.cs.dl.util.concurrent.ReentrantLock#acquire() */ public void lock() { try { acquire(); } catch (InterruptedException interruptedexception) { // Null behavior, as notify() is already called // by acquire(); // We may want to log here. } } /** Pass the buck to tryLock(long), passing zero time as the parameter. * * @see #tryLock(long) */ public boolean tryLock() { return tryLock(1); } /** Attempt to acquire the lock, catching the thrown exception to mirror * the behavior of com.webobjects.foundation.NSRecursiveLock. Note that * ReentrantLock.attempt(*) performs a notify() when it's interrupted. * Fail gracefully after the given milliseconds * * @param (long) * @see edu.oswego.cs.dl.util.concurrent.ReentrantLock#acquire() */ public boolean tryLock(long milliseconds) { try { return attempt(milliseconds); } catch (InterruptedException interruptedexception) { // notify() is already called by attempt(); // We may want to log here. return false; } } /** * Attempt to acquire a lock until the timestamp is reached. Add * 1 to the recursion count if the calling thread already owns the * lock. Otherwise block until free or until the given timestamp * is reached. * * @see Timestamp * @see ReentrantLock.attempt(long); */ public boolean tryLock(NSTimestamp nstimestamp) { return tryLock(nstimestamp.getTime() - System.currentTimeMillis()); } /** Unlock the current lock precisely once. */ public synchronized void unlock() { unlock(1); } /** Unlock the current lock count times. */ public synchronized void unlock(long count) { if (owner_ != null && Thread.currentThread() != owner_) throw new IllegalStateException("Illegal Lock usage: unlocking thread not owner."); if (owner_ == null || holds_ == 0L) throw new IllegalStateException("Illegal Lock usage: unlock() called without a lock()."); release(count); } public synchronized long recursionCount() { return holds(); } public String toString() { long holds = holds(); boolean oneHold = (holds == 1); boolean noHolds = (holds < 1 || owner_ == null); return getClass().getName() + " <" + ((noHolds) ? "Unlocked" : ( "Locked " + holds + " time" + (oneHold ? "" : "s") + " by " + owner_ ) ) + ">"; } } /* * $Log$ * Revision 1.2 2006/02/16 13:15:00 cgruber * Check in all sources in eclipse-friendly maven-enabled packages. * * Revision 1.1 2002/07/14 21:56:16 mpowers * Contributions from cgruber. * * Revision 1.5 2002/06/25 19:02:19 cgruber * I'm a dumbass. * * Revision 1.4 2002/06/25 18:52:56 cgruber * Fix javadocs that resulted from bad cut-and-paste of the boilerplate. * * Revision 1.3 2002/06/25 18:45:27 cgruber * Add some javadocs. * * Revision 1.2 2002/06/25 18:06:48 cgruber * Add implementation of NSRecursiveLock using Doug Lea's concurrent programming APIs. * Specifically inherit from ReentrantLock, which magically does the exact job we want! * * Revision 1.1 2002/06/25 07:52:56 cgruber * Add quite a few abstract classes, interfaces, and classes. All API consistent with WebObjects, but with no implementation, nor any private or package access members from the original. * */