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

Comparing jsr166/src/jdk8/java/util/concurrent/CompletableFuture.java (file contents):
Revision 1.3 by dl, Sun Apr 3 14:42:09 2016 UTC vs.
Revision 1.10 by jsr166, Mon Oct 1 03:58:18 2018 UTC

# Line 105 | Line 105 | import java.util.function.Supplier;
105   * }}</pre>
106   *
107   * @author Doug Lea
108 * @since 1.8
108   * @param <T> The result type returned by this future's {@code join}
109   * and {@code get} methods
110 + * @since 1.8
111   */
112   public class CompletableFuture<T> implements Future<T>, CompletionStage<T> {
113  
# Line 120 | Line 120 | public class CompletableFuture<T> implem
120       * applies across normal vs exceptional outcomes, sync vs async
121       * actions, binary triggers, and various forms of completions.
122       *
123 <     * Non-nullness of field result (set via CAS) indicates done.  An
124 <     * AltResult is used to box null as a result, as well as to hold
125 <     * exceptions.  Using a single field makes completion simple to
126 <     * detect and trigger.  Encoding and decoding is straightforward
127 <     * but adds to the sprawl of trapping and associating exceptions
128 <     * with targets.  Minor simplifications rely on (static) NIL (to
129 <     * box null results) being the only AltResult with a null
130 <     * exception field, so we don't usually need explicit comparisons.
131 <     * Even though some of the generics casts are unchecked (see
132 <     * SuppressWarnings annotations), they are placed to be
133 <     * appropriate even if checked.
123 >     * Non-nullness of volatile field "result" indicates done.  It may
124 >     * be set directly if known to be thread-confined, else via CAS.
125 >     * An AltResult is used to box null as a result, as well as to
126 >     * hold exceptions.  Using a single field makes completion simple
127 >     * to detect and trigger.  Result encoding and decoding is
128 >     * straightforward but tedious and adds to the sprawl of trapping
129 >     * and associating exceptions with targets.  Minor simplifications
130 >     * rely on (static) NIL (to box null results) being the only
131 >     * AltResult with a null exception field, so we don't usually need
132 >     * explicit comparisons.  Even though some of the generics casts
133 >     * are unchecked (see SuppressWarnings annotations), they are
134 >     * placed to be appropriate even if checked.
135       *
136       * Dependent actions are represented by Completion objects linked
137       * as Treiber stacks headed by field "stack". There are Completion
138 <     * classes for each kind of action, grouped into single-input
139 <     * (UniCompletion), two-input (BiCompletion), projected
140 <     * (BiCompletions using either (not both) of two inputs), shared
141 <     * (CoCompletion, used by the second of two sources), zero-input
142 <     * source actions, and Signallers that unblock waiters. Class
143 <     * Completion extends ForkJoinTask to enable async execution
138 >     * classes for each kind of action, grouped into:
139 >     * - single-input (UniCompletion),
140 >     * - two-input (BiCompletion),
141 >     * - projected (BiCompletions using exactly one of two inputs),
142 >     * - shared (CoCompletion, used by the second of two sources),
143 >     * - zero-input source actions,
144 >     * - Signallers that unblock waiters.
145 >     * Class Completion extends ForkJoinTask to enable async execution
146       * (adding no space overhead because we exploit its "tag" methods
147       * to maintain claims). It is also declared as Runnable to allow
148       * usage with arbitrary executors.
# Line 155 | Line 158 | public class CompletableFuture<T> implem
158       *   encounter layers of adapters in common usages.
159       *
160       * * Boolean CompletableFuture method x(...) (for example
161 <     *   uniApply) takes all of the arguments needed to check that an
161 >     *   biApply) takes all of the arguments needed to check that an
162       *   action is triggerable, and then either runs the action or
163       *   arranges its async execution by executing its Completion
164       *   argument, if present. The method returns true if known to be
# Line 165 | Line 168 | public class CompletableFuture<T> implem
168       *   method with its held arguments, and on success cleans up.
169       *   The mode argument allows tryFire to be called twice (SYNC,
170       *   then ASYNC); the first to screen and trap exceptions while
171 <     *   arranging to execute, and the second when called from a
172 <     *   task. (A few classes are not used async so take slightly
173 <     *   different forms.)  The claim() callback suppresses function
174 <     *   invocation if already claimed by another thread.
171 >     *   arranging to execute, and the second when called from a task.
172 >     *   (A few classes are not used async so take slightly different
173 >     *   forms.)  The claim() callback suppresses function invocation
174 >     *   if already claimed by another thread.
175 >     *
176 >     * * Some classes (for example UniApply) have separate handling
177 >     *   code for when known to be thread-confined ("now" methods) and
178 >     *   for when shared (in tryFire), for efficiency.
179       *
180       * * CompletableFuture method xStage(...) is called from a public
181 <     *   stage method of CompletableFuture x. It screens user
181 >     *   stage method of CompletableFuture f. It screens user
182       *   arguments and invokes and/or creates the stage object.  If
183 <     *   not async and x is already complete, the action is run
184 <     *   immediately.  Otherwise a Completion c is created, pushed to
185 <     *   x's stack (unless done), and started or triggered via
186 <     *   c.tryFire.  This also covers races possible if x completes
187 <     *   while pushing.  Classes with two inputs (for example BiApply)
188 <     *   deal with races across both while pushing actions.  The
189 <     *   second completion is a CoCompletion pointing to the first,
190 <     *   shared so that at most one performs the action.  The
191 <     *   multiple-arity methods allOf and anyOf do this pairwise to
192 <     *   form trees of completions.
183 >     *   not async and already triggerable, the action is run
184 >     *   immediately.  Otherwise a Completion c is created, and
185 >     *   submitted to the executor if triggerable, or pushed onto f's
186 >     *   stack if not.  Completion actions are started via c.tryFire.
187 >     *   We recheck after pushing to a source future's stack to cover
188 >     *   possible races if the source completes while pushing.
189 >     *   Classes with two inputs (for example BiApply) deal with races
190 >     *   across both while pushing actions.  The second completion is
191 >     *   a CoCompletion pointing to the first, shared so that at most
192 >     *   one performs the action.  The multiple-arity methods allOf
193 >     *   does this pairwise to form trees of completions.  Method
194 >     *   anyOf is handled differently from allOf because completion of
195 >     *   any source should trigger a cleanStack of other sources.
196 >     *   Each AnyOf completion can reach others via a shared array.
197       *
198       * Note that the generic type parameters of methods vary according
199       * to whether "this" is a source, dependent, or completion.
# Line 327 | Line 338 | public class CompletableFuture<T> implem
338       */
339      static Object encodeRelay(Object r) {
340          Throwable x;
341 <        return (((r instanceof AltResult) &&
342 <                 (x = ((AltResult)r).ex) != null &&
343 <                 !(x instanceof CompletionException)) ?
344 <                new AltResult(new CompletionException(x)) : r);
341 >        if (r instanceof AltResult
342 >            && (x = ((AltResult)r).ex) != null
343 >            && !(x instanceof CompletionException))
344 >            r = new AltResult(new CompletionException(x));
345 >        return r;
346      }
347  
348      /**
# Line 345 | Line 357 | public class CompletableFuture<T> implem
357      /**
358       * Reports result using Future.get conventions.
359       */
360 <    private static <T> T reportGet(Object r)
360 >    private static Object reportGet(Object r)
361          throws InterruptedException, ExecutionException {
362          if (r == null) // by convention below, null means interrupted
363              throw new InterruptedException();
# Line 360 | Line 372 | public class CompletableFuture<T> implem
372                  x = cause;
373              throw new ExecutionException(x);
374          }
375 <        @SuppressWarnings("unchecked") T t = (T) r;
364 <        return t;
375 >        return r;
376      }
377  
378      /**
379       * Decodes outcome to return result or throw unchecked exception.
380       */
381 <    private static <T> T reportJoin(Object r) {
381 >    private static Object reportJoin(Object r) {
382          if (r instanceof AltResult) {
383              Throwable x;
384              if ((x = ((AltResult)r).ex) == null)
# Line 378 | Line 389 | public class CompletableFuture<T> implem
389                  throw (CompletionException)x;
390              throw new CompletionException(x);
391          }
392 <        @SuppressWarnings("unchecked") T t = (T) r;
382 <        return t;
392 >        return r;
393      }
394  
395      /* ------------- Async task preliminaries -------------- */
# Line 486 | Line 496 | public class CompletableFuture<T> implem
496  
497      /** Traverses stack and unlinks one or more dead Completions, if found. */
498      final void cleanStack() {
499 <        boolean unlinked = false;
500 <        Completion p;
501 <        while ((p = stack) != null && !p.isLive()) // ensure head of stack live
502 <            unlinked = casStack(p, p.next);
503 <        if (p != null && !unlinked) {              // try to unlink first nonlive
504 <            for (Completion q = p.next; q != null;) {
505 <                Completion s = q.next;
506 <                if (q.isLive()) {
507 <                    p = q;
498 <                    q = s;
499 <                }
500 <                else {
501 <                    casNext(p, q, s);
499 >        Completion p = stack;
500 >        // ensure head of stack live
501 >        for (boolean unlinked = false;;) {
502 >            if (p == null)
503 >                return;
504 >            else if (p.isLive()) {
505 >                if (unlinked)
506 >                    return;
507 >                else
508                      break;
503                }
509              }
510 +            else if (casStack(p, (p = p.next)))
511 +                unlinked = true;
512 +            else
513 +                p = stack;
514 +        }
515 +        // try to unlink first non-live
516 +        for (Completion q = p.next; q != null;) {
517 +            Completion s = q.next;
518 +            if (q.isLive()) {
519 +                p = q;
520 +                q = s;
521 +            } else if (casNext(p, q, s))
522 +                break;
523 +            else
524 +                q = p.next;
525          }
526      }
527  
# Line 539 | Line 559 | public class CompletableFuture<T> implem
559          final boolean isLive() { return dep != null; }
560      }
561  
562 <    /** Pushes the given completion (if it exists) unless done. */
563 <    final void push(UniCompletion<?,?> c) {
562 >    /**
563 >     * Pushes the given completion unless it completes while trying.
564 >     * Caller should first check that result is null.
565 >     */
566 >    final void unipush(Completion c) {
567          if (c != null) {
568 <            while (result == null && !tryPushStack(c))
569 <                lazySetNext(c, null); // clear on failure
568 >            while (!tryPushStack(c)) {
569 >                if (result != null) {
570 >                    lazySetNext(c, null);
571 >                    break;
572 >                }
573 >            }
574 >            if (result != null)
575 >                c.tryFire(SYNC);
576          }
577      }
578  
579      /**
580 <     * Post-processing by dependent after successful UniCompletion
581 <     * tryFire.  Tries to clean stack of source a, and then either runs
582 <     * postComplete or returns this to caller, depending on mode.
580 >     * Post-processing by dependent after successful UniCompletion tryFire.
581 >     * Tries to clean stack of source a, and then either runs postComplete
582 >     * or returns this to caller, depending on mode.
583       */
584      final CompletableFuture<T> postFire(CompletableFuture<?> a, int mode) {
585          if (a != null && a.stack != null) {
# Line 579 | Line 608 | public class CompletableFuture<T> implem
608          }
609          final CompletableFuture<V> tryFire(int mode) {
610              CompletableFuture<V> d; CompletableFuture<T> a;
611 <            if ((d = dep) == null ||
612 <                !d.uniApply(a = src, fn, mode > 0 ? null : this))
611 >            Object r; Throwable x; Function<? super T,? extends V> f;
612 >            if ((d = dep) == null || (f = fn) == null
613 >                || (a = src) == null || (r = a.result) == null)
614                  return null;
615 <            dep = null; src = null; fn = null;
616 <            return d.postFire(a, mode);
617 <        }
618 <    }
619 <
620 <    final <S> boolean uniApply(CompletableFuture<S> a,
621 <                               Function<? super S,? extends T> f,
622 <                               UniApply<S,T> c) {
623 <        Object r; Throwable x;
624 <        if (a == null || (r = a.result) == null || f == null)
625 <            return false;
626 <        tryComplete: if (result == null) {
627 <            if (r instanceof AltResult) {
628 <                if ((x = ((AltResult)r).ex) != null) {
629 <                    completeThrowable(x, r);
630 <                    break tryComplete;
615 >            tryComplete: if (d.result == null) {
616 >                if (r instanceof AltResult) {
617 >                    if ((x = ((AltResult)r).ex) != null) {
618 >                        d.completeThrowable(x, r);
619 >                        break tryComplete;
620 >                    }
621 >                    r = null;
622 >                }
623 >                try {
624 >                    if (mode <= 0 && !claim())
625 >                        return null;
626 >                    else {
627 >                        @SuppressWarnings("unchecked") T t = (T) r;
628 >                        d.completeValue(f.apply(t));
629 >                    }
630 >                } catch (Throwable ex) {
631 >                    d.completeThrowable(ex);
632                  }
602                r = null;
603            }
604            try {
605                if (c != null && !c.claim())
606                    return false;
607                @SuppressWarnings("unchecked") S s = (S) r;
608                completeValue(f.apply(s));
609            } catch (Throwable ex) {
610                completeThrowable(ex);
633              }
634 +            dep = null; src = null; fn = null;
635 +            return d.postFire(a, mode);
636          }
613        return true;
637      }
638  
639      private <V> CompletableFuture<V> uniApplyStage(
640          Executor e, Function<? super T,? extends V> f) {
641          if (f == null) throw new NullPointerException();
642 +        Object r;
643 +        if ((r = result) != null)
644 +            return uniApplyNow(r, e, f);
645          CompletableFuture<V> d = newIncompleteFuture();
646 <        if (e != null || !d.uniApply(this, f, null)) {
647 <            UniApply<T,V> c = new UniApply<T,V>(e, d, this, f);
648 <            if (e != null && result != null) {
649 <                try {
650 <                    e.execute(c);
651 <                } catch (Throwable ex) {
652 <                    d.completeThrowable(ex);
653 <                }
646 >        unipush(new UniApply<T,V>(e, d, this, f));
647 >        return d;
648 >    }
649 >
650 >    private <V> CompletableFuture<V> uniApplyNow(
651 >        Object r, Executor e, Function<? super T,? extends V> f) {
652 >        Throwable x;
653 >        CompletableFuture<V> d = newIncompleteFuture();
654 >        if (r instanceof AltResult) {
655 >            if ((x = ((AltResult)r).ex) != null) {
656 >                d.result = encodeThrowable(x, r);
657 >                return d;
658              }
659 <            else {
660 <                push(c);
661 <                c.tryFire(SYNC);
659 >            r = null;
660 >        }
661 >        try {
662 >            if (e != null) {
663 >                e.execute(new UniApply<T,V>(null, d, this, f));
664 >            } else {
665 >                @SuppressWarnings("unchecked") T t = (T) r;
666 >                d.result = d.encodeValue(f.apply(t));
667              }
668 +        } catch (Throwable ex) {
669 +            d.result = encodeThrowable(ex);
670          }
671          return d;
672      }
# Line 643 | Line 680 | public class CompletableFuture<T> implem
680          }
681          final CompletableFuture<Void> tryFire(int mode) {
682              CompletableFuture<Void> d; CompletableFuture<T> a;
683 <            if ((d = dep) == null ||
684 <                !d.uniAccept(a = src, fn, mode > 0 ? null : this))
683 >            Object r; Throwable x; Consumer<? super T> f;
684 >            if ((d = dep) == null || (f = fn) == null
685 >                || (a = src) == null || (r = a.result) == null)
686                  return null;
687 <            dep = null; src = null; fn = null;
688 <            return d.postFire(a, mode);
689 <        }
690 <    }
691 <
692 <    final <S> boolean uniAccept(CompletableFuture<S> a,
693 <                                Consumer<? super S> f, UniAccept<S> c) {
694 <        Object r; Throwable x;
695 <        if (a == null || (r = a.result) == null || f == null)
696 <            return false;
697 <        tryComplete: if (result == null) {
698 <            if (r instanceof AltResult) {
699 <                if ((x = ((AltResult)r).ex) != null) {
700 <                    completeThrowable(x, r);
701 <                    break tryComplete;
687 >            tryComplete: if (d.result == null) {
688 >                if (r instanceof AltResult) {
689 >                    if ((x = ((AltResult)r).ex) != null) {
690 >                        d.completeThrowable(x, r);
691 >                        break tryComplete;
692 >                    }
693 >                    r = null;
694 >                }
695 >                try {
696 >                    if (mode <= 0 && !claim())
697 >                        return null;
698 >                    else {
699 >                        @SuppressWarnings("unchecked") T t = (T) r;
700 >                        f.accept(t);
701 >                        d.completeNull();
702 >                    }
703 >                } catch (Throwable ex) {
704 >                    d.completeThrowable(ex);
705                  }
665                r = null;
666            }
667            try {
668                if (c != null && !c.claim())
669                    return false;
670                @SuppressWarnings("unchecked") S s = (S) r;
671                f.accept(s);
672                completeNull();
673            } catch (Throwable ex) {
674                completeThrowable(ex);
706              }
707 +            dep = null; src = null; fn = null;
708 +            return d.postFire(a, mode);
709          }
677        return true;
710      }
711  
712      private CompletableFuture<Void> uniAcceptStage(Executor e,
713                                                     Consumer<? super T> f) {
714          if (f == null) throw new NullPointerException();
715 +        Object r;
716 +        if ((r = result) != null)
717 +            return uniAcceptNow(r, e, f);
718          CompletableFuture<Void> d = newIncompleteFuture();
719 <        if (e != null || !d.uniAccept(this, f, null)) {
720 <            UniAccept<T> c = new UniAccept<T>(e, d, this, f);
721 <            if (e != null && result != null) {
722 <                try {
723 <                    e.execute(c);
724 <                } catch (Throwable ex) {
725 <                    d.completeThrowable(ex);
726 <                }
719 >        unipush(new UniAccept<T>(e, d, this, f));
720 >        return d;
721 >    }
722 >
723 >    private CompletableFuture<Void> uniAcceptNow(
724 >        Object r, Executor e, Consumer<? super T> f) {
725 >        Throwable x;
726 >        CompletableFuture<Void> d = newIncompleteFuture();
727 >        if (r instanceof AltResult) {
728 >            if ((x = ((AltResult)r).ex) != null) {
729 >                d.result = encodeThrowable(x, r);
730 >                return d;
731              }
732 <            else {
733 <                push(c);
734 <                c.tryFire(SYNC);
732 >            r = null;
733 >        }
734 >        try {
735 >            if (e != null) {
736 >                e.execute(new UniAccept<T>(null, d, this, f));
737 >            } else {
738 >                @SuppressWarnings("unchecked") T t = (T) r;
739 >                f.accept(t);
740 >                d.result = NIL;
741              }
742 +        } catch (Throwable ex) {
743 +            d.result = encodeThrowable(ex);
744          }
745          return d;
746      }
# Line 707 | Line 754 | public class CompletableFuture<T> implem
754          }
755          final CompletableFuture<Void> tryFire(int mode) {
756              CompletableFuture<Void> d; CompletableFuture<T> a;
757 <            if ((d = dep) == null ||
758 <                !d.uniRun(a = src, fn, mode > 0 ? null : this))
757 >            Object r; Throwable x; Runnable f;
758 >            if ((d = dep) == null || (f = fn) == null
759 >                || (a = src) == null || (r = a.result) == null)
760                  return null;
761 +            if (d.result == null) {
762 +                if (r instanceof AltResult && (x = ((AltResult)r).ex) != null)
763 +                    d.completeThrowable(x, r);
764 +                else
765 +                    try {
766 +                        if (mode <= 0 && !claim())
767 +                            return null;
768 +                        else {
769 +                            f.run();
770 +                            d.completeNull();
771 +                        }
772 +                    } catch (Throwable ex) {
773 +                        d.completeThrowable(ex);
774 +                    }
775 +            }
776              dep = null; src = null; fn = null;
777              return d.postFire(a, mode);
778          }
779      }
780  
718    final boolean uniRun(CompletableFuture<?> a, Runnable f, UniRun<?> c) {
719        Object r; Throwable x;
720        if (a == null || (r = a.result) == null || f == null)
721            return false;
722        if (result == null) {
723            if (r instanceof AltResult && (x = ((AltResult)r).ex) != null)
724                completeThrowable(x, r);
725            else
726                try {
727                    if (c != null && !c.claim())
728                        return false;
729                    f.run();
730                    completeNull();
731                } catch (Throwable ex) {
732                    completeThrowable(ex);
733                }
734        }
735        return true;
736    }
737
781      private CompletableFuture<Void> uniRunStage(Executor e, Runnable f) {
782          if (f == null) throw new NullPointerException();
783 +        Object r;
784 +        if ((r = result) != null)
785 +            return uniRunNow(r, e, f);
786          CompletableFuture<Void> d = newIncompleteFuture();
787 <        if (e != null || !d.uniRun(this, f, null)) {
788 <            UniRun<T> c = new UniRun<T>(e, d, this, f);
789 <            if (e != null && result != null) {
790 <                try {
791 <                    e.execute(c);
792 <                } catch (Throwable ex) {
793 <                    d.completeThrowable(ex);
787 >        unipush(new UniRun<T>(e, d, this, f));
788 >        return d;
789 >    }
790 >
791 >    private CompletableFuture<Void> uniRunNow(Object r, Executor e, Runnable f) {
792 >        Throwable x;
793 >        CompletableFuture<Void> d = newIncompleteFuture();
794 >        if (r instanceof AltResult && (x = ((AltResult)r).ex) != null)
795 >            d.result = encodeThrowable(x, r);
796 >        else
797 >            try {
798 >                if (e != null) {
799 >                    e.execute(new UniRun<T>(null, d, this, f));
800 >                } else {
801 >                    f.run();
802 >                    d.result = NIL;
803                  }
804 +            } catch (Throwable ex) {
805 +                d.result = encodeThrowable(ex);
806              }
750            else {
751                push(c);
752                c.tryFire(SYNC);
753            }
754        }
807          return d;
808      }
809  
# Line 765 | Line 817 | public class CompletableFuture<T> implem
817          }
818          final CompletableFuture<T> tryFire(int mode) {
819              CompletableFuture<T> d; CompletableFuture<T> a;
820 <            if ((d = dep) == null ||
821 <                !d.uniWhenComplete(a = src, fn, mode > 0 ? null : this))
820 >            Object r; BiConsumer<? super T, ? super Throwable> f;
821 >            if ((d = dep) == null || (f = fn) == null
822 >                || (a = src) == null || (r = a.result) == null
823 >                || !d.uniWhenComplete(r, f, mode > 0 ? null : this))
824                  return null;
825              dep = null; src = null; fn = null;
826              return d.postFire(a, mode);
827          }
828      }
829  
830 <    final boolean uniWhenComplete(CompletableFuture<T> a,
830 >    final boolean uniWhenComplete(Object r,
831                                    BiConsumer<? super T,? super Throwable> f,
832                                    UniWhenComplete<T> c) {
833 <        Object r; T t; Throwable x = null;
780 <        if (a == null || (r = a.result) == null || f == null)
781 <            return false;
833 >        T t; Throwable x = null;
834          if (result == null) {
835              try {
836                  if (c != null && !c.claim())
# Line 810 | Line 862 | public class CompletableFuture<T> implem
862          Executor e, BiConsumer<? super T, ? super Throwable> f) {
863          if (f == null) throw new NullPointerException();
864          CompletableFuture<T> d = newIncompleteFuture();
865 <        if (e != null || !d.uniWhenComplete(this, f, null)) {
866 <            UniWhenComplete<T> c = new UniWhenComplete<T>(e, d, this, f);
867 <            if (e != null && result != null) {
868 <                try {
869 <                    e.execute(c);
870 <                } catch (Throwable ex) {
871 <                    d.completeThrowable(ex);
872 <                }
873 <            }
874 <            else {
823 <                push(c);
824 <                c.tryFire(SYNC);
865 >        Object r;
866 >        if ((r = result) == null)
867 >            unipush(new UniWhenComplete<T>(e, d, this, f));
868 >        else if (e == null)
869 >            d.uniWhenComplete(r, f, null);
870 >        else {
871 >            try {
872 >                e.execute(new UniWhenComplete<T>(null, d, this, f));
873 >            } catch (Throwable ex) {
874 >                d.result = encodeThrowable(ex);
875              }
876          }
877          return d;
# Line 837 | Line 887 | public class CompletableFuture<T> implem
887          }
888          final CompletableFuture<V> tryFire(int mode) {
889              CompletableFuture<V> d; CompletableFuture<T> a;
890 <            if ((d = dep) == null ||
891 <                !d.uniHandle(a = src, fn, mode > 0 ? null : this))
890 >            Object r; BiFunction<? super T, Throwable, ? extends V> f;
891 >            if ((d = dep) == null || (f = fn) == null
892 >                || (a = src) == null || (r = a.result) == null
893 >                || !d.uniHandle(r, f, mode > 0 ? null : this))
894                  return null;
895              dep = null; src = null; fn = null;
896              return d.postFire(a, mode);
897          }
898      }
899  
900 <    final <S> boolean uniHandle(CompletableFuture<S> a,
900 >    final <S> boolean uniHandle(Object r,
901                                  BiFunction<? super S, Throwable, ? extends T> f,
902                                  UniHandle<S,T> c) {
903 <        Object r; S s; Throwable x;
852 <        if (a == null || (r = a.result) == null || f == null)
853 <            return false;
903 >        S s; Throwable x;
904          if (result == null) {
905              try {
906                  if (c != null && !c.claim())
# Line 875 | Line 925 | public class CompletableFuture<T> implem
925          Executor e, BiFunction<? super T, Throwable, ? extends V> f) {
926          if (f == null) throw new NullPointerException();
927          CompletableFuture<V> d = newIncompleteFuture();
928 <        if (e != null || !d.uniHandle(this, f, null)) {
929 <            UniHandle<T,V> c = new UniHandle<T,V>(e, d, this, f);
930 <            if (e != null && result != null) {
931 <                try {
932 <                    e.execute(c);
933 <                } catch (Throwable ex) {
934 <                    d.completeThrowable(ex);
935 <                }
936 <            }
937 <            else {
888 <                push(c);
889 <                c.tryFire(SYNC);
928 >        Object r;
929 >        if ((r = result) == null)
930 >            unipush(new UniHandle<T,V>(e, d, this, f));
931 >        else if (e == null)
932 >            d.uniHandle(r, f, null);
933 >        else {
934 >            try {
935 >                e.execute(new UniHandle<T,V>(null, d, this, f));
936 >            } catch (Throwable ex) {
937 >                d.result = encodeThrowable(ex);
938              }
939          }
940          return d;
# Line 895 | Line 943 | public class CompletableFuture<T> implem
943      @SuppressWarnings("serial")
944      static final class UniExceptionally<T> extends UniCompletion<T,T> {
945          Function<? super Throwable, ? extends T> fn;
946 <        UniExceptionally(CompletableFuture<T> dep, CompletableFuture<T> src,
946 >        UniExceptionally(Executor executor,
947 >                         CompletableFuture<T> dep, CompletableFuture<T> src,
948                           Function<? super Throwable, ? extends T> fn) {
949 <            super(null, dep, src); this.fn = fn;
949 >            super(executor, dep, src); this.fn = fn;
950          }
951 <        final CompletableFuture<T> tryFire(int mode) { // never ASYNC
903 <            // assert mode != ASYNC;
951 >        final CompletableFuture<T> tryFire(int mode) {
952              CompletableFuture<T> d; CompletableFuture<T> a;
953 <            if ((d = dep) == null || !d.uniExceptionally(a = src, fn, this))
953 >            Object r; Function<? super Throwable, ? extends T> f;
954 >            if ((d = dep) == null || (f = fn) == null
955 >                || (a = src) == null || (r = a.result) == null
956 >                || !d.uniExceptionally(r, f, mode > 0 ? null : this))
957                  return null;
958              dep = null; src = null; fn = null;
959              return d.postFire(a, mode);
960          }
961      }
962  
963 <    final boolean uniExceptionally(CompletableFuture<T> a,
963 >    final boolean uniExceptionally(Object r,
964                                     Function<? super Throwable, ? extends T> f,
965                                     UniExceptionally<T> c) {
966 <        Object r; Throwable x;
916 <        if (a == null || (r = a.result) == null || f == null)
917 <            return false;
966 >        Throwable x;
967          if (result == null) {
968              try {
969 <                if (r instanceof AltResult && (x = ((AltResult)r).ex) != null) {
970 <                    if (c != null && !c.claim())
971 <                        return false;
969 >                if (c != null && !c.claim())
970 >                    return false;
971 >                if (r instanceof AltResult && (x = ((AltResult)r).ex) != null)
972                      completeValue(f.apply(x));
973 <                } else
973 >                else
974                      internalComplete(r);
975              } catch (Throwable ex) {
976                  completeThrowable(ex);
# Line 931 | Line 980 | public class CompletableFuture<T> implem
980      }
981  
982      private CompletableFuture<T> uniExceptionallyStage(
983 <        Function<Throwable, ? extends T> f) {
983 >        Executor e, Function<Throwable, ? extends T> f) {
984          if (f == null) throw new NullPointerException();
985          CompletableFuture<T> d = newIncompleteFuture();
986 <        if (!d.uniExceptionally(this, f, null)) {
987 <            UniExceptionally<T> c = new UniExceptionally<T>(d, this, f);
988 <            push(c);
989 <            c.tryFire(SYNC);
986 >        Object r;
987 >        if ((r = result) == null)
988 >            unipush(new UniExceptionally<T>(e, d, this, f));
989 >        else if (e == null)
990 >            d.uniExceptionally(r, f, null);
991 >        else {
992 >            try {
993 >                e.execute(new UniExceptionally<T>(null, d, this, f));
994 >            } catch (Throwable ex) {
995 >                d.result = encodeThrowable(ex);
996 >            }
997          }
998          return d;
999      }
1000  
1001      @SuppressWarnings("serial")
1002 <    static final class UniRelay<T> extends UniCompletion<T,T> { // for Compose
1003 <        UniRelay(CompletableFuture<T> dep, CompletableFuture<T> src) {
1004 <            super(null, dep, src);
1002 >    static final class UniComposeExceptionally<T> extends UniCompletion<T,T> {
1003 >        Function<Throwable, ? extends CompletionStage<T>> fn;
1004 >        UniComposeExceptionally(Executor executor, CompletableFuture<T> dep,
1005 >                                CompletableFuture<T> src,
1006 >                                Function<Throwable, ? extends CompletionStage<T>> fn) {
1007 >            super(executor, dep, src); this.fn = fn;
1008          }
1009          final CompletableFuture<T> tryFire(int mode) {
1010              CompletableFuture<T> d; CompletableFuture<T> a;
1011 <            if ((d = dep) == null || !d.uniRelay(a = src))
1011 >            Function<Throwable, ? extends CompletionStage<T>> f;
1012 >            Object r; Throwable x;
1013 >            if ((d = dep) == null || (f = fn) == null
1014 >                || (a = src) == null || (r = a.result) == null)
1015                  return null;
1016 <            src = null; dep = null;
1016 >            if (d.result == null) {
1017 >                if ((r instanceof AltResult) &&
1018 >                    (x = ((AltResult)r).ex) != null) {
1019 >                    try {
1020 >                        if (mode <= 0 && !claim())
1021 >                            return null;
1022 >                        CompletableFuture<T> g = f.apply(x).toCompletableFuture();
1023 >                        if ((r = g.result) != null)
1024 >                            d.completeRelay(r);
1025 >                        else {
1026 >                            g.unipush(new UniRelay<T,T>(d, g));
1027 >                            if (d.result == null)
1028 >                                return null;
1029 >                        }
1030 >                    } catch (Throwable ex) {
1031 >                        d.completeThrowable(ex);
1032 >                    }
1033 >                }
1034 >                else
1035 >                    d.internalComplete(r);
1036 >            }
1037 >            dep = null; src = null; fn = null;
1038              return d.postFire(a, mode);
1039          }
1040      }
1041  
1042 <    final boolean uniRelay(CompletableFuture<T> a) {
1043 <        Object r;
1044 <        if (a == null || (r = a.result) == null)
1045 <            return false;
1046 <        if (result == null) // no need to claim
1047 <            completeRelay(r);
1048 <        return true;
1042 >    private CompletableFuture<T> uniComposeExceptionallyStage(
1043 >        Executor e, Function<Throwable, ? extends CompletionStage<T>> f) {
1044 >        if (f == null) throw new NullPointerException();
1045 >        CompletableFuture<T> d = newIncompleteFuture();
1046 >        Object r, s; Throwable x;
1047 >        if ((r = result) == null)
1048 >            unipush(new UniComposeExceptionally<T>(e, d, this, f));
1049 >        else if (!(r instanceof AltResult) || (x = ((AltResult)r).ex) == null)
1050 >            d.internalComplete(r);
1051 >        else
1052 >            try {
1053 >                if (e != null)
1054 >                    e.execute(new UniComposeExceptionally<T>(null, d, this, f));
1055 >                else {
1056 >                    CompletableFuture<T> g = f.apply(x).toCompletableFuture();
1057 >                    if ((s = g.result) != null)
1058 >                        d.result = encodeRelay(s);
1059 >                    else
1060 >                        g.unipush(new UniRelay<T,T>(d, g));
1061 >                }
1062 >            } catch (Throwable ex) {
1063 >                d.result = encodeThrowable(ex);
1064 >            }
1065 >        return d;
1066      }
1067  
1068 <    private CompletableFuture<T> uniCopyStage() {
1069 <        Object r;
1070 <        CompletableFuture<T> d = newIncompleteFuture();
1071 <        if ((r = result) != null)
1072 <            d.completeRelay(r);
1073 <        else {
1074 <            UniRelay<T> c = new UniRelay<T>(d, this);
1075 <            push(c);
1076 <            c.tryFire(SYNC);
1068 >    @SuppressWarnings("serial")
1069 >    static final class UniRelay<U, T extends U> extends UniCompletion<T,U> {
1070 >        UniRelay(CompletableFuture<U> dep, CompletableFuture<T> src) {
1071 >            super(null, dep, src);
1072 >        }
1073 >        final CompletableFuture<U> tryFire(int mode) {
1074 >            CompletableFuture<U> d; CompletableFuture<T> a; Object r;
1075 >            if ((d = dep) == null
1076 >                || (a = src) == null || (r = a.result) == null)
1077 >                return null;
1078 >            if (d.result == null)
1079 >                d.completeRelay(r);
1080 >            src = null; dep = null;
1081 >            return d.postFire(a, mode);
1082          }
1083 +    }
1084 +
1085 +    private static <U, T extends U> CompletableFuture<U> uniCopyStage(
1086 +        CompletableFuture<T> src) {
1087 +        Object r;
1088 +        CompletableFuture<U> d = src.newIncompleteFuture();
1089 +        if ((r = src.result) != null)
1090 +            d.result = encodeRelay(r);
1091 +        else
1092 +            src.unipush(new UniRelay<U,T>(d, src));
1093          return d;
1094      }
1095  
# Line 983 | Line 1098 | public class CompletableFuture<T> implem
1098          if ((r = result) != null)
1099              return new MinimalStage<T>(encodeRelay(r));
1100          MinimalStage<T> d = new MinimalStage<T>();
1101 <        UniRelay<T> c = new UniRelay<T>(d, this);
987 <        push(c);
988 <        c.tryFire(SYNC);
1101 >        unipush(new UniRelay<T,T>(d, this));
1102          return d;
1103      }
1104  
# Line 999 | Line 1112 | public class CompletableFuture<T> implem
1112          }
1113          final CompletableFuture<V> tryFire(int mode) {
1114              CompletableFuture<V> d; CompletableFuture<T> a;
1115 <            if ((d = dep) == null ||
1116 <                !d.uniCompose(a = src, fn, mode > 0 ? null : this))
1115 >            Function<? super T, ? extends CompletionStage<V>> f;
1116 >            Object r; Throwable x;
1117 >            if ((d = dep) == null || (f = fn) == null
1118 >                || (a = src) == null || (r = a.result) == null)
1119                  return null;
1120 <            dep = null; src = null; fn = null;
1121 <            return d.postFire(a, mode);
1122 <        }
1123 <    }
1124 <
1125 <    final <S> boolean uniCompose(
1126 <        CompletableFuture<S> a,
1012 <        Function<? super S, ? extends CompletionStage<T>> f,
1013 <        UniCompose<S,T> c) {
1014 <        Object r; Throwable x;
1015 <        if (a == null || (r = a.result) == null || f == null)
1016 <            return false;
1017 <        tryComplete: if (result == null) {
1018 <            if (r instanceof AltResult) {
1019 <                if ((x = ((AltResult)r).ex) != null) {
1020 <                    completeThrowable(x, r);
1021 <                    break tryComplete;
1120 >            tryComplete: if (d.result == null) {
1121 >                if (r instanceof AltResult) {
1122 >                    if ((x = ((AltResult)r).ex) != null) {
1123 >                        d.completeThrowable(x, r);
1124 >                        break tryComplete;
1125 >                    }
1126 >                    r = null;
1127                  }
1128 <                r = null;
1129 <            }
1130 <            try {
1131 <                if (c != null && !c.claim())
1132 <                    return false;
1133 <                @SuppressWarnings("unchecked") S s = (S) r;
1134 <                CompletableFuture<T> g = f.apply(s).toCompletableFuture();
1135 <                if (g.result == null || !uniRelay(g)) {
1136 <                    UniRelay<T> copy = new UniRelay<T>(this, g);
1137 <                    g.push(copy);
1138 <                    copy.tryFire(SYNC);
1139 <                    if (result == null)
1140 <                        return false;
1128 >                try {
1129 >                    if (mode <= 0 && !claim())
1130 >                        return null;
1131 >                    @SuppressWarnings("unchecked") T t = (T) r;
1132 >                    CompletableFuture<V> g = f.apply(t).toCompletableFuture();
1133 >                    if ((r = g.result) != null)
1134 >                        d.completeRelay(r);
1135 >                    else {
1136 >                        g.unipush(new UniRelay<V,V>(d, g));
1137 >                        if (d.result == null)
1138 >                            return null;
1139 >                    }
1140 >                } catch (Throwable ex) {
1141 >                    d.completeThrowable(ex);
1142                  }
1037            } catch (Throwable ex) {
1038                completeThrowable(ex);
1143              }
1144 +            dep = null; src = null; fn = null;
1145 +            return d.postFire(a, mode);
1146          }
1041        return true;
1147      }
1148  
1149      private <V> CompletableFuture<V> uniComposeStage(
1150          Executor e, Function<? super T, ? extends CompletionStage<V>> f) {
1151          if (f == null) throw new NullPointerException();
1047        Object r, s; Throwable x;
1152          CompletableFuture<V> d = newIncompleteFuture();
1153 <        if ((r = result) != null && e == null) {
1153 >        Object r, s; Throwable x;
1154 >        if ((r = result) == null)
1155 >            unipush(new UniCompose<T,V>(e, d, this, f));
1156 >        else if (e == null) {
1157              if (r instanceof AltResult) {
1158                  if ((x = ((AltResult)r).ex) != null) {
1159                      d.result = encodeThrowable(x, r);
# Line 1058 | Line 1165 | public class CompletableFuture<T> implem
1165                  @SuppressWarnings("unchecked") T t = (T) r;
1166                  CompletableFuture<V> g = f.apply(t).toCompletableFuture();
1167                  if ((s = g.result) != null)
1168 <                    d.completeRelay(s);
1168 >                    d.result = encodeRelay(s);
1169                  else {
1170 <                    UniRelay<V> c = new UniRelay<V>(d, g);
1064 <                    g.push(c);
1065 <                    c.tryFire(SYNC);
1170 >                    g.unipush(new UniRelay<V,V>(d, g));
1171                  }
1067                return d;
1172              } catch (Throwable ex) {
1173                  d.result = encodeThrowable(ex);
1070                return d;
1174              }
1175          }
1176 <        UniCompose<T,V> c = new UniCompose<T,V>(e, d, this, f);
1074 <        if (r != null && e != null) {
1176 >        else
1177              try {
1178                  e.execute(new UniCompose<T,V>(null, d, this, f));
1179              } catch (Throwable ex) {
1180 <                d.completeThrowable(ex);
1180 >                d.result = encodeThrowable(ex);
1181              }
1080        }
1081        else {
1082            push(c);
1083            c.tryFire(SYNC);
1084        }
1182          return d;
1183      }
1184  
# Line 1111 | Line 1208 | public class CompletableFuture<T> implem
1208          }
1209          final boolean isLive() {
1210              BiCompletion<?,?,?> c;
1211 <            return (c = base) != null && c.dep != null;
1211 >            return (c = base) != null
1212 >                // && c.isLive()
1213 >                && c.dep != null;
1214          }
1215      }
1216  
1217 <    /** Pushes completion to this and b unless both done. */
1217 >    /**
1218 >     * Pushes completion to this and b unless both done.
1219 >     * Caller should first check that either result or b.result is null.
1220 >     */
1221      final void bipush(CompletableFuture<?> b, BiCompletion<?,?,?> c) {
1222          if (c != null) {
1223 <            Object r;
1224 <            while ((r = result) == null && !tryPushStack(c))
1225 <                lazySetNext(c, null); // clear on failure
1226 <            if (b != null && b != this && b.result == null) {
1227 <                Completion q = (r != null) ? c : new CoCompletion(c);
1228 <                while (b.result == null && !b.tryPushStack(q))
1229 <                    lazySetNext(q, null); // clear on failure
1223 >            while (result == null) {
1224 >                if (tryPushStack(c)) {
1225 >                    if (b.result == null)
1226 >                        b.unipush(new CoCompletion(c));
1227 >                    else if (result != null)
1228 >                        c.tryFire(SYNC);
1229 >                    return;
1230 >                }
1231              }
1232 +            b.unipush(c);
1233          }
1234      }
1235  
# Line 1154 | Line 1258 | public class CompletableFuture<T> implem
1258              CompletableFuture<V> d;
1259              CompletableFuture<T> a;
1260              CompletableFuture<U> b;
1261 <            if ((d = dep) == null ||
1262 <                !d.biApply(a = src, b = snd, fn, mode > 0 ? null : this))
1261 >            Object r, s; BiFunction<? super T,? super U,? extends V> f;
1262 >            if ((d = dep) == null || (f = fn) == null
1263 >                || (a = src) == null || (r = a.result) == null
1264 >                || (b = snd) == null || (s = b.result) == null
1265 >                || !d.biApply(r, s, f, mode > 0 ? null : this))
1266                  return null;
1267              dep = null; src = null; snd = null; fn = null;
1268              return d.postFire(a, b, mode);
1269          }
1270      }
1271  
1272 <    final <R,S> boolean biApply(CompletableFuture<R> a,
1166 <                                CompletableFuture<S> b,
1272 >    final <R,S> boolean biApply(Object r, Object s,
1273                                  BiFunction<? super R,? super S,? extends T> f,
1274                                  BiApply<R,S,T> c) {
1275 <        Object r, s; Throwable x;
1170 <        if (a == null || (r = a.result) == null ||
1171 <            b == null || (s = b.result) == null || f == null)
1172 <            return false;
1275 >        Throwable x;
1276          tryComplete: if (result == null) {
1277              if (r instanceof AltResult) {
1278                  if ((x = ((AltResult)r).ex) != null) {
# Line 1201 | Line 1304 | public class CompletableFuture<T> implem
1304      private <U,V> CompletableFuture<V> biApplyStage(
1305          Executor e, CompletionStage<U> o,
1306          BiFunction<? super T,? super U,? extends V> f) {
1307 <        CompletableFuture<U> b;
1307 >        CompletableFuture<U> b; Object r, s;
1308          if (f == null || (b = o.toCompletableFuture()) == null)
1309              throw new NullPointerException();
1310          CompletableFuture<V> d = newIncompleteFuture();
1311 <        if (e != null || !d.biApply(this, b, f, null)) {
1312 <            BiApply<T,U,V> c = new BiApply<T,U,V>(e, d, this, b, f);
1313 <            if (e != null && result != null && b.result != null) {
1314 <                try {
1315 <                    e.execute(c);
1316 <                } catch (Throwable ex) {
1317 <                    d.completeThrowable(ex);
1318 <                }
1319 <            }
1217 <            else {
1218 <                bipush(b, c);
1219 <                c.tryFire(SYNC);
1311 >        if ((r = result) == null || (s = b.result) == null)
1312 >            bipush(b, new BiApply<T,U,V>(e, d, this, b, f));
1313 >        else if (e == null)
1314 >            d.biApply(r, s, f, null);
1315 >        else
1316 >            try {
1317 >                e.execute(new BiApply<T,U,V>(null, d, this, b, f));
1318 >            } catch (Throwable ex) {
1319 >                d.result = encodeThrowable(ex);
1320              }
1221        }
1321          return d;
1322      }
1323  
# Line 1234 | Line 1333 | public class CompletableFuture<T> implem
1333              CompletableFuture<Void> d;
1334              CompletableFuture<T> a;
1335              CompletableFuture<U> b;
1336 <            if ((d = dep) == null ||
1337 <                !d.biAccept(a = src, b = snd, fn, mode > 0 ? null : this))
1336 >            Object r, s; BiConsumer<? super T,? super U> f;
1337 >            if ((d = dep) == null || (f = fn) == null
1338 >                || (a = src) == null || (r = a.result) == null
1339 >                || (b = snd) == null || (s = b.result) == null
1340 >                || !d.biAccept(r, s, f, mode > 0 ? null : this))
1341                  return null;
1342              dep = null; src = null; snd = null; fn = null;
1343              return d.postFire(a, b, mode);
1344          }
1345      }
1346  
1347 <    final <R,S> boolean biAccept(CompletableFuture<R> a,
1246 <                                 CompletableFuture<S> b,
1347 >    final <R,S> boolean biAccept(Object r, Object s,
1348                                   BiConsumer<? super R,? super S> f,
1349                                   BiAccept<R,S> c) {
1350 <        Object r, s; Throwable x;
1250 <        if (a == null || (r = a.result) == null ||
1251 <            b == null || (s = b.result) == null || f == null)
1252 <            return false;
1350 >        Throwable x;
1351          tryComplete: if (result == null) {
1352              if (r instanceof AltResult) {
1353                  if ((x = ((AltResult)r).ex) != null) {
# Line 1282 | Line 1380 | public class CompletableFuture<T> implem
1380      private <U> CompletableFuture<Void> biAcceptStage(
1381          Executor e, CompletionStage<U> o,
1382          BiConsumer<? super T,? super U> f) {
1383 <        CompletableFuture<U> b;
1383 >        CompletableFuture<U> b; Object r, s;
1384          if (f == null || (b = o.toCompletableFuture()) == null)
1385              throw new NullPointerException();
1386          CompletableFuture<Void> d = newIncompleteFuture();
1387 <        if (e != null || !d.biAccept(this, b, f, null)) {
1388 <            BiAccept<T,U> c = new BiAccept<T,U>(e, d, this, b, f);
1389 <            if (e != null && result != null && b.result != null) {
1390 <                try {
1391 <                    e.execute(c);
1392 <                } catch (Throwable ex) {
1393 <                    d.completeThrowable(ex);
1394 <                }
1395 <            }
1298 <            else {
1299 <                bipush(b, c);
1300 <                c.tryFire(SYNC);
1387 >        if ((r = result) == null || (s = b.result) == null)
1388 >            bipush(b, new BiAccept<T,U>(e, d, this, b, f));
1389 >        else if (e == null)
1390 >            d.biAccept(r, s, f, null);
1391 >        else
1392 >            try {
1393 >                e.execute(new BiAccept<T,U>(null, d, this, b, f));
1394 >            } catch (Throwable ex) {
1395 >                d.result = encodeThrowable(ex);
1396              }
1302        }
1397          return d;
1398      }
1399  
# Line 1307 | Line 1401 | public class CompletableFuture<T> implem
1401      static final class BiRun<T,U> extends BiCompletion<T,U,Void> {
1402          Runnable fn;
1403          BiRun(Executor executor, CompletableFuture<Void> dep,
1404 <              CompletableFuture<T> src,
1311 <              CompletableFuture<U> snd,
1404 >              CompletableFuture<T> src, CompletableFuture<U> snd,
1405                Runnable fn) {
1406              super(executor, dep, src, snd); this.fn = fn;
1407          }
# Line 1316 | Line 1409 | public class CompletableFuture<T> implem
1409              CompletableFuture<Void> d;
1410              CompletableFuture<T> a;
1411              CompletableFuture<U> b;
1412 <            if ((d = dep) == null ||
1413 <                !d.biRun(a = src, b = snd, fn, mode > 0 ? null : this))
1412 >            Object r, s; Runnable f;
1413 >            if ((d = dep) == null || (f = fn) == null
1414 >                || (a = src) == null || (r = a.result) == null
1415 >                || (b = snd) == null || (s = b.result) == null
1416 >                || !d.biRun(r, s, f, mode > 0 ? null : this))
1417                  return null;
1418              dep = null; src = null; snd = null; fn = null;
1419              return d.postFire(a, b, mode);
1420          }
1421      }
1422  
1423 <    final boolean biRun(CompletableFuture<?> a, CompletableFuture<?> b,
1424 <                        Runnable f, BiRun<?,?> c) {
1329 <        Object r, s; Throwable x;
1330 <        if (a == null || (r = a.result) == null ||
1331 <            b == null || (s = b.result) == null || f == null)
1332 <            return false;
1423 >    final boolean biRun(Object r, Object s, Runnable f, BiRun<?,?> c) {
1424 >        Throwable x; Object z;
1425          if (result == null) {
1426 <            if (r instanceof AltResult && (x = ((AltResult)r).ex) != null)
1427 <                completeThrowable(x, r);
1428 <            else if (s instanceof AltResult && (x = ((AltResult)s).ex) != null)
1429 <                completeThrowable(x, s);
1426 >            if ((r instanceof AltResult
1427 >                 && (x = ((AltResult)(z = r)).ex) != null) ||
1428 >                (s instanceof AltResult
1429 >                 && (x = ((AltResult)(z = s)).ex) != null))
1430 >                completeThrowable(x, z);
1431              else
1432                  try {
1433                      if (c != null && !c.claim())
# Line 1350 | Line 1443 | public class CompletableFuture<T> implem
1443  
1444      private CompletableFuture<Void> biRunStage(Executor e, CompletionStage<?> o,
1445                                                 Runnable f) {
1446 <        CompletableFuture<?> b;
1446 >        CompletableFuture<?> b; Object r, s;
1447          if (f == null || (b = o.toCompletableFuture()) == null)
1448              throw new NullPointerException();
1449          CompletableFuture<Void> d = newIncompleteFuture();
1450 <        if (e != null || !d.biRun(this, b, f, null)) {
1451 <            BiRun<T,?> c = new BiRun<>(e, d, this, b, f);
1452 <            if (e != null && result != null && b.result != null) {
1453 <                try {
1454 <                    e.execute(c);
1455 <                } catch (Throwable ex) {
1456 <                    d.completeThrowable(ex);
1457 <                }
1458 <            }
1366 <            else {
1367 <                bipush(b, c);
1368 <                c.tryFire(SYNC);
1450 >        if ((r = result) == null || (s = b.result) == null)
1451 >            bipush(b, new BiRun<>(e, d, this, b, f));
1452 >        else if (e == null)
1453 >            d.biRun(r, s, f, null);
1454 >        else
1455 >            try {
1456 >                e.execute(new BiRun<>(null, d, this, b, f));
1457 >            } catch (Throwable ex) {
1458 >                d.result = encodeThrowable(ex);
1459              }
1370        }
1460          return d;
1461      }
1462  
1463      @SuppressWarnings("serial")
1464      static final class BiRelay<T,U> extends BiCompletion<T,U,Void> { // for And
1465          BiRelay(CompletableFuture<Void> dep,
1466 <                CompletableFuture<T> src,
1378 <                CompletableFuture<U> snd) {
1466 >                CompletableFuture<T> src, CompletableFuture<U> snd) {
1467              super(null, dep, src, snd);
1468          }
1469          final CompletableFuture<Void> tryFire(int mode) {
1470              CompletableFuture<Void> d;
1471              CompletableFuture<T> a;
1472              CompletableFuture<U> b;
1473 <            if ((d = dep) == null || !d.biRelay(a = src, b = snd))
1473 >            Object r, s, z; Throwable x;
1474 >            if ((d = dep) == null
1475 >                || (a = src) == null || (r = a.result) == null
1476 >                || (b = snd) == null || (s = b.result) == null)
1477                  return null;
1478 +            if (d.result == null) {
1479 +                if ((r instanceof AltResult
1480 +                     && (x = ((AltResult)(z = r)).ex) != null) ||
1481 +                    (s instanceof AltResult
1482 +                     && (x = ((AltResult)(z = s)).ex) != null))
1483 +                    d.completeThrowable(x, z);
1484 +                else
1485 +                    d.completeNull();
1486 +            }
1487              src = null; snd = null; dep = null;
1488              return d.postFire(a, b, mode);
1489          }
1490      }
1491  
1392    boolean biRelay(CompletableFuture<?> a, CompletableFuture<?> b) {
1393        Object r, s; Throwable x;
1394        if (a == null || (r = a.result) == null ||
1395            b == null || (s = b.result) == null)
1396            return false;
1397        if (result == null) {
1398            if (r instanceof AltResult && (x = ((AltResult)r).ex) != null)
1399                completeThrowable(x, r);
1400            else if (s instanceof AltResult && (x = ((AltResult)s).ex) != null)
1401                completeThrowable(x, s);
1402            else
1403                completeNull();
1404        }
1405        return true;
1406    }
1407
1492      /** Recursively constructs a tree of completions. */
1493      static CompletableFuture<Void> andTree(CompletableFuture<?>[] cfs,
1494                                             int lo, int hi) {
# Line 1412 | Line 1496 | public class CompletableFuture<T> implem
1496          if (lo > hi) // empty
1497              d.result = NIL;
1498          else {
1499 <            CompletableFuture<?> a, b;
1499 >            CompletableFuture<?> a, b; Object r, s, z; Throwable x;
1500              int mid = (lo + hi) >>> 1;
1501              if ((a = (lo == mid ? cfs[lo] :
1502                        andTree(cfs, lo, mid))) == null ||
1503                  (b = (lo == hi ? a : (hi == mid+1) ? cfs[hi] :
1504                        andTree(cfs, mid+1, hi))) == null)
1505                  throw new NullPointerException();
1506 <            if (!d.biRelay(a, b)) {
1507 <                BiRelay<?,?> c = new BiRelay<>(d, a, b);
1508 <                a.bipush(b, c);
1509 <                c.tryFire(SYNC);
1510 <            }
1506 >            if ((r = a.result) == null || (s = b.result) == null)
1507 >                a.bipush(b, new BiRelay<>(d, a, b));
1508 >            else if ((r instanceof AltResult
1509 >                      && (x = ((AltResult)(z = r)).ex) != null) ||
1510 >                     (s instanceof AltResult
1511 >                      && (x = ((AltResult)(z = s)).ex) != null))
1512 >                d.result = encodeThrowable(x, z);
1513 >            else
1514 >                d.result = NIL;
1515          }
1516          return d;
1517      }
1518  
1519      /* ------------- Projected (Ored) BiCompletions -------------- */
1520  
1521 <    /** Pushes completion to this and b unless either done. */
1521 >    /**
1522 >     * Pushes completion to this and b unless either done.
1523 >     * Caller should first check that result and b.result are both null.
1524 >     */
1525      final void orpush(CompletableFuture<?> b, BiCompletion<?,?,?> c) {
1526          if (c != null) {
1527 <            while ((b == null || b.result == null) && result == null) {
1528 <                if (tryPushStack(c)) {
1529 <                    if (b != null && b != this && b.result == null) {
1439 <                        Completion q = new CoCompletion(c);
1440 <                        while (result == null && b.result == null &&
1441 <                               !b.tryPushStack(q))
1442 <                            lazySetNext(q, null); // clear on failure
1443 <                    }
1527 >            while (!tryPushStack(c)) {
1528 >                if (result != null) {
1529 >                    lazySetNext(c, null);
1530                      break;
1531                  }
1446                lazySetNext(c, null); // clear on failure
1532              }
1533 +            if (result != null)
1534 +                c.tryFire(SYNC);
1535 +            else
1536 +                b.unipush(new CoCompletion(c));
1537          }
1538      }
1539  
# Line 1452 | Line 1541 | public class CompletableFuture<T> implem
1541      static final class OrApply<T,U extends T,V> extends BiCompletion<T,U,V> {
1542          Function<? super T,? extends V> fn;
1543          OrApply(Executor executor, CompletableFuture<V> dep,
1544 <                CompletableFuture<T> src,
1456 <                CompletableFuture<U> snd,
1544 >                CompletableFuture<T> src, CompletableFuture<U> snd,
1545                  Function<? super T,? extends V> fn) {
1546              super(executor, dep, src, snd); this.fn = fn;
1547          }
# Line 1461 | Line 1549 | public class CompletableFuture<T> implem
1549              CompletableFuture<V> d;
1550              CompletableFuture<T> a;
1551              CompletableFuture<U> b;
1552 <            if ((d = dep) == null ||
1553 <                !d.orApply(a = src, b = snd, fn, mode > 0 ? null : this))
1552 >            Object r; Throwable x; Function<? super T,? extends V> f;
1553 >            if ((d = dep) == null || (f = fn) == null
1554 >                || (a = src) == null || (b = snd) == null
1555 >                || ((r = a.result) == null && (r = b.result) == null))
1556                  return null;
1557 <            dep = null; src = null; snd = null; fn = null;
1558 <            return d.postFire(a, b, mode);
1559 <        }
1560 <    }
1561 <
1562 <    final <R,S extends R> boolean orApply(CompletableFuture<R> a,
1563 <                                          CompletableFuture<S> b,
1564 <                                          Function<? super R, ? extends T> f,
1565 <                                          OrApply<R,S,T> c) {
1566 <        Object r; Throwable x;
1477 <        if (a == null || b == null ||
1478 <            ((r = a.result) == null && (r = b.result) == null) || f == null)
1479 <            return false;
1480 <        tryComplete: if (result == null) {
1481 <            try {
1482 <                if (c != null && !c.claim())
1483 <                    return false;
1484 <                if (r instanceof AltResult) {
1485 <                    if ((x = ((AltResult)r).ex) != null) {
1486 <                        completeThrowable(x, r);
1487 <                        break tryComplete;
1557 >            tryComplete: if (d.result == null) {
1558 >                try {
1559 >                    if (mode <= 0 && !claim())
1560 >                        return null;
1561 >                    if (r instanceof AltResult) {
1562 >                        if ((x = ((AltResult)r).ex) != null) {
1563 >                            d.completeThrowable(x, r);
1564 >                            break tryComplete;
1565 >                        }
1566 >                        r = null;
1567                      }
1568 <                    r = null;
1568 >                    @SuppressWarnings("unchecked") T t = (T) r;
1569 >                    d.completeValue(f.apply(t));
1570 >                } catch (Throwable ex) {
1571 >                    d.completeThrowable(ex);
1572                  }
1491                @SuppressWarnings("unchecked") R rr = (R) r;
1492                completeValue(f.apply(rr));
1493            } catch (Throwable ex) {
1494                completeThrowable(ex);
1573              }
1574 +            dep = null; src = null; snd = null; fn = null;
1575 +            return d.postFire(a, b, mode);
1576          }
1497        return true;
1577      }
1578  
1579      private <U extends T,V> CompletableFuture<V> orApplyStage(
1580 <        Executor e, CompletionStage<U> o,
1502 <        Function<? super T, ? extends V> f) {
1580 >        Executor e, CompletionStage<U> o, Function<? super T, ? extends V> f) {
1581          CompletableFuture<U> b;
1582          if (f == null || (b = o.toCompletableFuture()) == null)
1583              throw new NullPointerException();
1584 +
1585 +        Object r; CompletableFuture<? extends T> z;
1586 +        if ((r = (z = this).result) != null ||
1587 +            (r = (z = b).result) != null)
1588 +            return z.uniApplyNow(r, e, f);
1589 +
1590          CompletableFuture<V> d = newIncompleteFuture();
1591 <        if (e != null || !d.orApply(this, b, f, null)) {
1508 <            OrApply<T,U,V> c = new OrApply<T,U,V>(e, d, this, b, f);
1509 <            if (e != null && (result != null || b.result != null)) {
1510 <                try {
1511 <                    e.execute(c);
1512 <                } catch (Throwable ex) {
1513 <                    d.completeThrowable(ex);
1514 <                }
1515 <            }
1516 <            else {
1517 <                orpush(b, c);
1518 <                c.tryFire(SYNC);
1519 <            }
1520 <        }
1591 >        orpush(b, new OrApply<T,U,V>(e, d, this, b, f));
1592          return d;
1593      }
1594  
# Line 1525 | Line 1596 | public class CompletableFuture<T> implem
1596      static final class OrAccept<T,U extends T> extends BiCompletion<T,U,Void> {
1597          Consumer<? super T> fn;
1598          OrAccept(Executor executor, CompletableFuture<Void> dep,
1599 <                 CompletableFuture<T> src,
1529 <                 CompletableFuture<U> snd,
1599 >                 CompletableFuture<T> src, CompletableFuture<U> snd,
1600                   Consumer<? super T> fn) {
1601              super(executor, dep, src, snd); this.fn = fn;
1602          }
# Line 1534 | Line 1604 | public class CompletableFuture<T> implem
1604              CompletableFuture<Void> d;
1605              CompletableFuture<T> a;
1606              CompletableFuture<U> b;
1607 <            if ((d = dep) == null ||
1608 <                !d.orAccept(a = src, b = snd, fn, mode > 0 ? null : this))
1607 >            Object r; Throwable x; Consumer<? super T> f;
1608 >            if ((d = dep) == null || (f = fn) == null
1609 >                || (a = src) == null || (b = snd) == null
1610 >                || ((r = a.result) == null && (r = b.result) == null))
1611                  return null;
1612 <            dep = null; src = null; snd = null; fn = null;
1613 <            return d.postFire(a, b, mode);
1614 <        }
1615 <    }
1616 <
1617 <    final <R,S extends R> boolean orAccept(CompletableFuture<R> a,
1618 <                                           CompletableFuture<S> b,
1619 <                                           Consumer<? super R> f,
1620 <                                           OrAccept<R,S> c) {
1621 <        Object r; Throwable x;
1550 <        if (a == null || b == null ||
1551 <            ((r = a.result) == null && (r = b.result) == null) || f == null)
1552 <            return false;
1553 <        tryComplete: if (result == null) {
1554 <            try {
1555 <                if (c != null && !c.claim())
1556 <                    return false;
1557 <                if (r instanceof AltResult) {
1558 <                    if ((x = ((AltResult)r).ex) != null) {
1559 <                        completeThrowable(x, r);
1560 <                        break tryComplete;
1612 >            tryComplete: if (d.result == null) {
1613 >                try {
1614 >                    if (mode <= 0 && !claim())
1615 >                        return null;
1616 >                    if (r instanceof AltResult) {
1617 >                        if ((x = ((AltResult)r).ex) != null) {
1618 >                            d.completeThrowable(x, r);
1619 >                            break tryComplete;
1620 >                        }
1621 >                        r = null;
1622                      }
1623 <                    r = null;
1623 >                    @SuppressWarnings("unchecked") T t = (T) r;
1624 >                    f.accept(t);
1625 >                    d.completeNull();
1626 >                } catch (Throwable ex) {
1627 >                    d.completeThrowable(ex);
1628                  }
1564                @SuppressWarnings("unchecked") R rr = (R) r;
1565                f.accept(rr);
1566                completeNull();
1567            } catch (Throwable ex) {
1568                completeThrowable(ex);
1629              }
1630 +            dep = null; src = null; snd = null; fn = null;
1631 +            return d.postFire(a, b, mode);
1632          }
1571        return true;
1633      }
1634  
1635      private <U extends T> CompletableFuture<Void> orAcceptStage(
# Line 1576 | Line 1637 | public class CompletableFuture<T> implem
1637          CompletableFuture<U> b;
1638          if (f == null || (b = o.toCompletableFuture()) == null)
1639              throw new NullPointerException();
1640 +
1641 +        Object r; CompletableFuture<? extends T> z;
1642 +        if ((r = (z = this).result) != null ||
1643 +            (r = (z = b).result) != null)
1644 +            return z.uniAcceptNow(r, e, f);
1645 +
1646          CompletableFuture<Void> d = newIncompleteFuture();
1647 <        if (e != null || !d.orAccept(this, b, f, null)) {
1581 <            OrAccept<T,U> c = new OrAccept<T,U>(e, d, this, b, f);
1582 <            if (e != null && (result != null || b.result != null)) {
1583 <                try {
1584 <                    e.execute(c);
1585 <                } catch (Throwable ex) {
1586 <                    d.completeThrowable(ex);
1587 <                }
1588 <            }
1589 <            else {
1590 <                orpush(b, c);
1591 <                c.tryFire(SYNC);
1592 <            }
1593 <        }
1647 >        orpush(b, new OrAccept<T,U>(e, d, this, b, f));
1648          return d;
1649      }
1650  
# Line 1598 | Line 1652 | public class CompletableFuture<T> implem
1652      static final class OrRun<T,U> extends BiCompletion<T,U,Void> {
1653          Runnable fn;
1654          OrRun(Executor executor, CompletableFuture<Void> dep,
1655 <              CompletableFuture<T> src,
1602 <              CompletableFuture<U> snd,
1655 >              CompletableFuture<T> src, CompletableFuture<U> snd,
1656                Runnable fn) {
1657              super(executor, dep, src, snd); this.fn = fn;
1658          }
# Line 1607 | Line 1660 | public class CompletableFuture<T> implem
1660              CompletableFuture<Void> d;
1661              CompletableFuture<T> a;
1662              CompletableFuture<U> b;
1663 <            if ((d = dep) == null ||
1664 <                !d.orRun(a = src, b = snd, fn, mode > 0 ? null : this))
1663 >            Object r; Throwable x; Runnable f;
1664 >            if ((d = dep) == null || (f = fn) == null
1665 >                || (a = src) == null || (b = snd) == null
1666 >                || ((r = a.result) == null && (r = b.result) == null))
1667                  return null;
1668 <            dep = null; src = null; snd = null; fn = null;
1669 <            return d.postFire(a, b, mode);
1670 <        }
1671 <    }
1672 <
1673 <    final boolean orRun(CompletableFuture<?> a, CompletableFuture<?> b,
1674 <                        Runnable f, OrRun<?,?> c) {
1675 <        Object r; Throwable x;
1676 <        if (a == null || b == null ||
1677 <            ((r = a.result) == null && (r = b.result) == null) || f == null)
1678 <            return false;
1679 <        if (result == null) {
1680 <            try {
1626 <                if (c != null && !c.claim())
1627 <                    return false;
1628 <                if (r instanceof AltResult && (x = ((AltResult)r).ex) != null)
1629 <                    completeThrowable(x, r);
1630 <                else {
1631 <                    f.run();
1632 <                    completeNull();
1668 >            if (d.result == null) {
1669 >                try {
1670 >                    if (mode <= 0 && !claim())
1671 >                        return null;
1672 >                    else if (r instanceof AltResult
1673 >                        && (x = ((AltResult)r).ex) != null)
1674 >                        d.completeThrowable(x, r);
1675 >                    else {
1676 >                        f.run();
1677 >                        d.completeNull();
1678 >                    }
1679 >                } catch (Throwable ex) {
1680 >                    d.completeThrowable(ex);
1681                  }
1634            } catch (Throwable ex) {
1635                completeThrowable(ex);
1682              }
1683 +            dep = null; src = null; snd = null; fn = null;
1684 +            return d.postFire(a, b, mode);
1685          }
1638        return true;
1686      }
1687  
1688      private CompletableFuture<Void> orRunStage(Executor e, CompletionStage<?> o,
# Line 1643 | Line 1690 | public class CompletableFuture<T> implem
1690          CompletableFuture<?> b;
1691          if (f == null || (b = o.toCompletableFuture()) == null)
1692              throw new NullPointerException();
1693 +
1694 +        Object r; CompletableFuture<?> z;
1695 +        if ((r = (z = this).result) != null ||
1696 +            (r = (z = b).result) != null)
1697 +            return z.uniRunNow(r, e, f);
1698 +
1699          CompletableFuture<Void> d = newIncompleteFuture();
1700 <        if (e != null || !d.orRun(this, b, f, null)) {
1648 <            OrRun<T,?> c = new OrRun<>(e, d, this, b, f);
1649 <            if (e != null && (result != null || b.result != null)) {
1650 <                try {
1651 <                    e.execute(c);
1652 <                } catch (Throwable ex) {
1653 <                    d.completeThrowable(ex);
1654 <                }
1655 <            }
1656 <            else {
1657 <                orpush(b, c);
1658 <                c.tryFire(SYNC);
1659 <            }
1660 <        }
1700 >        orpush(b, new OrRun<>(e, d, this, b, f));
1701          return d;
1702      }
1703  
1704 +    /** Completion for an anyOf input future. */
1705      @SuppressWarnings("serial")
1706 <    static final class OrRelay<T,U> extends BiCompletion<T,U,Object> { // for Or
1707 <        OrRelay(CompletableFuture<Object> dep, CompletableFuture<T> src,
1708 <                CompletableFuture<U> snd) {
1709 <            super(null, dep, src, snd);
1706 >    static class AnyOf extends Completion {
1707 >        CompletableFuture<Object> dep; CompletableFuture<?> src;
1708 >        CompletableFuture<?>[] srcs;
1709 >        AnyOf(CompletableFuture<Object> dep, CompletableFuture<?> src,
1710 >              CompletableFuture<?>[] srcs) {
1711 >            this.dep = dep; this.src = src; this.srcs = srcs;
1712          }
1713          final CompletableFuture<Object> tryFire(int mode) {
1714 <            CompletableFuture<Object> d;
1715 <            CompletableFuture<T> a;
1716 <            CompletableFuture<U> b;
1717 <            if ((d = dep) == null || !d.orRelay(a = src, b = snd))
1714 >            // assert mode != ASYNC;
1715 >            CompletableFuture<Object> d; CompletableFuture<?> a;
1716 >            CompletableFuture<?>[] as;
1717 >            Object r;
1718 >            if ((d = dep) == null
1719 >                || (a = src) == null || (r = a.result) == null
1720 >                || (as = srcs) == null)
1721                  return null;
1722 <            src = null; snd = null; dep = null;
1723 <            return d.postFire(a, b, mode);
1724 <        }
1725 <    }
1726 <
1727 <    final boolean orRelay(CompletableFuture<?> a, CompletableFuture<?> b) {
1728 <        Object r;
1729 <        if (a == null || b == null ||
1730 <            ((r = a.result) == null && (r = b.result) == null))
1685 <            return false;
1686 <        if (result == null)
1687 <            completeRelay(r);
1688 <        return true;
1689 <    }
1690 <
1691 <    /** Recursively constructs a tree of completions. */
1692 <    static CompletableFuture<Object> orTree(CompletableFuture<?>[] cfs,
1693 <                                            int lo, int hi) {
1694 <        CompletableFuture<Object> d = new CompletableFuture<Object>();
1695 <        if (lo <= hi) {
1696 <            CompletableFuture<?> a, b;
1697 <            int mid = (lo + hi) >>> 1;
1698 <            if ((a = (lo == mid ? cfs[lo] :
1699 <                      orTree(cfs, lo, mid))) == null ||
1700 <                (b = (lo == hi ? a : (hi == mid+1) ? cfs[hi] :
1701 <                      orTree(cfs, mid+1, hi))) == null)
1702 <                throw new NullPointerException();
1703 <            if (!d.orRelay(a, b)) {
1704 <                OrRelay<?,?> c = new OrRelay<>(d, a, b);
1705 <                a.orpush(b, c);
1706 <                c.tryFire(SYNC);
1722 >            dep = null; src = null; srcs = null;
1723 >            if (d.completeRelay(r)) {
1724 >                for (CompletableFuture<?> b : as)
1725 >                    if (b != a)
1726 >                        b.cleanStack();
1727 >                if (mode < 0)
1728 >                    return d;
1729 >                else
1730 >                    d.postComplete();
1731              }
1732 +            return null;
1733 +        }
1734 +        final boolean isLive() {
1735 +            CompletableFuture<Object> d;
1736 +            return (d = dep) != null && d.result == null;
1737          }
1709        return d;
1738      }
1739  
1740      /* ------------- Zero-input Async forms -------------- */
# Line 1721 | Line 1749 | public class CompletableFuture<T> implem
1749  
1750          public final Void getRawResult() { return null; }
1751          public final void setRawResult(Void v) {}
1752 <        public final boolean exec() { run(); return true; }
1752 >        public final boolean exec() { run(); return false; }
1753  
1754          public void run() {
1755              CompletableFuture<T> d; Supplier<? extends T> f;
# Line 1757 | Line 1785 | public class CompletableFuture<T> implem
1785  
1786          public final Void getRawResult() { return null; }
1787          public final void setRawResult(Void v) {}
1788 <        public final boolean exec() { run(); return true; }
1788 >        public final boolean exec() { run(); return false; }
1789  
1790          public void run() {
1791              CompletableFuture<Void> d; Runnable f;
# Line 1845 | Line 1873 | public class CompletableFuture<T> implem
1873          while ((r = result) == null) {
1874              if (q == null) {
1875                  q = new Signaller(interruptible, 0L, 0L);
1876 <                ForkJoinPool.helpAsyncBlocker(defaultExecutor(), q);
1876 >                if (Thread.currentThread() instanceof ForkJoinWorkerThread)
1877 >                    ForkJoinPool.helpAsyncBlocker(defaultExecutor(), q);
1878              }
1879              else if (!queued)
1880                  queued = tryPushStack(q);
# Line 1887 | Line 1916 | public class CompletableFuture<T> implem
1916              while ((r = result) == null) { // similar to untimed
1917                  if (q == null) {
1918                      q = new Signaller(true, nanos, deadline);
1919 <                    ForkJoinPool.helpAsyncBlocker(defaultExecutor(), q);
1919 >                    if (Thread.currentThread() instanceof ForkJoinWorkerThread)
1920 >                        ForkJoinPool.helpAsyncBlocker(defaultExecutor(), q);
1921                  }
1922                  else if (!queued)
1923                      queued = tryPushStack(q);
# Line 2021 | Line 2051 | public class CompletableFuture<T> implem
2051       * @throws InterruptedException if the current thread was interrupted
2052       * while waiting
2053       */
2054 +    @SuppressWarnings("unchecked")
2055      public T get() throws InterruptedException, ExecutionException {
2056          Object r;
2057 <        return reportGet((r = result) == null ? waitingGet(true) : r);
2057 >        if ((r = result) == null)
2058 >            r = waitingGet(true);
2059 >        return (T) reportGet(r);
2060      }
2061  
2062      /**
# Line 2039 | Line 2072 | public class CompletableFuture<T> implem
2072       * while waiting
2073       * @throws TimeoutException if the wait timed out
2074       */
2075 +    @SuppressWarnings("unchecked")
2076      public T get(long timeout, TimeUnit unit)
2077          throws InterruptedException, ExecutionException, TimeoutException {
2044        Object r;
2078          long nanos = unit.toNanos(timeout);
2079 <        return reportGet((r = result) == null ? timedGet(nanos) : r);
2079 >        Object r;
2080 >        if ((r = result) == null)
2081 >            r = timedGet(nanos);
2082 >        return (T) reportGet(r);
2083      }
2084  
2085      /**
# Line 2060 | Line 2096 | public class CompletableFuture<T> implem
2096       * @throws CompletionException if this future completed
2097       * exceptionally or a completion computation threw an exception
2098       */
2099 +    @SuppressWarnings("unchecked")
2100      public T join() {
2101          Object r;
2102 <        return reportJoin((r = result) == null ? waitingGet(false) : r);
2102 >        if ((r = result) == null)
2103 >            r = waitingGet(false);
2104 >        return (T) reportJoin(r);
2105      }
2106  
2107      /**
# Line 2075 | Line 2114 | public class CompletableFuture<T> implem
2114       * @throws CompletionException if this future completed
2115       * exceptionally or a completion computation threw an exception
2116       */
2117 +    @SuppressWarnings("unchecked")
2118      public T getNow(T valueIfAbsent) {
2119          Object r;
2120 <        return ((r = result) == null) ? valueIfAbsent : reportJoin(r);
2120 >        return ((r = result) == null) ? valueIfAbsent : (T) reportJoin(r);
2121      }
2122  
2123      /**
# Line 2305 | Line 2345 | public class CompletableFuture<T> implem
2345          return this;
2346      }
2347  
2308    // not in interface CompletionStage
2309
2310    /**
2311     * Returns a new CompletableFuture that is completed when this
2312     * CompletableFuture completes, with the result of the given
2313     * function of the exception triggering this CompletableFuture's
2314     * completion when it completes exceptionally; otherwise, if this
2315     * CompletableFuture completes normally, then the returned
2316     * CompletableFuture also completes normally with the same value.
2317     * Note: More flexible versions of this functionality are
2318     * available using methods {@code whenComplete} and {@code handle}.
2319     *
2320     * @param fn the function to use to compute the value of the
2321     * returned CompletableFuture if this CompletableFuture completed
2322     * exceptionally
2323     * @return the new CompletableFuture
2324     */
2348      public CompletableFuture<T> exceptionally(
2349          Function<Throwable, ? extends T> fn) {
2350 <        return uniExceptionallyStage(fn);
2350 >        return uniExceptionallyStage(null, fn);
2351 >    }
2352 >
2353 >    public CompletableFuture<T> exceptionallyAsync(
2354 >        Function<Throwable, ? extends T> fn) {
2355 >        return uniExceptionallyStage(defaultExecutor(), fn);
2356      }
2357  
2358 +    public CompletableFuture<T> exceptionallyAsync(
2359 +        Function<Throwable, ? extends T> fn, Executor executor) {
2360 +        return uniExceptionallyStage(screenExecutor(executor), fn);
2361 +    }
2362 +
2363 +    public CompletableFuture<T> exceptionallyCompose(
2364 +        Function<Throwable, ? extends CompletionStage<T>> fn) {
2365 +        return uniComposeExceptionallyStage(null, fn);
2366 +    }
2367 +
2368 +    public CompletableFuture<T> exceptionallyComposeAsync(
2369 +        Function<Throwable, ? extends CompletionStage<T>> fn) {
2370 +        return uniComposeExceptionallyStage(defaultExecutor(), fn);
2371 +    }
2372 +
2373 +    public CompletableFuture<T> exceptionallyComposeAsync(
2374 +        Function<Throwable, ? extends CompletionStage<T>> fn,
2375 +        Executor executor) {
2376 +        return uniComposeExceptionallyStage(screenExecutor(executor), fn);
2377 +    }
2378  
2379      /* ------------- Arbitrary-arity constructions -------------- */
2380  
# Line 2373 | Line 2421 | public class CompletableFuture<T> implem
2421       * {@code null}
2422       */
2423      public static CompletableFuture<Object> anyOf(CompletableFuture<?>... cfs) {
2424 <        return orTree(cfs, 0, cfs.length - 1);
2424 >        int n; Object r;
2425 >        if ((n = cfs.length) <= 1)
2426 >            return (n == 0)
2427 >                ? new CompletableFuture<Object>()
2428 >                : uniCopyStage(cfs[0]);
2429 >        for (CompletableFuture<?> cf : cfs)
2430 >            if ((r = cf.result) != null)
2431 >                return new CompletableFuture<Object>(encodeRelay(r));
2432 >        cfs = cfs.clone();
2433 >        CompletableFuture<Object> d = new CompletableFuture<>();
2434 >        for (CompletableFuture<?> cf : cfs)
2435 >            cf.unipush(new AnyOf(d, cf, cfs));
2436 >        // If d was completed while we were adding completions, we should
2437 >        // clean the stack of any sources that may have had completions
2438 >        // pushed on their stack after d was completed.
2439 >        if (d.result != null)
2440 >            for (int i = 0, len = cfs.length; i < len; i++)
2441 >                if (cfs[i].result != null)
2442 >                    for (i++; i < len; i++)
2443 >                        if (cfs[i].result == null)
2444 >                            cfs[i].cleanStack();
2445 >        return d;
2446      }
2447  
2448      /* ------------- Control and status methods -------------- */
# Line 2489 | Line 2558 | public class CompletableFuture<T> implem
2558          for (Completion p = stack; p != null; p = p.next)
2559              ++count;
2560          return super.toString() +
2561 <            ((r == null) ?
2562 <             ((count == 0) ?
2563 <              "[Not completed]" :
2564 <              "[Not completed, " + count + " dependents]") :
2565 <             (((r instanceof AltResult) && ((AltResult)r).ex != null) ?
2566 <              "[Completed exceptionally]" :
2567 <              "[Completed normally]"));
2561 >            ((r == null)
2562 >             ? ((count == 0)
2563 >                ? "[Not completed]"
2564 >                : "[Not completed, " + count + " dependents]")
2565 >             : (((r instanceof AltResult) && ((AltResult)r).ex != null)
2566 >                ? "[Completed exceptionally: " + ((AltResult)r).ex + "]"
2567 >                : "[Completed normally]"));
2568      }
2569  
2570      // jdk9 additions
# Line 2545 | Line 2614 | public class CompletableFuture<T> implem
2614       * @since 9
2615       */
2616      public CompletableFuture<T> copy() {
2617 <        return uniCopyStage();
2617 >        return uniCopyStage(this);
2618      }
2619  
2620      /**
# Line 2558 | Line 2627 | public class CompletableFuture<T> implem
2627       * exceptionally with a CompletionException with this exception as
2628       * cause.
2629       *
2630 +     * <p>Unless overridden by a subclass, a new non-minimal
2631 +     * CompletableFuture with all methods available can be obtained from
2632 +     * a minimal CompletionStage via {@link #toCompletableFuture()}.
2633 +     * For example, completion of a minimal stage can be awaited by
2634 +     *
2635 +     * <pre> {@code minimalStage.toCompletableFuture().join(); }</pre>
2636 +     *
2637       * @return the new CompletionStage
2638       * @since 9
2639       */
# Line 2852 | Line 2928 | public class CompletableFuture<T> implem
2928          @Override public CompletableFuture<T> completeOnTimeout
2929              (T value, long timeout, TimeUnit unit) {
2930              throw new UnsupportedOperationException(); }
2931 +        @Override public CompletableFuture<T> toCompletableFuture() {
2932 +            Object r;
2933 +            if ((r = result) != null)
2934 +                return new CompletableFuture<T>(encodeRelay(r));
2935 +            else {
2936 +                CompletableFuture<T> d = new CompletableFuture<>();
2937 +                unipush(new UniRelay<T,T>(d, this));
2938 +                return d;
2939 +            }
2940 +        }
2941      }
2942  
2943      // Unsafe mechanics

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines