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 org.apache.http.util.Args;
30
31 import java.util.concurrent.CancellationException;
32 import java.util.concurrent.ExecutionException;
33 import java.util.concurrent.Future;
34 import java.util.concurrent.TimeUnit;
35 import java.util.concurrent.TimeoutException;
36
37
38
39
40
41
42
43
44
45 public class BasicFuture<T> implements Future<T>, Cancellable {
46
47 private final FutureCallback<T> callback;
48
49 private volatile boolean completed;
50 private volatile boolean cancelled;
51 private volatile T result;
52 private volatile Exception ex;
53
54 public BasicFuture(final FutureCallback<T> callback) {
55 super();
56 this.callback = callback;
57 }
58
59 @Override
60 public boolean isCancelled() {
61 return this.cancelled;
62 }
63
64 @Override
65 public boolean isDone() {
66 return this.completed;
67 }
68
69 private T getResult() throws ExecutionException {
70 if (this.ex != null) {
71 throw new ExecutionException(this.ex);
72 }
73 if (cancelled) {
74 throw new CancellationException();
75 }
76 return this.result;
77 }
78
79 @Override
80 public synchronized T get() throws InterruptedException, ExecutionException {
81 while (!this.completed) {
82 wait();
83 }
84 return getResult();
85 }
86
87 @Override
88 public synchronized T get(final long timeout, final TimeUnit unit)
89 throws InterruptedException, ExecutionException, TimeoutException {
90 Args.notNull(unit, "Time unit");
91 final long msecs = unit.toMillis(timeout);
92 final long startTime = (msecs <= 0) ? 0 : System.currentTimeMillis();
93 long waitTime = msecs;
94 if (this.completed) {
95 return getResult();
96 } else if (waitTime <= 0) {
97 throw new TimeoutException();
98 } else {
99 for (;;) {
100 wait(waitTime);
101 if (this.completed) {
102 return getResult();
103 }
104 waitTime = msecs - (System.currentTimeMillis() - startTime);
105 if (waitTime <= 0) {
106 throw new TimeoutException();
107 }
108 }
109 }
110 }
111
112 public boolean completed(final T result) {
113 synchronized(this) {
114 if (this.completed) {
115 return false;
116 }
117 this.completed = true;
118 this.result = result;
119 notifyAll();
120 }
121 if (this.callback != null) {
122 this.callback.completed(result);
123 }
124 return true;
125 }
126
127 public boolean failed(final Exception exception) {
128 synchronized(this) {
129 if (this.completed) {
130 return false;
131 }
132 this.completed = true;
133 this.ex = exception;
134 notifyAll();
135 }
136 if (this.callback != null) {
137 this.callback.failed(exception);
138 }
139 return true;
140 }
141
142 @Override
143 public boolean cancel(final boolean mayInterruptIfRunning) {
144 synchronized(this) {
145 if (this.completed) {
146 return false;
147 }
148 this.completed = true;
149 this.cancelled = true;
150 notifyAll();
151 }
152 if (this.callback != null) {
153 this.callback.cancelled();
154 }
155 return true;
156 }
157
158 @Override
159 public boolean cancel() {
160 return cancel(true);
161 }
162
163 }