1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.waarp.common.future;
21
22 import org.waarp.common.logging.SysErrLogger;
23
24 import java.util.concurrent.TimeUnit;
25
26 import static java.util.concurrent.TimeUnit.*;
27
28
29
30
31
32
33 public class WaarpFuture implements WaarpFutureInterface {
34 private static final Throwable CANCELLED = new Throwable();
35
36 private final boolean cancellable;
37
38 private volatile boolean done;
39
40 private Throwable cause;
41
42 private int waiters;
43
44
45
46
47 public WaarpFuture() {
48 cancellable = false;
49 }
50
51
52
53
54
55
56
57 public WaarpFuture(final boolean cancellable) {
58 this.cancellable = cancellable;
59 }
60
61
62
63
64
65
66
67
68
69 @Override
70 public final boolean isDone() {
71 return done;
72 }
73
74
75
76
77
78
79
80 @Override
81 public final boolean isSuccess() {
82 return done && cause == null;
83 }
84
85
86
87
88
89
90
91 @Override
92 public final boolean isFailed() {
93 return done && cause != null;
94 }
95
96
97
98
99
100
101
102
103 @Override
104 public final Throwable getCause() {
105 if (cause != CANCELLED) {
106 return cause;
107 }
108 return null;
109 }
110
111
112
113
114
115
116
117 @Override
118 public final boolean isCancelled() {
119 return done && cause == CANCELLED;
120 }
121
122
123
124
125
126 @Override
127 public final WaarpFuture rethrowIfFailed() throws Exception {
128 if (!isDone()) {
129 return this;
130 }
131
132 final Throwable causeNew = getCause();
133 if (causeNew == null) {
134 return this;
135 }
136
137 if (causeNew instanceof Exception) {
138 throw (Exception) causeNew;
139 }
140
141 if (causeNew instanceof Error) {
142 throw (Error) causeNew;
143 }
144
145 throw new RuntimeException(causeNew);
146 }
147
148
149
150
151 @Override
152 public final boolean awaitOrInterruptible() {
153 while (!Thread.interrupted()) {
154 if (awaitOrInterruptible(1, SECONDS)) {
155 return true;
156 }
157 }
158 return false;
159 }
160
161
162
163
164
165
166 @Override
167 public final boolean awaitOrInterruptible(final long timeoutMilliseconds) {
168 return awaitOrInterruptible(MILLISECONDS.toNanos(timeoutMilliseconds),
169 false);
170 }
171
172
173
174
175
176
177
178 @Override
179 public final boolean awaitOrInterruptible(final long timeout,
180 final TimeUnit unit) {
181 return awaitOrInterruptible(unit.toNanos(timeout), false);
182 }
183
184
185
186
187
188
189
190 private boolean awaitOrInterruptible(final long timeoutNanos,
191 final boolean interruptable) {
192 try {
193 if (await0(timeoutNanos, interruptable) && !Thread.interrupted()) {
194 return true;
195 }
196 } catch (final InterruptedException e) {
197 SysErrLogger.FAKE_LOGGER.ignoreLog(e);
198 }
199 return false;
200 }
201
202 private boolean await0(final long timeoutNanos, final boolean interruptable)
203 throws InterruptedException {
204 if (done) {
205 return done;
206 }
207 if (timeoutNanos <= 0) {
208 return done;
209 }
210 if (interruptable && Thread.interrupted()) {
211 throw new InterruptedException();
212 }
213
214 final long startTime = System.nanoTime();
215 long waitTime = timeoutNanos;
216 boolean interrupted = false;
217
218 try {
219 for (; ; ) {
220 synchronized (this) {
221 if (done) {
222 return done;
223 }
224 waiters++;
225
226 try {
227 wait(waitTime / 1000000, (int) (waitTime % 1000000));
228 } catch (final InterruptedException e) {
229 SysErrLogger.FAKE_LOGGER.ignoreLog(e);
230 if (interruptable) {
231 throw e;
232 } else {
233 interrupted = true;
234 }
235 } finally {
236 waiters--;
237 }
238 }
239 if (done) {
240 return true;
241 }
242 waitTime = timeoutNanos - (System.nanoTime() - startTime);
243 if (waitTime <= 0) {
244 return done;
245 }
246 }
247 } finally {
248 if (interrupted) {
249 Thread.currentThread().interrupt();
250 }
251 }
252 }
253
254
255
256
257
258
259
260
261
262 @Override
263 public final boolean setSuccess() {
264 synchronized (this) {
265
266 if (done) {
267 return false;
268 }
269
270 done = true;
271 if (waiters > 0) {
272 notifyAll();
273 }
274 }
275 return true;
276 }
277
278
279
280
281
282
283
284
285
286
287
288 @Override
289 public final boolean setFailure(final Throwable cause) {
290 synchronized (this) {
291
292 if (done) {
293 return false;
294 }
295
296 this.cause = cause;
297 done = true;
298 if (waiters > 0) {
299 notifyAll();
300 }
301 }
302 return true;
303 }
304
305
306
307
308
309
310
311
312
313
314 @Override
315 public final boolean cancel() {
316 if (!cancellable) {
317 return false;
318 }
319 synchronized (this) {
320
321 if (done) {
322 return false;
323 }
324
325 cause = CANCELLED;
326 done = true;
327 if (waiters > 0) {
328 notifyAll();
329 }
330 }
331 return true;
332 }
333
334
335
336
337 @Override
338 public final void reset() {
339 synchronized (this) {
340 done = false;
341 cause = null;
342 }
343 }
344 }