19 |
|
import java.util.concurrent.ExecutionException; |
20 |
|
import java.util.concurrent.TimeoutException; |
21 |
|
import java.util.concurrent.CancellationException; |
22 |
+ |
import java.util.concurrent.CompletionException; |
23 |
|
import java.util.concurrent.atomic.AtomicInteger; |
24 |
|
import java.util.concurrent.locks.LockSupport; |
25 |
|
|
39 |
|
* |
40 |
|
* <p>When two or more threads attempt to {@link #complete} or {@link |
41 |
|
* #completeExceptionally} a CompletableFuture, only one of them |
42 |
< |
* succeeds. Upon exceptional completion, or when a completion entails |
42 |
> |
* succeeds. |
43 |
> |
* |
44 |
> |
* <p> Upon exceptional completion, or when a completion entails |
45 |
|
* computation of a function or action, and it terminates abruptly |
46 |
< |
* with an exception, then further completions act as {@code |
47 |
< |
* completeExceptionally} with that exception. |
46 |
> |
* with an (unchecked) exception or error, then further completions |
47 |
> |
* act as {@code completeExceptionally} with a {@link |
48 |
> |
* CompletionException} holding that exception as its cause. If a |
49 |
> |
* CompletableFuture completes exceptionally, and is not followed by a |
50 |
> |
* {@link #exceptionally} or {@link #handle} completion, then all of |
51 |
> |
* its dependents (and their dependents) also complete exceptionally |
52 |
> |
* with CompletionExceptions holding the ultimate cause. For |
53 |
> |
* compatibility with {@link Future}, in case of a CompletionException, |
54 |
> |
* methods {@link #get()} and {@link #get(long, TimeUnit)} throw a |
55 |
> |
* {@link ExecutionException} with the same cause as would be held in |
56 |
> |
* the corresponding CompletionException. |
57 |
|
* |
58 |
|
* <p>CompletableFutures themselves do not execute asynchronously. |
59 |
|
* However, the {@code async} methods provide commonly useful ways to |
108 |
|
CompletionNode(Completion completion) { this.completion = completion; } |
109 |
|
} |
110 |
|
|
99 |
– |
|
111 |
|
volatile Object result; // either the result or boxed AltResult |
112 |
|
volatile WaitNode waiters; // Treiber stack of threads blocked on get() |
113 |
|
volatile CompletionNode completions; // list (Treiber stack) of completions |
201 |
|
} |
202 |
|
|
203 |
|
/** |
204 |
+ |
* Waits if necessary for the computation to complete, and then |
205 |
+ |
* retrieves its result. |
206 |
+ |
* |
207 |
+ |
* @return the computed result |
208 |
+ |
* @throws CancellationException if the computation was cancelled |
209 |
+ |
* @throws ExecutionException if the computation threw an |
210 |
+ |
* exception |
211 |
+ |
* @throws InterruptedException if the current thread was interrupted |
212 |
+ |
* while waiting |
213 |
+ |
*/ |
214 |
+ |
public T get() throws InterruptedException, ExecutionException { |
215 |
+ |
Object r; Throwable ex; |
216 |
+ |
if ((r = result) == null && (r = waitingGet(true)) == null) |
217 |
+ |
throw new InterruptedException(); |
218 |
+ |
if (r instanceof AltResult) { |
219 |
+ |
if ((ex = ((AltResult)r).ex) != null) { |
220 |
+ |
if (ex instanceof CancellationException) |
221 |
+ |
throw (CancellationException)ex; |
222 |
+ |
if (ex instanceof CompletionException) { |
223 |
+ |
Throwable cause = ex.getCause(); |
224 |
+ |
if (cause != null) |
225 |
+ |
ex = cause; |
226 |
+ |
} |
227 |
+ |
throw new ExecutionException(ex); |
228 |
+ |
} |
229 |
+ |
return null; |
230 |
+ |
} |
231 |
+ |
return (T)r; |
232 |
+ |
} |
233 |
+ |
|
234 |
+ |
/** |
235 |
|
* Returns the result value when complete, or throws an |
236 |
|
* (unchecked) exception if completed exceptionally. To better |
237 |
< |
* conform with the use of common functional forms, this method |
238 |
< |
* transforms any checked exception possible with {@link |
239 |
< |
* Future#get} into an (unchecked) {@link RuntimeException} with |
240 |
< |
* the underlying exception as its cause. (The checked exception |
241 |
< |
* convention is available using the timed form of get.) |
237 |
> |
* conform with the use of common functional forms, if a |
238 |
> |
* computation involved in the completion of this |
239 |
> |
* CompletableFuture threw an exception, this method throws an |
240 |
> |
* (unchecked) {@link CompletionException} with the |
241 |
> |
* underlying exception as its cause. Additionally, this method |
242 |
> |
* does not abort on interrupt. |
243 |
|
* |
244 |
|
* @return the result value |
245 |
+ |
* @throws CancellationException if the computation was cancelled |
246 |
+ |
* @throws CompletionException if the computation threw an |
247 |
+ |
* exception |
248 |
|
*/ |
249 |
< |
public T get() { |
249 |
> |
public T getValue() { |
250 |
|
Object r; Throwable ex; |
251 |
|
if ((r = result) == null) |
252 |
< |
return waitingGet(); |
252 |
> |
r = waitingGet(false); |
253 |
|
if (r instanceof AltResult) { |
254 |
|
if ((ex = ((AltResult)r).ex) != null) { |
255 |
< |
if (ex instanceof Error) |
256 |
< |
throw (Error)ex; |
257 |
< |
if (ex instanceof RuntimeException) |
258 |
< |
throw (RuntimeException)ex; |
259 |
< |
throw new RuntimeException(ex); |
255 |
> |
if (ex instanceof CancellationException) |
256 |
> |
throw (CancellationException)ex; |
257 |
> |
if (ex instanceof CompletionException) |
258 |
> |
throw (CompletionException)ex; |
259 |
> |
throw new CompletionException(ex); |
260 |
|
} |
261 |
|
return null; |
262 |
|
} |
269 |
|
* |
270 |
|
* @param valueIfAbsent the value to return if not completed |
271 |
|
* @return the result value, if completed, else the given valueIfAbsent |
272 |
+ |
* @throws CancellationException if the computation was cancelled |
273 |
+ |
* @throws CompletionException if the computation threw an |
274 |
+ |
* exception |
275 |
|
*/ |
276 |
|
public T getNow(T valueIfAbsent) { |
277 |
|
Object r; Throwable ex; |
279 |
|
return valueIfAbsent; |
280 |
|
if (r instanceof AltResult) { |
281 |
|
if ((ex = ((AltResult)r).ex) != null) { |
282 |
< |
if (ex instanceof Error) |
283 |
< |
throw (Error)ex; |
284 |
< |
if (ex instanceof RuntimeException) |
285 |
< |
throw (RuntimeException)ex; |
286 |
< |
throw new RuntimeException(ex); |
282 |
> |
if (ex instanceof CancellationException) |
283 |
> |
throw (CancellationException)ex; |
284 |
> |
if (ex instanceof CompletionException) |
285 |
> |
throw (CompletionException)ex; |
286 |
> |
throw new CompletionException(ex); |
287 |
|
} |
288 |
|
return null; |
289 |
|
} |
314 |
|
r = timedAwaitDone(nanos); |
315 |
|
if (r instanceof AltResult) { |
316 |
|
if ((ex = ((AltResult)r).ex) != null) { |
317 |
< |
if (ex instanceof ExecutionException) // avoid re-wrap |
318 |
< |
throw (ExecutionException)ex; |
317 |
> |
if (ex instanceof CancellationException) |
318 |
> |
throw (CancellationException)ex; |
319 |
> |
if (ex instanceof CompletionException) { |
320 |
> |
Throwable cause = ex.getCause(); |
321 |
> |
if (cause != null) |
322 |
> |
ex = cause; |
323 |
> |
} |
324 |
|
throw new ExecutionException(ex); |
325 |
|
} |
326 |
|
return null; |
347 |
|
} |
348 |
|
|
349 |
|
/** |
350 |
+ |
* Internal version of complete; CASes in an existing result or |
351 |
+ |
* AltResult. |
352 |
+ |
*/ |
353 |
+ |
private void propagateCompletion(Object r) { |
354 |
+ |
if (UNSAFE.compareAndSwapObject(this, RESULT, null, r)) |
355 |
+ |
postComplete(); |
356 |
+ |
} |
357 |
+ |
|
358 |
+ |
/** |
359 |
|
* If not already completed, causes invocations of {@link #get()} |
360 |
|
* and related methods to throw the given exception. |
361 |
|
* |
366 |
|
public boolean completeExceptionally(Throwable ex) { |
367 |
|
if (ex == null) throw new NullPointerException(); |
368 |
|
if (result == null) { |
369 |
< |
Object r = new AltResult(ex); |
369 |
> |
AltResult r = new AltResult(ex); |
370 |
|
if (UNSAFE.compareAndSwapObject(this, RESULT, null, r)) { |
371 |
|
postComplete(); |
372 |
|
return true; |
376 |
|
} |
377 |
|
|
378 |
|
/** |
379 |
+ |
* Internal version of completeExceptionally that avoids creating |
380 |
+ |
* chains of CompletionExceptions |
381 |
+ |
*/ |
382 |
+ |
private void propagateException(Throwable ex) { |
383 |
+ |
if (result == null) { |
384 |
+ |
AltResult r = new AltResult |
385 |
+ |
((ex instanceof CompletionException) ? ex : |
386 |
+ |
new CompletionException(ex)); |
387 |
+ |
if (UNSAFE.compareAndSwapObject(this, RESULT, null, r)) |
388 |
+ |
postComplete(); |
389 |
+ |
} |
390 |
+ |
} |
391 |
+ |
|
392 |
+ |
/** |
393 |
|
* Creates and returns a CompletableFuture that is completed with |
394 |
|
* the result of the given function of this CompletableFuture. |
395 |
|
* If this CompletableFuture completes exceptionally, |
396 |
|
* then the returned CompletableFuture also does so, |
397 |
< |
* with a RuntimeException having this exception as |
397 |
> |
* with a CompletionException holding this exception as |
398 |
|
* its cause. |
399 |
|
* |
400 |
|
* @param fn the function to use to compute the value of |
411 |
|
* result of the given function of this CompletableFuture. If |
412 |
|
* this CompletableFuture completes exceptionally, then the |
413 |
|
* returned CompletableFuture also does so, with a |
414 |
< |
* RuntimeException having this exception as its cause. |
414 |
> |
* CompletionException holding this exception as its cause. |
415 |
|
* |
416 |
|
* @param fn the function to use to compute the value of |
417 |
|
* the returned CompletableFuture |
426 |
|
* completed using the given executor with the result of the given |
427 |
|
* function of this CompletableFuture. If this CompletableFuture |
428 |
|
* completes exceptionally, then the returned CompletableFuture |
429 |
< |
* also does so, with a RuntimeException having this exception as |
429 |
> |
* also does so, with a CompletionException holding this exception as |
430 |
|
* its cause. |
431 |
|
* |
432 |
|
* @param fn the function to use to compute the value of |
445 |
|
* performing the given action with this CompletableFuture's |
446 |
|
* result when it completes. If this CompletableFuture |
447 |
|
* completes exceptionally, then the returned CompletableFuture |
448 |
< |
* also does so, with a RuntimeException having this exception as |
448 |
> |
* also does so, with a CompletionException holding this exception as |
449 |
|
* its cause. |
450 |
|
* |
451 |
|
* @param block the action to perform before completing the |
461 |
|
* completed using the {@link ForkJoinPool#commonPool()} with this |
462 |
|
* CompletableFuture's result when it completes. If this |
463 |
|
* CompletableFuture completes exceptionally, then the returned |
464 |
< |
* CompletableFuture also does so, with a RuntimeException having |
464 |
> |
* CompletableFuture also does so, with a CompletionException holding |
465 |
|
* this exception as its cause. |
466 |
|
* |
467 |
|
* @param block the action to perform before completing the |
477 |
|
* completed using the given executor with this |
478 |
|
* CompletableFuture's result when it completes. If this |
479 |
|
* CompletableFuture completes exceptionally, then the returned |
480 |
< |
* CompletableFuture also does so, with a RuntimeException having |
480 |
> |
* CompletableFuture also does so, with a CompletionException holding |
481 |
|
* this exception as its cause. |
482 |
|
* |
483 |
|
* @param block the action to perform before completing the |
496 |
|
* performing the given action when this CompletableFuture |
497 |
|
* completes. If this CompletableFuture completes exceptionally, |
498 |
|
* then the returned CompletableFuture also does so, with a |
499 |
< |
* RuntimeException having this exception as its cause. |
499 |
> |
* CompletionException holding this exception as its cause. |
500 |
|
* |
501 |
|
* @param action the action to perform before completing the |
502 |
|
* returned CompletableFuture |
512 |
|
* performing the given action when this CompletableFuture |
513 |
|
* completes. If this CompletableFuture completes exceptionally, |
514 |
|
* then the returned CompletableFuture also does so, with a |
515 |
< |
* RuntimeException having this exception as its cause. |
515 |
> |
* CompletionException holding this exception as its cause. |
516 |
|
* |
517 |
|
* @param action the action to perform before completing the |
518 |
|
* returned CompletableFuture |
527 |
|
* completed using the given executor after performing the given |
528 |
|
* action when this CompletableFuture completes. If this |
529 |
|
* CompletableFuture completes exceptionally, then the returned |
530 |
< |
* CompletableFuture also does so, with a RuntimeException having |
530 |
> |
* CompletableFuture also does so, with a CompletionException holding |
531 |
|
* this exception as its cause. |
532 |
|
* |
533 |
|
* @param action the action to perform before completing the |
547 |
|
* CompletableFuture's results when both complete. If this or |
548 |
|
* the other CompletableFuture complete exceptionally, then the |
549 |
|
* returned CompletableFuture also does so, with a |
550 |
< |
* RuntimeException having the exception as its cause. |
550 |
> |
* CompletionException holding the exception as its cause. |
551 |
|
* |
552 |
|
* @param other the other CompletableFuture |
553 |
|
* @param fn the function to use to compute the value of |
566 |
|
* CompletableFuture's results when both complete. If this or |
567 |
|
* the other CompletableFuture complete exceptionally, then the |
568 |
|
* returned CompletableFuture also does so, with a |
569 |
< |
* RuntimeException having the exception as its cause. |
569 |
> |
* CompletionException holding the exception as its cause. |
570 |
|
* |
571 |
|
* @param other the other CompletableFuture |
572 |
|
* @param fn the function to use to compute the value of |
585 |
|
* CompletableFuture's results when both complete. If this or |
586 |
|
* the other CompletableFuture complete exceptionally, then the |
587 |
|
* returned CompletableFuture also does so, with a |
588 |
< |
* RuntimeException having the exception as its cause. |
588 |
> |
* CompletionException holding the exception as its cause. |
589 |
|
* |
590 |
|
* @param other the other CompletableFuture |
591 |
|
* @param fn the function to use to compute the value of |
606 |
|
* the results of this and the other given CompletableFuture if |
607 |
|
* both complete. If this and/or the other CompletableFuture |
608 |
|
* complete exceptionally, then the returned CompletableFuture |
609 |
< |
* also does so, with a RuntimeException having one of these |
609 |
> |
* also does so, with a CompletionException holding one of these |
610 |
|
* exceptions as its cause. |
611 |
|
* |
612 |
|
* @param other the other CompletableFuture |
625 |
|
* the results of this and the other given CompletableFuture when |
626 |
|
* both complete. If this and/or the other CompletableFuture |
627 |
|
* complete exceptionally, then the returned CompletableFuture |
628 |
< |
* also does so, with a RuntimeException having one of these |
628 |
> |
* also does so, with a CompletionException holding one of these |
629 |
|
* exceptions as its cause. |
630 |
|
* |
631 |
|
* @param other the other CompletableFuture |
644 |
|
* this and the other given CompletableFuture when both complete. |
645 |
|
* If this and/or the other CompletableFuture complete |
646 |
|
* exceptionally, then the returned CompletableFuture also does |
647 |
< |
* so, with a RuntimeException having one of these exceptions as |
647 |
> |
* so, with a CompletionException holding one of these exceptions as |
648 |
|
* its cause. |
649 |
|
* |
650 |
|
* @param other the other CompletableFuture |
665 |
|
* when this and the other given CompletableFuture both |
666 |
|
* complete. If this and/or the other CompletableFuture complete |
667 |
|
* exceptionally, then the returned CompletableFuture also does |
668 |
< |
* so, with a RuntimeException having one of these exceptions as |
668 |
> |
* so, with a CompletionException holding one of these exceptions as |
669 |
|
* its cause. |
670 |
|
* |
671 |
|
* @param other the other CompletableFuture |
684 |
|
* when this and the other given CompletableFuture both |
685 |
|
* complete. If this and/or the other CompletableFuture complete |
686 |
|
* exceptionally, then the returned CompletableFuture also does |
687 |
< |
* so, with a RuntimeException having one of these exceptions as |
687 |
> |
* so, with a CompletionException holding one of these exceptions as |
688 |
|
* its cause. |
689 |
|
* |
690 |
|
* @param other the other CompletableFuture |
703 |
|
* when this and the other given CompletableFuture both |
704 |
|
* complete. If this and/or the other CompletableFuture complete |
705 |
|
* exceptionally, then the returned CompletableFuture also does |
706 |
< |
* so, with a RuntimeException having one of these exceptions as |
706 |
> |
* so, with a CompletionException holding one of these exceptions as |
707 |
|
* its cause. |
708 |
|
* |
709 |
|
* @param other the other CompletableFuture |
725 |
|
* given CompletableFuture's results when either complete. If |
726 |
|
* this and/or the other CompletableFuture complete exceptionally, |
727 |
|
* then the returned CompletableFuture may also do so, with a |
728 |
< |
* RuntimeException having one of these exceptions as its cause. |
728 |
> |
* CompletionException holding one of these exceptions as its cause. |
729 |
|
* No guarantees are made about which result or exception is used |
730 |
|
* in the returned CompletableFuture. |
731 |
|
* |
746 |
|
* given CompletableFuture's results when either complete. If |
747 |
|
* this and/or the other CompletableFuture complete exceptionally, |
748 |
|
* then the returned CompletableFuture may also do so, with a |
749 |
< |
* RuntimeException having one of these exceptions as its cause. |
749 |
> |
* CompletionException holding one of these exceptions as its cause. |
750 |
|
* No guarantees are made about which result or exception is used |
751 |
|
* in the returned CompletableFuture. |
752 |
|
* |
767 |
|
* CompletableFuture's results when either complete. If this |
768 |
|
* and/or the other CompletableFuture complete exceptionally, then |
769 |
|
* the returned CompletableFuture may also do so, with a |
770 |
< |
* RuntimeException having one of these exceptions as its cause. |
770 |
> |
* CompletionException holding one of these exceptions as its cause. |
771 |
|
* No guarantees are made about which result or exception is used |
772 |
|
* in the returned CompletableFuture. |
773 |
|
* |
790 |
|
* other given CompletableFuture's result, when either complete. |
791 |
|
* If this and/or the other CompletableFuture complete |
792 |
|
* exceptionally, then the returned CompletableFuture may also do |
793 |
< |
* so, with a RuntimeException having one of these exceptions as |
793 |
> |
* so, with a CompletionException holding one of these exceptions as |
794 |
|
* its cause. No guarantees are made about which exception is |
795 |
|
* used in the returned CompletableFuture. |
796 |
|
* |
811 |
|
* the other given CompletableFuture's result, when either |
812 |
|
* complete. If this and/or the other CompletableFuture complete |
813 |
|
* exceptionally, then the returned CompletableFuture may also do |
814 |
< |
* so, with a RuntimeException having one of these exceptions as |
814 |
> |
* so, with a CompletionException holding one of these exceptions as |
815 |
|
* its cause. No guarantees are made about which exception is |
816 |
|
* used in the returned CompletableFuture. |
817 |
|
* |
832 |
|
* the other given CompletableFuture's result, when either |
833 |
|
* complete. If this and/or the other CompletableFuture complete |
834 |
|
* exceptionally, then the returned CompletableFuture may also do |
835 |
< |
* so, with a RuntimeException having one of these exceptions as |
835 |
> |
* so, with a CompletionException holding one of these exceptions as |
836 |
|
* its cause. No guarantees are made about which exception is |
837 |
|
* used in the returned CompletableFuture. |
838 |
|
* |
854 |
|
* after this or the other given CompletableFuture complete. If |
855 |
|
* this and/or the other CompletableFuture complete exceptionally, |
856 |
|
* then the returned CompletableFuture may also do so, with a |
857 |
< |
* RuntimeException having one of these exceptions as its cause. |
857 |
> |
* CompletionException holding one of these exceptions as its cause. |
858 |
|
* No guarantees are made about which exception is used in the |
859 |
|
* returned CompletableFuture. |
860 |
|
* |
874 |
|
* after this or the other given CompletableFuture complete. If |
875 |
|
* this and/or the other CompletableFuture complete exceptionally, |
876 |
|
* then the returned CompletableFuture may also do so, with a |
877 |
< |
* RuntimeException having one of these exceptions as its cause. |
877 |
> |
* CompletionException holding one of these exceptions as its cause. |
878 |
|
* No guarantees are made about which exception is used in the |
879 |
|
* returned CompletableFuture. |
880 |
|
* |
893 |
|
* asynchronously using the given executor after this or the other |
894 |
|
* given CompletableFuture complete. If this and/or the other |
895 |
|
* CompletableFuture complete exceptionally, then the returned |
896 |
< |
* CompletableFuture may also do so, with a RuntimeException |
897 |
< |
* having one of these exceptions as its cause. No guarantees are |
896 |
> |
* CompletableFuture may also do so, with a CompletionException |
897 |
> |
* holding one of these exceptions as its cause. No guarantees are |
898 |
|
* made about which exception is used in the returned |
899 |
|
* CompletableFuture. |
900 |
|
* |
916 |
|
* produced by the given function of the result of this |
917 |
|
* CompletableFuture when completed. If this CompletableFuture |
918 |
|
* completes exceptionally, then the returned CompletableFuture |
919 |
< |
* also does so, with a RuntimeException having this exception as |
919 |
> |
* also does so, with a CompletionException holding this exception as |
920 |
|
* its cause. |
921 |
|
* |
922 |
|
* @param fn the function returning a new CompletableFuture. |
961 |
|
ex = new NullPointerException(); |
962 |
|
} |
963 |
|
if (ex != null) |
964 |
< |
dst.completeExceptionally(new RuntimeException(ex)); |
964 |
> |
dst.propagateException(ex); |
965 |
|
} |
966 |
|
if (r != null || result != null) |
967 |
|
postComplete(); |
1147 |
|
static final int WAITING_GET_SPINS = 256; |
1148 |
|
|
1149 |
|
/** |
1150 |
< |
* Returns result after waiting. |
1150 |
> |
* Returns raw result after waiting, or null if interruptible and |
1151 |
> |
* interrupted. |
1152 |
|
*/ |
1153 |
< |
private T waitingGet() { |
1153 |
> |
private Object waitingGet(boolean interruptible) { |
1154 |
|
WaitNode q = null; |
1155 |
|
boolean queued = false, interrupted = false; |
1156 |
|
int h = 0, spins = 0; |
1162 |
|
postComplete(); // help release others |
1163 |
|
if (interrupted) |
1164 |
|
Thread.currentThread().interrupt(); |
1165 |
< |
if (r instanceof AltResult) { |
1088 |
< |
if ((ex = ((AltResult)r).ex) != null) { |
1089 |
< |
if (ex instanceof Error) |
1090 |
< |
throw (Error)ex; |
1091 |
< |
if (ex instanceof RuntimeException) |
1092 |
< |
throw (RuntimeException)ex; |
1093 |
< |
throw new RuntimeException(ex); |
1094 |
< |
} |
1095 |
< |
return null; |
1096 |
< |
} |
1097 |
< |
return (T)r; |
1165 |
> |
return r; |
1166 |
|
} |
1167 |
|
else if (h == 0) { |
1168 |
|
h = ThreadLocalRandom.current().nextInt(); |
1180 |
|
else if (!queued) |
1181 |
|
queued = UNSAFE.compareAndSwapObject(this, WAITERS, |
1182 |
|
q.next = waiters, q); |
1183 |
< |
else if (Thread.interrupted()) |
1183 |
> |
else if (Thread.interrupted()) { |
1184 |
> |
if (interruptible) |
1185 |
> |
return null; |
1186 |
|
interrupted = true; |
1187 |
+ |
} |
1188 |
|
else if (q.thread == null) |
1189 |
|
q.thread = Thread.currentThread(); |
1190 |
|
else |
1440 |
|
(r = a.result) != null && |
1441 |
|
compareAndSet(0, 1)) { |
1442 |
|
if (r instanceof AltResult) { |
1443 |
< |
if ((ex = ((AltResult)r).ex) != null) |
1373 |
< |
ex = new RuntimeException(ex); |
1443 |
> |
ex = ((AltResult)r).ex; |
1444 |
|
t = null; |
1445 |
|
} |
1446 |
|
else { |
1458 |
|
} |
1459 |
|
} |
1460 |
|
if (ex != null) |
1461 |
< |
dst.completeExceptionally(ex); |
1461 |
> |
dst.propagateException(ex); |
1462 |
|
} |
1463 |
|
} |
1464 |
|
} |
1485 |
|
(r = a.result) != null && |
1486 |
|
compareAndSet(0, 1)) { |
1487 |
|
if (r instanceof AltResult) { |
1488 |
< |
if ((ex = ((AltResult)r).ex) != null) |
1419 |
< |
ex = new RuntimeException(ex); |
1488 |
> |
ex = ((AltResult)r).ex; |
1489 |
|
t = null; |
1490 |
|
} |
1491 |
|
else { |
1505 |
|
} |
1506 |
|
} |
1507 |
|
if (ex != null) |
1508 |
< |
dst.completeExceptionally(ex); |
1508 |
> |
dst.propagateException(ex); |
1509 |
|
} |
1510 |
|
} |
1511 |
|
} |
1532 |
|
(a = this.src) != null && |
1533 |
|
(r = a.result) != null && |
1534 |
|
compareAndSet(0, 1)) { |
1535 |
< |
if (r instanceof AltResult) { |
1536 |
< |
if ((ex = ((AltResult)r).ex) != null) |
1468 |
< |
ex = new RuntimeException(ex); |
1469 |
< |
} |
1535 |
> |
if (r instanceof AltResult) |
1536 |
> |
ex = ((AltResult)r).ex; |
1537 |
|
else |
1538 |
|
ex = null; |
1539 |
|
if (ex == null) { |
1549 |
|
} |
1550 |
|
} |
1551 |
|
if (ex != null) |
1552 |
< |
dst.completeExceptionally(ex); |
1552 |
> |
dst.propagateException(ex); |
1553 |
|
} |
1554 |
|
} |
1555 |
|
} |
1582 |
|
(s = b.result) != null && |
1583 |
|
compareAndSet(0, 1)) { |
1584 |
|
if (r instanceof AltResult) { |
1585 |
< |
if ((ex = ((AltResult)r).ex) != null) { |
1519 |
< |
dst.completeExceptionally(new RuntimeException(ex)); |
1520 |
< |
return; |
1521 |
< |
} |
1585 |
> |
ex = ((AltResult)r).ex; |
1586 |
|
t = null; |
1587 |
|
} |
1588 |
< |
else |
1588 |
> |
else { |
1589 |
> |
ex = null; |
1590 |
|
t = (T) r; |
1591 |
< |
if (s instanceof AltResult) { |
1592 |
< |
if ((ex = ((AltResult)s).ex) != null) { |
1593 |
< |
dst.completeExceptionally(new RuntimeException(ex)); |
1594 |
< |
return; |
1595 |
< |
} |
1591 |
> |
} |
1592 |
> |
if (ex != null) |
1593 |
> |
u = null; |
1594 |
> |
else if (s instanceof AltResult) { |
1595 |
> |
ex = ((AltResult)s).ex; |
1596 |
|
u = null; |
1597 |
|
} |
1598 |
|
else |
1599 |
|
u = (U) s; |
1600 |
< |
try { |
1601 |
< |
if (executor != null) |
1602 |
< |
executor.execute(new AsyncBiFunction<T,U,V>(t, u, fn, dst)); |
1603 |
< |
else |
1604 |
< |
dst.complete(fn.apply(t, u)); |
1605 |
< |
} catch (Throwable rex) { |
1606 |
< |
dst.completeExceptionally(rex); |
1600 |
> |
if (ex == null) { |
1601 |
> |
try { |
1602 |
> |
if (executor != null) |
1603 |
> |
executor.execute(new AsyncBiFunction<T,U,V>(t, u, fn, dst)); |
1604 |
> |
else |
1605 |
> |
dst.complete(fn.apply(t, u)); |
1606 |
> |
} catch (Throwable rex) { |
1607 |
> |
ex = rex; |
1608 |
> |
} |
1609 |
|
} |
1610 |
+ |
if (ex != null) |
1611 |
+ |
dst.propagateException(ex); |
1612 |
|
} |
1613 |
|
} |
1614 |
|
} |
1641 |
|
(s = b.result) != null && |
1642 |
|
compareAndSet(0, 1)) { |
1643 |
|
if (r instanceof AltResult) { |
1644 |
< |
if ((ex = ((AltResult)r).ex) != null) { |
1576 |
< |
dst.completeExceptionally(new RuntimeException(ex)); |
1577 |
< |
return; |
1578 |
< |
} |
1644 |
> |
ex = ((AltResult)r).ex; |
1645 |
|
t = null; |
1646 |
|
} |
1647 |
< |
else |
1647 |
> |
else { |
1648 |
> |
ex = null; |
1649 |
|
t = (T) r; |
1650 |
< |
if (s instanceof AltResult) { |
1651 |
< |
if ((ex = ((AltResult)s).ex) != null) { |
1652 |
< |
dst.completeExceptionally(new RuntimeException(ex)); |
1653 |
< |
return; |
1654 |
< |
} |
1650 |
> |
} |
1651 |
> |
if (ex != null) |
1652 |
> |
u = null; |
1653 |
> |
else if (s instanceof AltResult) { |
1654 |
> |
ex = ((AltResult)s).ex; |
1655 |
|
u = null; |
1656 |
|
} |
1657 |
|
else |
1658 |
|
u = (U) s; |
1659 |
< |
try { |
1660 |
< |
if (executor != null) |
1661 |
< |
executor.execute(new AsyncBiBlock<T,U>(t, u, fn, dst)); |
1662 |
< |
else { |
1663 |
< |
fn.accept(t, u); |
1664 |
< |
dst.complete(null); |
1659 |
> |
if (ex == null) { |
1660 |
> |
try { |
1661 |
> |
if (executor != null) |
1662 |
> |
executor.execute(new AsyncBiBlock<T,U>(t, u, fn, dst)); |
1663 |
> |
else { |
1664 |
> |
fn.accept(t, u); |
1665 |
> |
dst.complete(null); |
1666 |
> |
} |
1667 |
> |
} catch (Throwable rex) { |
1668 |
> |
ex = rex; |
1669 |
|
} |
1599 |
– |
} catch (Throwable rex) { |
1600 |
– |
dst.completeExceptionally(rex); |
1670 |
|
} |
1671 |
+ |
if (ex != null) |
1672 |
+ |
dst.propagateException(ex); |
1673 |
|
} |
1674 |
|
} |
1675 |
|
} |
1701 |
|
(b = this.snd) != null && |
1702 |
|
(s = b.result) != null && |
1703 |
|
compareAndSet(0, 1)) { |
1704 |
< |
if (r instanceof AltResult) { |
1705 |
< |
if ((ex = ((AltResult)r).ex) != null) { |
1706 |
< |
dst.completeExceptionally(new RuntimeException(ex)); |
1707 |
< |
return; |
1708 |
< |
} |
1709 |
< |
} |
1710 |
< |
if (s instanceof AltResult) { |
1711 |
< |
if ((ex = ((AltResult)s).ex) != null) { |
1712 |
< |
dst.completeExceptionally(new RuntimeException(ex)); |
1713 |
< |
return; |
1714 |
< |
} |
1715 |
< |
} |
1716 |
< |
try { |
1717 |
< |
if (executor != null) |
1718 |
< |
executor.execute(new AsyncRunnable(fn, dst)); |
1719 |
< |
else { |
1649 |
< |
fn.run(); |
1650 |
< |
dst.complete(null); |
1704 |
> |
if (r instanceof AltResult) |
1705 |
> |
ex = ((AltResult)r).ex; |
1706 |
> |
else |
1707 |
> |
ex = null; |
1708 |
> |
if (ex == null && (s instanceof AltResult)) |
1709 |
> |
ex = ((AltResult)s).ex; |
1710 |
> |
if (ex == null) { |
1711 |
> |
try { |
1712 |
> |
if (executor != null) |
1713 |
> |
executor.execute(new AsyncRunnable(fn, dst)); |
1714 |
> |
else { |
1715 |
> |
fn.run(); |
1716 |
> |
dst.complete(null); |
1717 |
> |
} |
1718 |
> |
} catch (Throwable rex) { |
1719 |
> |
ex = rex; |
1720 |
|
} |
1652 |
– |
} catch (Throwable rex) { |
1653 |
– |
dst.completeExceptionally(rex); |
1721 |
|
} |
1722 |
+ |
if (ex != null) |
1723 |
+ |
dst.propagateException(ex); |
1724 |
|
} |
1725 |
|
} |
1726 |
|
} |
1751 |
|
((b = this.snd) != null && (r = b.result) != null)) && |
1752 |
|
compareAndSet(0, 1)) { |
1753 |
|
if (r instanceof AltResult) { |
1754 |
< |
if ((ex = ((AltResult)r).ex) != null) { |
1686 |
< |
dst.completeExceptionally(new RuntimeException(ex)); |
1687 |
< |
return; |
1688 |
< |
} |
1754 |
> |
ex = ((AltResult)r).ex; |
1755 |
|
t = null; |
1756 |
|
} |
1757 |
< |
else |
1757 |
> |
else { |
1758 |
> |
ex = null; |
1759 |
|
t = (T) r; |
1693 |
– |
try { |
1694 |
– |
if (executor != null) |
1695 |
– |
executor.execute(new AsyncFunction<T,U>(t, fn, dst)); |
1696 |
– |
else |
1697 |
– |
dst.complete(fn.apply(t)); |
1698 |
– |
} catch (Throwable rex) { |
1699 |
– |
dst.completeExceptionally(rex); |
1760 |
|
} |
1761 |
+ |
if (ex == null) { |
1762 |
+ |
try { |
1763 |
+ |
if (executor != null) |
1764 |
+ |
executor.execute(new AsyncFunction<T,U>(t, fn, dst)); |
1765 |
+ |
else |
1766 |
+ |
dst.complete(fn.apply(t)); |
1767 |
+ |
} catch (Throwable rex) { |
1768 |
+ |
ex = rex; |
1769 |
+ |
} |
1770 |
+ |
} |
1771 |
+ |
if (ex != null) |
1772 |
+ |
dst.propagateException(ex); |
1773 |
|
} |
1774 |
|
} |
1775 |
|
} |
1800 |
|
((b = this.snd) != null && (r = b.result) != null)) && |
1801 |
|
compareAndSet(0, 1)) { |
1802 |
|
if (r instanceof AltResult) { |
1803 |
< |
if ((ex = ((AltResult)r).ex) != null) { |
1732 |
< |
dst.completeExceptionally(new RuntimeException(ex)); |
1733 |
< |
return; |
1734 |
< |
} |
1803 |
> |
ex = ((AltResult)r).ex; |
1804 |
|
t = null; |
1805 |
|
} |
1806 |
< |
else |
1806 |
> |
else { |
1807 |
> |
ex = null; |
1808 |
|
t = (T) r; |
1809 |
< |
try { |
1810 |
< |
if (executor != null) |
1811 |
< |
executor.execute(new AsyncBlock<T>(t, fn, dst)); |
1812 |
< |
else { |
1813 |
< |
fn.accept(t); |
1814 |
< |
dst.complete(null); |
1809 |
> |
} |
1810 |
> |
if (ex == null) { |
1811 |
> |
try { |
1812 |
> |
if (executor != null) |
1813 |
> |
executor.execute(new AsyncBlock<T>(t, fn, dst)); |
1814 |
> |
else { |
1815 |
> |
fn.accept(t); |
1816 |
> |
dst.complete(null); |
1817 |
> |
} |
1818 |
> |
} catch (Throwable rex) { |
1819 |
> |
ex = rex; |
1820 |
|
} |
1746 |
– |
} catch (Throwable rex) { |
1747 |
– |
dst.completeExceptionally(rex); |
1821 |
|
} |
1822 |
+ |
if (ex != null) |
1823 |
+ |
dst.propagateException(ex); |
1824 |
|
} |
1825 |
|
} |
1826 |
|
} |
1850 |
|
(((a = this.src) != null && (r = a.result) != null) || |
1851 |
|
((b = this.snd) != null && (r = b.result) != null)) && |
1852 |
|
compareAndSet(0, 1)) { |
1853 |
< |
if ((r instanceof AltResult) && |
1854 |
< |
(ex = ((AltResult)r).ex) != null) { |
1855 |
< |
dst.completeExceptionally(new RuntimeException(ex)); |
1856 |
< |
} |
1857 |
< |
else { |
1853 |
> |
if (r instanceof AltResult) |
1854 |
> |
ex = ((AltResult)r).ex; |
1855 |
> |
else |
1856 |
> |
ex = null; |
1857 |
> |
if (ex == null) { |
1858 |
|
try { |
1859 |
|
if (executor != null) |
1860 |
|
executor.execute(new AsyncRunnable(fn, dst)); |
1863 |
|
dst.complete(null); |
1864 |
|
} |
1865 |
|
} catch (Throwable rex) { |
1866 |
< |
dst.completeExceptionally(rex); |
1866 |
> |
ex = rex; |
1867 |
|
} |
1868 |
|
} |
1869 |
+ |
if (ex != null) |
1870 |
+ |
dst.propagateException(ex); |
1871 |
|
} |
1872 |
|
} |
1873 |
|
} |
1924 |
|
(a = this.src) != null && |
1925 |
|
(r = a.result) != null && |
1926 |
|
compareAndSet(0, 1)) { |
1927 |
< |
if (r instanceof AltResult) { |
1851 |
< |
if ((ex = ((AltResult)r).ex) != null) { |
1852 |
< |
dst.completeExceptionally(new RuntimeException(ex)); |
1853 |
< |
return; |
1854 |
< |
} |
1855 |
< |
t = null; |
1856 |
< |
} |
1857 |
< |
else |
1858 |
< |
t = (T) r; |
1859 |
< |
dst.complete(t); |
1927 |
> |
dst.propagateCompletion(r); |
1928 |
|
} |
1929 |
|
} |
1930 |
|
} |
2003 |
|
if (ex != null || c == null) { |
2004 |
|
if (ex == null) |
2005 |
|
ex = new NullPointerException(); |
1938 |
– |
else |
1939 |
– |
ex = new RuntimeException(ex); |
2006 |
|
} |
2007 |
|
else { |
2008 |
|
ThenCopy<U> d = null; |
2029 |
|
} |
2030 |
|
} |
2031 |
|
if (ex != null) |
2032 |
< |
dst.completeExceptionally(ex); |
2033 |
< |
if (c != null && c.result != null) |
2032 |
> |
dst.propagateException(ex); |
2033 |
> |
else if (c != null && c.result != null) |
2034 |
|
c.postComplete(); |
2035 |
|
} |
2036 |
|
} |
2040 |
|
|
2041 |
|
private <U> CompletableFuture<U> thenFunction(Function<? super T,? extends U> fn, |
2042 |
|
Executor executor) { |
1977 |
– |
|
2043 |
|
if (fn == null) throw new NullPointerException(); |
2044 |
|
CompletableFuture<U> dst = new CompletableFuture<U>(); |
2045 |
|
ThenFunction<T,U> d = null; |
2054 |
|
} |
2055 |
|
} |
2056 |
|
if (r != null && (d == null || d.compareAndSet(0, 1))) { |
2057 |
< |
T t; Throwable ex = null; |
2057 |
> |
T t; Throwable ex; |
2058 |
|
if (r instanceof AltResult) { |
2059 |
< |
if ((ex = ((AltResult)r).ex) != null) |
1995 |
< |
dst.completeExceptionally(new RuntimeException(ex)); |
2059 |
> |
ex = ((AltResult)r).ex; |
2060 |
|
t = null; |
2061 |
|
} |
2062 |
< |
else |
2062 |
> |
else { |
2063 |
> |
ex = null; |
2064 |
|
t = (T) r; |
2065 |
+ |
} |
2066 |
|
if (ex == null) { |
2067 |
|
try { |
2068 |
|
if (executor != null) |
2070 |
|
else |
2071 |
|
dst.complete(fn.apply(t)); |
2072 |
|
} catch (Throwable rex) { |
2073 |
< |
dst.completeExceptionally(rex); |
2073 |
> |
ex = rex; |
2074 |
|
} |
2075 |
|
} |
2076 |
+ |
if (ex != null) |
2077 |
+ |
dst.propagateException(ex); |
2078 |
|
} |
2079 |
|
if (r != null || result != null) |
2080 |
|
postComplete(); |
2083 |
|
|
2084 |
|
private CompletableFuture<Void> thenBlock(Block<? super T> fn, |
2085 |
|
Executor executor) { |
2018 |
– |
|
2086 |
|
if (fn == null) throw new NullPointerException(); |
2087 |
|
CompletableFuture<Void> dst = new CompletableFuture<Void>(); |
2088 |
|
ThenBlock<T> d = null; |
2097 |
|
} |
2098 |
|
} |
2099 |
|
if (r != null && (d == null || d.compareAndSet(0, 1))) { |
2100 |
< |
T t; Throwable ex = null; |
2100 |
> |
T t; Throwable ex; |
2101 |
|
if (r instanceof AltResult) { |
2102 |
< |
if ((ex = ((AltResult)r).ex) != null) |
2036 |
< |
dst.completeExceptionally(new RuntimeException(ex)); |
2102 |
> |
ex = ((AltResult)r).ex; |
2103 |
|
t = null; |
2104 |
|
} |
2105 |
< |
else |
2105 |
> |
else { |
2106 |
> |
ex = null; |
2107 |
|
t = (T) r; |
2108 |
+ |
} |
2109 |
|
if (ex == null) { |
2110 |
|
try { |
2111 |
|
if (executor != null) |
2115 |
|
dst.complete(null); |
2116 |
|
} |
2117 |
|
} catch (Throwable rex) { |
2118 |
< |
dst.completeExceptionally(rex); |
2118 |
> |
ex = rex; |
2119 |
|
} |
2120 |
|
} |
2121 |
+ |
if (ex != null) |
2122 |
+ |
dst.propagateException(ex); |
2123 |
|
} |
2124 |
|
if (r != null || result != null) |
2125 |
|
postComplete(); |
2142 |
|
} |
2143 |
|
} |
2144 |
|
if (r != null && (d == null || d.compareAndSet(0, 1))) { |
2145 |
< |
Throwable ex = null; |
2146 |
< |
if (r instanceof AltResult) { |
2147 |
< |
if ((ex = ((AltResult)r).ex) != null) |
2148 |
< |
dst.completeExceptionally(new RuntimeException(ex)); |
2149 |
< |
} |
2145 |
> |
Throwable ex; |
2146 |
> |
if (r instanceof AltResult) |
2147 |
> |
ex = ((AltResult)r).ex; |
2148 |
> |
else |
2149 |
> |
ex = null; |
2150 |
|
if (ex == null) { |
2151 |
|
try { |
2152 |
|
if (executor != null) |
2156 |
|
dst.complete(null); |
2157 |
|
} |
2158 |
|
} catch (Throwable rex) { |
2159 |
< |
dst.completeExceptionally(rex); |
2159 |
> |
ex = rex; |
2160 |
|
} |
2161 |
|
} |
2162 |
+ |
if (ex != null) |
2163 |
+ |
dst.propagateException(ex); |
2164 |
|
} |
2165 |
|
if (r != null || result != null) |
2166 |
|
postComplete(); |
2195 |
|
} |
2196 |
|
} |
2197 |
|
if (r != null && s != null && (d == null || d.compareAndSet(0, 1))) { |
2198 |
< |
T t; U u; Throwable ex = null; |
2198 |
> |
T t; U u; Throwable ex; |
2199 |
|
if (r instanceof AltResult) { |
2200 |
< |
if ((ex = ((AltResult)r).ex) != null) |
2129 |
< |
dst.completeExceptionally(new RuntimeException(ex)); |
2200 |
> |
ex = ((AltResult)r).ex; |
2201 |
|
t = null; |
2202 |
|
} |
2203 |
< |
else |
2203 |
> |
else { |
2204 |
> |
ex = null; |
2205 |
|
t = (T) r; |
2206 |
+ |
} |
2207 |
|
if (ex != null) |
2208 |
|
u = null; |
2209 |
|
else if (s instanceof AltResult) { |
2210 |
< |
if ((ex = ((AltResult)s).ex) != null) |
2138 |
< |
dst.completeExceptionally(new RuntimeException(ex)); |
2210 |
> |
ex = ((AltResult)s).ex; |
2211 |
|
u = null; |
2212 |
|
} |
2213 |
|
else |
2219 |
|
else |
2220 |
|
dst.complete(fn.apply(t, u)); |
2221 |
|
} catch (Throwable rex) { |
2222 |
< |
dst.completeExceptionally(rex); |
2222 |
> |
ex = rex; |
2223 |
|
} |
2224 |
|
} |
2225 |
+ |
if (ex != null) |
2226 |
+ |
dst.propagateException(ex); |
2227 |
|
} |
2228 |
|
if (r != null || result != null) |
2229 |
|
postComplete(); |
2260 |
|
} |
2261 |
|
} |
2262 |
|
if (r != null && s != null && (d == null || d.compareAndSet(0, 1))) { |
2263 |
< |
T t; U u; Throwable ex = null; |
2263 |
> |
T t; U u; Throwable ex; |
2264 |
|
if (r instanceof AltResult) { |
2265 |
< |
if ((ex = ((AltResult)r).ex) != null) |
2192 |
< |
dst.completeExceptionally(new RuntimeException(ex)); |
2265 |
> |
ex = ((AltResult)r).ex; |
2266 |
|
t = null; |
2267 |
|
} |
2268 |
< |
else |
2268 |
> |
else { |
2269 |
> |
ex = null; |
2270 |
|
t = (T) r; |
2271 |
+ |
} |
2272 |
|
if (ex != null) |
2273 |
|
u = null; |
2274 |
|
else if (s instanceof AltResult) { |
2275 |
< |
if ((ex = ((AltResult)s).ex) != null) |
2201 |
< |
dst.completeExceptionally(new RuntimeException(ex)); |
2275 |
> |
ex = ((AltResult)s).ex; |
2276 |
|
u = null; |
2277 |
|
} |
2278 |
|
else |
2286 |
|
dst.complete(null); |
2287 |
|
} |
2288 |
|
} catch (Throwable rex) { |
2289 |
< |
dst.completeExceptionally(rex); |
2289 |
> |
ex = rex; |
2290 |
|
} |
2291 |
|
} |
2292 |
+ |
if (ex != null) |
2293 |
+ |
dst.propagateException(ex); |
2294 |
|
} |
2295 |
|
if (r != null || result != null) |
2296 |
|
postComplete(); |
2327 |
|
} |
2328 |
|
} |
2329 |
|
if (r != null && s != null && (d == null || d.compareAndSet(0, 1))) { |
2330 |
< |
Throwable ex = null; |
2331 |
< |
if ((r instanceof AltResult) && |
2332 |
< |
(ex = ((AltResult)r).ex) != null) |
2333 |
< |
dst.completeExceptionally(new RuntimeException(ex)); |
2334 |
< |
else if ((s instanceof AltResult) && |
2335 |
< |
(ex = ((AltResult)s).ex) != null) |
2336 |
< |
dst.completeExceptionally(new RuntimeException(ex)); |
2337 |
< |
else { |
2330 |
> |
Throwable ex; |
2331 |
> |
if (r instanceof AltResult) |
2332 |
> |
ex = ((AltResult)r).ex; |
2333 |
> |
else |
2334 |
> |
ex = null; |
2335 |
> |
if (ex == null && (s instanceof AltResult)) |
2336 |
> |
ex = ((AltResult)s).ex; |
2337 |
> |
if (ex == null) { |
2338 |
|
try { |
2339 |
|
if (executor != null) |
2340 |
|
executor.execute(new AsyncRunnable(action, dst)); |
2343 |
|
dst.complete(null); |
2344 |
|
} |
2345 |
|
} catch (Throwable rex) { |
2346 |
< |
dst.completeExceptionally(rex); |
2346 |
> |
ex = rex; |
2347 |
|
} |
2348 |
|
} |
2349 |
+ |
if (ex != null) |
2350 |
+ |
dst.propagateException(ex); |
2351 |
|
} |
2352 |
|
if (r != null || result != null) |
2353 |
|
postComplete(); |
2378 |
|
} |
2379 |
|
} |
2380 |
|
if (r != null && (d == null || d.compareAndSet(0, 1))) { |
2381 |
< |
T t; Throwable ex = null; |
2381 |
> |
T t; Throwable ex; |
2382 |
|
if (r instanceof AltResult) { |
2383 |
< |
if ((ex = ((AltResult)r).ex) != null) |
2306 |
< |
dst.completeExceptionally(new RuntimeException(ex)); |
2383 |
> |
ex = ((AltResult)r).ex; |
2384 |
|
t = null; |
2385 |
|
} |
2386 |
< |
else |
2386 |
> |
else { |
2387 |
> |
ex = null; |
2388 |
|
t = (T) r; |
2389 |
+ |
} |
2390 |
|
if (ex == null) { |
2391 |
|
try { |
2392 |
|
if (executor != null) |
2394 |
|
else |
2395 |
|
dst.complete(fn.apply(t)); |
2396 |
|
} catch (Throwable rex) { |
2397 |
< |
dst.completeExceptionally(rex); |
2397 |
> |
ex = rex; |
2398 |
|
} |
2399 |
|
} |
2400 |
+ |
if (ex != null) |
2401 |
+ |
dst.propagateException(ex); |
2402 |
|
} |
2403 |
|
if (result != null) |
2404 |
|
postComplete(); |
2429 |
|
} |
2430 |
|
} |
2431 |
|
if (r != null && (d == null || d.compareAndSet(0, 1))) { |
2432 |
< |
T t; Throwable ex = null; |
2432 |
> |
T t; Throwable ex; |
2433 |
|
if (r instanceof AltResult) { |
2434 |
< |
if ((ex = ((AltResult)r).ex) != null) |
2354 |
< |
dst.completeExceptionally(new RuntimeException(ex)); |
2434 |
> |
ex = ((AltResult)r).ex; |
2435 |
|
t = null; |
2436 |
|
} |
2437 |
< |
else |
2437 |
> |
else { |
2438 |
> |
ex = null; |
2439 |
|
t = (T) r; |
2440 |
+ |
} |
2441 |
|
if (ex == null) { |
2442 |
|
try { |
2443 |
|
if (executor != null) |
2447 |
|
dst.complete(null); |
2448 |
|
} |
2449 |
|
} catch (Throwable rex) { |
2450 |
< |
dst.completeExceptionally(rex); |
2450 |
> |
ex = rex; |
2451 |
|
} |
2452 |
|
} |
2453 |
+ |
if (ex != null) |
2454 |
+ |
dst.propagateException(ex); |
2455 |
|
} |
2456 |
|
if (result != null) |
2457 |
|
postComplete(); |
2482 |
|
} |
2483 |
|
} |
2484 |
|
if (r != null && (d == null || d.compareAndSet(0, 1))) { |
2485 |
< |
Throwable ex = null; |
2486 |
< |
if ((r instanceof AltResult) && |
2487 |
< |
(ex = ((AltResult)r).ex) != null) |
2488 |
< |
dst.completeExceptionally(new RuntimeException(ex)); |
2489 |
< |
else { |
2485 |
> |
Throwable ex; |
2486 |
> |
if (r instanceof AltResult) |
2487 |
> |
ex = ((AltResult)r).ex; |
2488 |
> |
else |
2489 |
> |
ex = null; |
2490 |
> |
if (ex == null) { |
2491 |
|
try { |
2492 |
|
if (executor != null) |
2493 |
|
executor.execute(new AsyncRunnable(action, dst)); |
2496 |
|
dst.complete(null); |
2497 |
|
} |
2498 |
|
} catch (Throwable rex) { |
2499 |
< |
dst.completeExceptionally(rex); |
2499 |
> |
ex = rex; |
2500 |
|
} |
2501 |
|
} |
2502 |
+ |
if (ex != null) |
2503 |
+ |
dst.propagateException(ex); |
2504 |
|
} |
2505 |
|
if (result != null) |
2506 |
|
postComplete(); |