View Javadoc

1   /*
2   Wotonomy: OpenStep design patterns for pure Java applications.
3   Copyright (C) 2002 Israfil consulting Services Corporation
4   
5   This library is free software; you can redistribute it and/or
6   modify it under the terms of the GNU Lesser General Public
7   License as published by the Free Software Foundation; either
8   version 2.1 of the License, or (at your option) any later version.
9   
10  This library is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  Lesser General Public License for more details.
14  
15  You should have received a copy of the GNU Lesser General Public
16  License along with this library; if not, see http://www.gnu.org
17  
18  $Id: NSRecursiveLock.java 893 2006-02-16 13:22:23 +0000 (Thu, 16 Feb 2006) cgruber $
19  
20  */
21  
22  package net.wotonomy.foundation;
23  
24  import EDU.oswego.cs.dl.util.concurrent.ReentrantLock;
25  
26  /***
27  * A lock class that allows a thread to re-acquire it's lock 
28  * recursively.  Currently an API-compliance wrapper around Doug Lea's 
29  * ReentrantLock, conforming to the API and behavior of 
30  * com.webobjects.foundation.NSRecursiveLock.
31  *
32  * @author cgruber@israfil.net
33  * @author $Author: cgruber $
34  * @version $Revision: 893 $
35  */
36  
37  public class NSRecursiveLock extends ReentrantLock implements NSLocking {
38  
39      public NSRecursiveLock() {
40      }
41      /*** Acquire the lock, catching the thrown exception to mirror the
42       *  behavior of com.webobjects.foundation.NSRecursiveLock.  Note that
43       *  ReentrantLock.acquire() performs a notify() when it's interrupted.
44       *  
45       *  @see edu.oswego.cs.dl.util.concurrent.ReentrantLock#acquire()
46       */
47      public void lock() {
48         try {
49              acquire();
50          } catch (InterruptedException interruptedexception) {
51              // Null behavior, as notify() is already called
52              // by acquire();            
53              // We may want to log here.  
54          }
55      }
56  
57      /*** Pass the buck to tryLock(long), passing zero time as the parameter.
58       * 
59       *  @see #tryLock(long)
60       */
61      public boolean tryLock() {
62          return tryLock(1);
63      }
64  
65      /*** Attempt to acquire the lock, catching the thrown exception to mirror 
66       *  the behavior of com.webobjects.foundation.NSRecursiveLock.  Note that
67       *  ReentrantLock.attempt(*) performs a notify() when it's interrupted.
68       *  Fail gracefully after the given milliseconds
69       *  
70       *  @param (long) 
71       *  @see edu.oswego.cs.dl.util.concurrent.ReentrantLock#acquire()
72       */
73      public boolean tryLock(long milliseconds) {
74          try {
75              return attempt(milliseconds);
76          } catch (InterruptedException interruptedexception) {
77              // notify() is already called by attempt();
78              // We may want to log here.  
79              return false;
80          }
81      }
82      /***
83       *  Attempt to acquire a lock until the timestamp is reached. Add 
84       *  1 to the recursion count if the calling thread already owns the
85       *  lock.  Otherwise block until free or until the given timestamp 
86       *  is reached.
87       * 
88       *  @see Timestamp
89       *  @see ReentrantLock.attempt(long);
90       */
91      public boolean tryLock(NSTimestamp nstimestamp) {
92          return tryLock(nstimestamp.getTime() - System.currentTimeMillis());
93      }
94  
95      /*** Unlock the current lock precisely once.
96       */
97      public synchronized void unlock() {
98          unlock(1);
99      }
100 
101     /*** Unlock the current lock count times.
102      */
103     public synchronized void unlock(long count) {
104         if (owner_ != null && Thread.currentThread() != owner_)
105             throw new IllegalStateException("Illegal Lock usage: unlocking thread not owner.");
106         if (owner_ == null || holds_ == 0L)
107             throw new IllegalStateException("Illegal Lock usage: unlock() called without a lock().");
108 		release(count);
109     }
110 
111     public synchronized long recursionCount() {
112 		return holds();
113     }
114 
115     public String toString() {
116         long holds = holds();
117         boolean oneHold = (holds == 1);
118         boolean noHolds = (holds < 1 || owner_ == null);
119         return getClass().getName() + " <" + 
120         ((noHolds) ? "Unlocked" : ( "Locked " + holds + " time" + (oneHold ? "" : "s") + " by " + owner_ ) ) + ">";
121     }
122 
123 }
124 /*
125  * $Log$
126  * Revision 1.2  2006/02/16 13:15:00  cgruber
127  * Check in all sources in eclipse-friendly maven-enabled packages.
128  *
129  * Revision 1.1  2002/07/14 21:56:16  mpowers
130  * Contributions from cgruber.
131  *
132  * Revision 1.5  2002/06/25 19:02:19  cgruber
133  * I'm a dumbass.
134  *
135  * Revision 1.4  2002/06/25 18:52:56  cgruber
136  * Fix javadocs that resulted from bad cut-and-paste of the boilerplate.
137  *
138  * Revision 1.3  2002/06/25 18:45:27  cgruber
139  * Add some javadocs.
140  *
141  * Revision 1.2  2002/06/25 18:06:48  cgruber
142  * Add implementation of NSRecursiveLock using Doug Lea's concurrent programming APIs. 
143  * Specifically inherit from ReentrantLock, which magically does the exact job we want!
144  *
145  * Revision 1.1  2002/06/25 07:52:56  cgruber
146  * 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.
147  *
148  */