View Javadoc
1   package locklib;
2   
3   
4   import java.util.concurrent.ExecutionException;
5   import java.util.concurrent.Future;
6   import java.util.concurrent.TimeUnit;
7   import java.util.concurrent.TimeoutException;
8   
9   import ensure.Ensure;
10  
11  /**
12   * <p>Future representing a request for a lock grant. This future object is
13   * created when requesting a lock on a target. A {@link LockGrantFuture} is
14   * an asynchronous request for a lock grant. A synchronous wait can be done
15   * invoking the {@link #get()} or the {@link #get(long, TimeUnit)} methods.</p>
16   * 
17   * <p>Lock grant futures can be cancelled. Cancelling a lock grant future
18   * will release any partial locks already acquired. It will not release the
19   * lock if it has already been acquired.</p>
20   * 
21   * <p>Synchronization locks on <code>LockGrantFuture</code> should never be
22   * made outside <em>locklib</em></p>.
23   * 
24   * @param <LockType> the type of lock
25   */
26  /*
27   * Implementation notes:
28   * 
29   * LockGrantFutures are chained just like the LockGrant.
30   * 
31   * The LockGrantFutures only acquire locks on themselves, their own LockGrants
32   * and other LockGrantFutures in the lock chain. LockGrantFutures are always
33   * locked *before* their predecessors.
34   */
35  public class LockGrantFuture<LockType> implements Future<LockGrant<LockType>> {
36  	/**
37  	 * The lock requested.
38  	 */
39  	private LockRequest<LockType> m_request;
40  	
41  	/**
42  	 * The target of the lock.
43  	 */
44  	private Target<LockType> m_target;
45  	
46  	/**
47  	 * The lock grant, <code>null</code> if the lock has not yet been granted
48  	 * or if the future has been canceled.
49  	 */
50  	private LockGrant<LockType> m_grant;
51  	
52  	/**
53  	 * Future granting the predecessor lock, if any.
54  	 */
55  	private LockGrantFuture<LockType> m_predecessor_future;
56  	
57  	/**
58  	 * Future granting the successor lock, if any.
59  	 */
60  	private LockGrantFuture<LockType> m_successor_future;
61  	
62  	/**
63  	 * Has the lock been cancelled?
64  	 */
65  	private boolean m_cancelled;
66  	
67  	/**
68  	 * Creates a future for a lock that will eventually be granted (or not!)
69  	 * @param request the lock type requested
70  	 * @param target the target where the lock was requested
71  	 * @param predecessor_future an optional future representing the
72  	 * acquisition of the predecessor lock
73  	 */
74  	LockGrantFuture(LockRequest<LockType> request, Target<LockType> target,
75  			LockGrantFuture<LockType> predecessor_future) {
76  		Ensure.not_null(request, "request == null");
77  		Ensure.not_null(target, "target == null");
78  		
79  		m_request = request;
80  		m_target = target;
81  		m_grant = null;
82  		m_predecessor_future = predecessor_future;
83  		m_successor_future = null;
84  		if (predecessor_future != null) {
85  			synchronized (predecessor_future) {
86  				Ensure.is_null(predecessor_future.m_successor_future,
87  						"predecessor_future.m_successor_future != null");
88  				Ensure.is_false(predecessor_future.m_cancelled,
89  						"predecessor_future.m_cancelled");
90  				predecessor_future.m_successor_future = this;
91  			}
92  		}
93  	}
94  
95  	@Override
96  	public boolean cancel(boolean mayInterruptIfRunning) {
97  		boolean c = m_target.cancel(this);
98  		synchronized (this) {
99  			if (c) {
100 				Ensure.is_true(m_cancelled, "!m_cancelled");
101 				Ensure.is_null(m_grant, "m_grant != null");
102 			} else {
103 				Ensure.is_false(m_cancelled, "m_cancelled");
104 				Ensure.not_null(m_grant, "m_grant == null");
105 			}
106 		}
107 		
108 		return c;
109 	}
110 
111 	@Override
112 	public synchronized boolean isCancelled() {
113 		return m_cancelled;
114 	}
115 
116 	@Override
117 	public synchronized boolean isDone() {
118 		return (m_grant != null) || m_cancelled;
119 	}
120 
121 	@Override
122 	public LockGrant<LockType> get() throws InterruptedException,
123 			ExecutionException {
124 		try {
125 			return get(0, TimeUnit.MILLISECONDS);
126 		} catch (TimeoutException e) {
127 			Ensure.never_thrown(e);
128 			return null;
129 		}
130 	}
131 
132 	@Override
133 	public LockGrant<LockType> get(long timeout, TimeUnit unit)
134 			throws InterruptedException, ExecutionException, TimeoutException {
135 		Ensure.greater_equal(timeout, 0, "timeout < 0");
136 		Ensure.not_null(unit, "unit == null");
137 		
138 		long limit = System.currentTimeMillis() + unit.toMillis(timeout);
139 		if (timeout == 0) {
140 			limit = Long.MAX_VALUE;
141 		}
142 		
143 		long now;
144 		LockGrantFuture<LockType> pf;
145 		synchronized (this) {
146 			pf = m_predecessor_future;
147 		}
148 		
149 		/*
150 		 * First we must wait for the predecessor lock to be acquired.
151 		 */
152 		if (pf != null) {
153 			pf.get(timeout, unit);
154 		}
155 		
156 		/*
157 		 * Then we must wait for the lock to be granted.
158 		 */
159 		synchronized (this) {
160 			while (m_grant == null
161 					&& (now = System.currentTimeMillis()) < limit) {
162 				if (m_cancelled) {
163 					throw new LockCancelledException("Locked has been "
164 							+ "cancelled.");
165 				}
166 				
167 				wait(limit - now);
168 			}
169 			
170 			if (m_grant == null) {
171 				throw new TimeoutException();
172 			}
173 			
174 			return m_grant;
175 		}
176 	}
177 	
178 	/**
179 	 * Obtains the grant. This method can only be invoked if we know that the
180 	 * grant has been acquired.
181 	 * @return the grant
182 	 */
183 	synchronized LockGrant<LockType> get_now() {
184 		Ensure.not_null(m_grant, "m_grant == null");
185 		return m_grant;
186 	}
187 	
188 	/**
189 	 * Marks the future as complete.
190 	 * @param grant the lock acquired
191 	 */
192 	synchronized void acquired(LockGrant<LockType> grant) {
193 		Ensure.not_null(grant, "grant == null");
194 		Ensure.is_null(m_grant, "m_grant != null");
195 		Ensure.is_false(m_cancelled, "m_cancelled");
196 		
197 		/*
198 		 * For safety, we want to ensure that if we have a predecessor lock,
199 		 * it has been acquired already. Note that we must have our
200 		 * synchronized lock acquired before the predecessor's synchronization
201 		 * lock is acquired.
202 		 */
203 		if (m_predecessor_future != null) {
204 			synchronized (m_predecessor_future) {
205 				Ensure.not_null(m_predecessor_future.m_grant,
206 						"m_predecessor_future.m_grant == null");
207 				Ensure.is_false(m_predecessor_future.m_cancelled,
208 						"m_predecessor_future.m_cancelled");
209 			}
210 		}
211 		
212 		m_grant = grant;
213 		notifyAll();
214 	}
215 	
216 	/**
217 	 * Marks the future as canceled.
218 	 */
219 	void cancelled() {
220 		/*
221 		 * For safety, we want to ensure that if we have a successor lock,
222 		 * it has been cancelled already. Note that we must have the
223 		 * successor's synchronization lock acquired before our own.
224 		 */
225 		LockGrantFuture<LockType> suc = null;
226 		synchronized (this) {
227 			suc = m_successor_future;
228 		}
229 		
230 		if (suc != null) {
231 			synchronized (suc) {
232 				Ensure.is_null(suc.m_grant, "suc.m_grant != null");
233 				Ensure.is_true(suc.m_cancelled, "!suc.m_cancelled");
234 				synchronized (this) {
235 					Ensure.is_null(m_grant, "m_grant != null");
236 					Ensure.is_false(m_cancelled, "m_cancelled");
237 					
238 					m_cancelled = true;
239 					notifyAll();
240 				}
241 			}
242 		} else {
243 			synchronized (this) {
244 				Ensure.is_null(m_grant, "m_grant != null");
245 				Ensure.is_false(m_cancelled, "m_cancelled");
246 				
247 				m_cancelled = true;
248 				notifyAll();
249 			}
250 		}
251 	}
252 	
253 	/**
254 	 * Obtains the target of the lock.
255 	 * @return the target
256 	 */
257 	public synchronized Target<LockType> target() {
258 		return m_target;
259 	}
260 	
261 	/**
262 	 * Obtains the lock request.
263 	 * @return the lock request
264 	 */
265 	public synchronized LockRequest<LockType> request() {
266 		return m_request;
267 	}
268 	
269 	/**
270 	 * Obtains the successor future that should be acquired after this one.
271 	 * @return the successor future or <code>null</code> if none
272 	 */
273 	synchronized LockGrantFuture<LockType> successor_future() {
274 		return m_successor_future;
275 	}
276 	
277 	/**
278 	 * Obtains the predecessor future that should be acquired before this one.
279 	 * @return the predecessor future or <code>null</code> if none
280 	 */
281 	LockGrantFuture<LockType> predecessor_future() {
282 		return m_predecessor_future;
283 	}
284 	
285 	@Override
286 	public synchronized String toString() {
287 		return "LockGrantFuture[request=" + m_request + ", granted?" +
288 				(m_grant == null? "false" : "true") + ", predecessor="
289 				+ m_predecessor_future + ", cancelled=" + m_cancelled + "]";
290 	}
291 }