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
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35 public class LockGrantFuture<LockType> implements Future<LockGrant<LockType>> {
36
37
38
39 private LockRequest<LockType> m_request;
40
41
42
43
44 private Target<LockType> m_target;
45
46
47
48
49
50 private LockGrant<LockType> m_grant;
51
52
53
54
55 private LockGrantFuture<LockType> m_predecessor_future;
56
57
58
59
60 private LockGrantFuture<LockType> m_successor_future;
61
62
63
64
65 private boolean m_cancelled;
66
67
68
69
70
71
72
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
151
152 if (pf != null) {
153 pf.get(timeout, unit);
154 }
155
156
157
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
180
181
182
183 synchronized LockGrant<LockType> get_now() {
184 Ensure.not_null(m_grant, "m_grant == null");
185 return m_grant;
186 }
187
188
189
190
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
199
200
201
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
218
219 void cancelled() {
220
221
222
223
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
255
256
257 public synchronized Target<LockType> target() {
258 return m_target;
259 }
260
261
262
263
264
265 public synchronized LockRequest<LockType> request() {
266 return m_request;
267 }
268
269
270
271
272
273 synchronized LockGrantFuture<LockType> successor_future() {
274 return m_successor_future;
275 }
276
277
278
279
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 }