1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 package org.apache.http.concurrent;
28
29 import java.util.concurrent.ExecutionException;
30 import java.util.concurrent.Future;
31 import java.util.concurrent.TimeUnit;
32 import java.util.concurrent.TimeoutException;
33
34
35
36
37
38
39
40
41
42 public class BasicFuture<T> implements Future<T>, Cancellable {
43
44 private final FutureCallback<T> callback;
45
46 private volatile boolean completed;
47 private volatile boolean cancelled;
48 private volatile T result;
49 private volatile Exception ex;
50
51 public BasicFuture(final FutureCallback<T> callback) {
52 super();
53 this.callback = callback;
54 }
55
56 public boolean isCancelled() {
57 return this.cancelled;
58 }
59
60 public boolean isDone() {
61 return this.completed;
62 }
63
64 private T getResult() throws ExecutionException {
65 if (this.ex != null) {
66 throw new ExecutionException(this.ex);
67 }
68 return this.result;
69 }
70
71 public synchronized T get() throws InterruptedException, ExecutionException {
72 while (!this.completed) {
73 wait();
74 }
75 return getResult();
76 }
77
78 public synchronized T get(final long timeout, final TimeUnit unit)
79 throws InterruptedException, ExecutionException, TimeoutException {
80 final long msecs = unit.toMillis(timeout);
81 final long startTime = (msecs <= 0) ? 0 : System.currentTimeMillis();
82 long waitTime = msecs;
83 if (this.completed) {
84 return getResult();
85 } else if (waitTime <= 0) {
86 throw new TimeoutException();
87 } else {
88 for (;;) {
89 wait(waitTime);
90 if (this.completed) {
91 return getResult();
92 } else {
93 waitTime = msecs - (System.currentTimeMillis() - startTime);
94 if (waitTime <= 0) {
95 throw new TimeoutException();
96 }
97 }
98 }
99 }
100 }
101
102 public boolean completed(final T result) {
103 synchronized(this) {
104 if (this.completed) {
105 return false;
106 }
107 this.completed = true;
108 this.result = result;
109 notifyAll();
110 }
111 if (this.callback != null) {
112 this.callback.completed(result);
113 }
114 return true;
115 }
116
117 public boolean failed(final Exception exception) {
118 synchronized(this) {
119 if (this.completed) {
120 return false;
121 }
122 this.completed = true;
123 this.ex = exception;
124 notifyAll();
125 }
126 if (this.callback != null) {
127 this.callback.failed(exception);
128 }
129 return true;
130 }
131
132 public boolean cancel(final boolean mayInterruptIfRunning) {
133 synchronized(this) {
134 if (this.completed) {
135 return false;
136 }
137 this.completed = true;
138 this.cancelled = true;
139 notifyAll();
140 }
141 if (this.callback != null) {
142 this.callback.cancelled();
143 }
144 return true;
145 }
146
147 public boolean cancel() {
148 return cancel(true);
149 }
150
151 }