ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/concurrent/CompletableFuture.java
(Generate patch)

Comparing jsr166/src/main/java/util/concurrent/CompletableFuture.java (file contents):
Revision 1.18 by dl, Sun Dec 30 16:11:36 2012 UTC vs.
Revision 1.19 by dl, Sun Dec 30 22:59:10 2012 UTC

# Line 19 | Line 19 | import java.util.concurrent.ThreadLocalR
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  
# Line 38 | Line 39 | import java.util.concurrent.locks.LockSu
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
# Line 96 | Line 108 | public class CompletableFuture<T> implem
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
# Line 190 | Line 201 | public class CompletableFuture<T> implem
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          }
# Line 223 | Line 269 | public class CompletableFuture<T> implem
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;
# Line 230 | Line 279 | public class CompletableFuture<T> implem
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          }
# Line 265 | Line 314 | public class CompletableFuture<T> implem
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;
# Line 293 | Line 347 | public class CompletableFuture<T> implem
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       *
# Line 303 | Line 366 | public class CompletableFuture<T> implem
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;
# Line 313 | Line 376 | public class CompletableFuture<T> implem
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
# Line 334 | Line 411 | public class CompletableFuture<T> implem
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
# Line 349 | Line 426 | public class CompletableFuture<T> implem
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
# Line 368 | Line 445 | public class CompletableFuture<T> implem
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
# Line 384 | Line 461 | public class CompletableFuture<T> implem
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
# Line 400 | Line 477 | public class CompletableFuture<T> implem
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
# Line 419 | Line 496 | public class CompletableFuture<T> implem
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
# Line 435 | Line 512 | public class CompletableFuture<T> implem
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
# Line 450 | Line 527 | public class CompletableFuture<T> implem
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
# Line 470 | Line 547 | public class CompletableFuture<T> implem
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
# Line 489 | Line 566 | public class CompletableFuture<T> implem
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
# Line 508 | Line 585 | public class CompletableFuture<T> implem
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
# Line 529 | Line 606 | public class CompletableFuture<T> implem
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
# Line 548 | Line 625 | public class CompletableFuture<T> implem
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
# Line 567 | Line 644 | public class CompletableFuture<T> implem
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
# Line 588 | Line 665 | public class CompletableFuture<T> implem
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
# Line 607 | Line 684 | public class CompletableFuture<T> implem
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
# Line 626 | Line 703 | public class CompletableFuture<T> implem
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
# Line 648 | Line 725 | public class CompletableFuture<T> implem
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       *
# Line 669 | Line 746 | public class CompletableFuture<T> implem
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       *
# Line 690 | Line 767 | public class CompletableFuture<T> implem
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       *
# Line 713 | Line 790 | public class CompletableFuture<T> implem
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       *
# Line 734 | Line 811 | public class CompletableFuture<T> implem
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       *
# Line 755 | Line 832 | public class CompletableFuture<T> implem
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       *
# Line 777 | Line 854 | public class CompletableFuture<T> implem
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       *
# Line 797 | Line 874 | public class CompletableFuture<T> implem
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       *
# Line 816 | Line 893 | public class CompletableFuture<T> implem
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       *
# Line 839 | Line 916 | public class CompletableFuture<T> implem
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.
# Line 884 | Line 961 | public class CompletableFuture<T> implem
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();
# Line 1070 | Line 1147 | public class CompletableFuture<T> implem
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;
# Line 1084 | Line 1162 | public class CompletableFuture<T> implem
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();
# Line 1112 | Line 1180 | public class CompletableFuture<T> implem
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
# Line 1369 | Line 1440 | public class CompletableFuture<T> implem
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 {
# Line 1388 | Line 1458 | public class CompletableFuture<T> implem
1458                      }
1459                  }
1460                  if (ex != null)
1461 <                    dst.completeExceptionally(ex);
1461 >                    dst.propagateException(ex);
1462              }
1463          }
1464      }
# Line 1415 | Line 1485 | public class CompletableFuture<T> implem
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 {
# Line 1436 | Line 1505 | public class CompletableFuture<T> implem
1505                      }
1506                  }
1507                  if (ex != null)
1508 <                    dst.completeExceptionally(ex);
1508 >                    dst.propagateException(ex);
1509              }
1510          }
1511      }
# Line 1463 | Line 1532 | public class CompletableFuture<T> implem
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) {
# Line 1482 | Line 1549 | public class CompletableFuture<T> implem
1549                      }
1550                  }
1551                  if (ex != null)
1552 <                    dst.completeExceptionally(ex);
1552 >                    dst.propagateException(ex);
1553              }
1554          }
1555      }
# Line 1515 | Line 1582 | public class CompletableFuture<T> implem
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      }
# Line 1572 | Line 1641 | public class CompletableFuture<T> implem
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      }
# Line 1630 | Line 1701 | public class CompletableFuture<T> implem
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      }
# Line 1682 | Line 1751 | public class CompletableFuture<T> implem
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      }
# Line 1728 | Line 1800 | public class CompletableFuture<T> implem
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      }
# Line 1775 | Line 1850 | public class CompletableFuture<T> implem
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));
# Line 1788 | Line 1863 | public class CompletableFuture<T> implem
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      }
# Line 1847 | Line 1924 | public class CompletableFuture<T> implem
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      }
# Line 1935 | Line 2003 | public class CompletableFuture<T> implem
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;
# Line 1963 | Line 2029 | public class CompletableFuture<T> implem
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          }
# Line 1974 | Line 2040 | public class CompletableFuture<T> implem
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;
# Line 1989 | Line 2054 | public class CompletableFuture<T> implem
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)
# Line 2004 | Line 2070 | public class CompletableFuture<T> implem
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();
# Line 2015 | Line 2083 | public class CompletableFuture<T> implem
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;
# Line 2030 | Line 2097 | public class CompletableFuture<T> implem
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)
# Line 2047 | Line 2115 | public class CompletableFuture<T> implem
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();
# Line 2072 | Line 2142 | public class CompletableFuture<T> implem
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)
# Line 2086 | Line 2156 | public class CompletableFuture<T> implem
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();
# Line 2123 | Line 2195 | public class CompletableFuture<T> implem
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
# Line 2147 | Line 2219 | public class CompletableFuture<T> implem
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();
# Line 2186 | Line 2260 | public class CompletableFuture<T> implem
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
# Line 2212 | Line 2286 | public class CompletableFuture<T> implem
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();
# Line 2251 | Line 2327 | public class CompletableFuture<T> implem
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));
# Line 2267 | Line 2343 | public class CompletableFuture<T> implem
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();
# Line 2300 | Line 2378 | public class CompletableFuture<T> implem
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)
# Line 2315 | Line 2394 | public class CompletableFuture<T> implem
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();
# Line 2348 | Line 2429 | public class CompletableFuture<T> implem
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)
# Line 2365 | Line 2447 | public class CompletableFuture<T> implem
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();
# Line 2398 | Line 2482 | public class CompletableFuture<T> implem
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));
# Line 2411 | Line 2496 | public class CompletableFuture<T> implem
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();

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines