45 |
|
*/ |
46 |
|
|
47 |
|
/** |
48 |
< |
* The run state of this task, initially UNDECIDED. The run state |
48 |
> |
* The run state of this task, initially NEW. The run state |
49 |
|
* transitions to a terminal state only in method setCompletion. |
50 |
|
* During setCompletion, state may take on transient values of |
51 |
|
* COMPLETING (while outcome is being set) or INTERRUPTING (only |
53 |
|
* State values are highly order-dependent to simplify checks. |
54 |
|
* |
55 |
|
* Possible state transitions: |
56 |
< |
* UNDECIDED -> NORMAL |
57 |
< |
* UNDECIDED -> COMPLETING -> NORMAL |
58 |
< |
* UNDECIDED -> COMPLETING -> EXCEPTIONAL |
59 |
< |
* UNDECIDED -> CANCELLED |
60 |
< |
* UNDECIDED -> INTERRUPTING -> INTERRUPTED |
56 |
> |
* NEW -> NORMAL |
57 |
> |
* NEW -> COMPLETING -> NORMAL |
58 |
> |
* NEW -> COMPLETING -> EXCEPTIONAL |
59 |
> |
* NEW -> CANCELLED |
60 |
> |
* NEW -> INTERRUPTING -> INTERRUPTED |
61 |
|
*/ |
62 |
|
private volatile int state; |
63 |
< |
private static final int UNDECIDED = 0; |
63 |
> |
private static final int NEW = 0; |
64 |
|
private static final int COMPLETING = 1; |
65 |
|
private static final int NORMAL = 2; |
66 |
|
private static final int EXCEPTIONAL = 3; |
84 |
|
* |
85 |
|
* @param x the outcome |
86 |
|
* @param mode the completion state value |
87 |
< |
* @return true if this call caused transition from UNDECIDED to completed |
87 |
> |
* @return true if this call caused transition from NEW to completed |
88 |
|
*/ |
89 |
|
private boolean setCompletion(Object x, int mode) { |
90 |
|
// set up transient states |
91 |
|
int next = (x != null) ? COMPLETING : mode; |
92 |
< |
if (!UNSAFE.compareAndSwapInt(this, stateOffset, UNDECIDED, next)) |
92 |
> |
if (!UNSAFE.compareAndSwapInt(this, stateOffset, NEW, next)) |
93 |
|
return false; |
94 |
|
if (next == INTERRUPTING) { |
95 |
|
// Must check after CAS to avoid missed interrupt |
156 |
|
} |
157 |
|
|
158 |
|
public boolean isDone() { |
159 |
< |
return state != UNDECIDED; |
159 |
> |
return state != NEW; |
160 |
|
} |
161 |
|
|
162 |
|
public boolean cancel(boolean mayInterruptIfRunning) { |
163 |
< |
return state == UNDECIDED && |
163 |
> |
return state == NEW && |
164 |
|
setCompletion(null, |
165 |
|
mayInterruptIfRunning ? INTERRUPTING : CANCELLED); |
166 |
|
} |
226 |
|
} |
227 |
|
|
228 |
|
public void run() { |
229 |
< |
if (state != UNDECIDED || |
229 |
> |
if (state != NEW || |
230 |
|
!UNSAFE.compareAndSwapObject(this, runnerOffset, |
231 |
|
null, Thread.currentThread())) |
232 |
|
return; |
233 |
|
|
234 |
|
try { |
235 |
|
// Recheck to avoid missed interrupt. |
236 |
< |
if (state != UNDECIDED) |
236 |
> |
if (state != NEW) |
237 |
|
return; |
238 |
|
V result; |
239 |
|
try { |
264 |
|
* @return true if successfully run and reset |
265 |
|
*/ |
266 |
|
protected boolean runAndReset() { |
267 |
< |
if (state != UNDECIDED || |
267 |
> |
if (state != NEW || |
268 |
|
!UNSAFE.compareAndSwapObject(this, runnerOffset, |
269 |
|
null, Thread.currentThread())) |
270 |
|
return false; |
271 |
|
|
272 |
|
try { |
273 |
|
// Recheck to avoid missed interrupt. |
274 |
< |
if (state != UNDECIDED) |
274 |
> |
if (state != NEW) |
275 |
|
return false; |
276 |
|
try { |
277 |
|
callable.call(); // don't set result |
278 |
< |
return (state == UNDECIDED); |
278 |
> |
return (state == NEW); |
279 |
|
} catch (Throwable ex) { |
280 |
|
setException(ex); |
281 |
|
return false; |