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.9 by jsr166, Tue Sep 26 03:44:53 2017 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 902 | Line 950 | public class CompletableFuture<T> implem
950          final CompletableFuture<T> tryFire(int mode) { // never ASYNC
951              // assert mode != ASYNC;
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, 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) {
# Line 934 | Line 983 | public class CompletableFuture<T> implem
983          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);
990 <        }
986 >        Object r;
987 >        if ((r = result) == null)
988 >            unipush(new UniExceptionally<T>(d, this, f));
989 >        else
990 >            d.uniExceptionally(r, f, null);
991          return d;
992      }
993  
994      @SuppressWarnings("serial")
995 <    static final class UniRelay<T> extends UniCompletion<T,T> { // for Compose
996 <        UniRelay(CompletableFuture<T> dep, CompletableFuture<T> src) {
995 >    static final class UniRelay<U, T extends U> extends UniCompletion<T,U> {
996 >        UniRelay(CompletableFuture<U> dep, CompletableFuture<T> src) {
997              super(null, dep, src);
998          }
999 <        final CompletableFuture<T> tryFire(int mode) {
1000 <            CompletableFuture<T> d; CompletableFuture<T> a;
1001 <            if ((d = dep) == null || !d.uniRelay(a = src))
999 >        final CompletableFuture<U> tryFire(int mode) {
1000 >            CompletableFuture<U> d; CompletableFuture<T> a; Object r;
1001 >            if ((d = dep) == null
1002 >                || (a = src) == null || (r = a.result) == null)
1003                  return null;
1004 +            if (d.result == null)
1005 +                d.completeRelay(r);
1006              src = null; dep = null;
1007              return d.postFire(a, mode);
1008          }
1009      }
1010  
1011 <    final boolean uniRelay(CompletableFuture<T> a) {
1012 <        Object r;
961 <        if (a == null || (r = a.result) == null)
962 <            return false;
963 <        if (result == null) // no need to claim
964 <            completeRelay(r);
965 <        return true;
966 <    }
967 <
968 <    private CompletableFuture<T> uniCopyStage() {
1011 >    private static <U, T extends U> CompletableFuture<U> uniCopyStage(
1012 >        CompletableFuture<T> src) {
1013          Object r;
1014 <        CompletableFuture<T> d = newIncompleteFuture();
1015 <        if ((r = result) != null)
1016 <            d.completeRelay(r);
1017 <        else {
1018 <            UniRelay<T> c = new UniRelay<T>(d, this);
975 <            push(c);
976 <            c.tryFire(SYNC);
977 <        }
1014 >        CompletableFuture<U> d = src.newIncompleteFuture();
1015 >        if ((r = src.result) != null)
1016 >            d.result = encodeRelay(r);
1017 >        else
1018 >            src.unipush(new UniRelay<U,T>(d, src));
1019          return d;
1020      }
1021  
# Line 983 | Line 1024 | public class CompletableFuture<T> implem
1024          if ((r = result) != null)
1025              return new MinimalStage<T>(encodeRelay(r));
1026          MinimalStage<T> d = new MinimalStage<T>();
1027 <        UniRelay<T> c = new UniRelay<T>(d, this);
987 <        push(c);
988 <        c.tryFire(SYNC);
1027 >        unipush(new UniRelay<T,T>(d, this));
1028          return d;
1029      }
1030  
# Line 999 | Line 1038 | public class CompletableFuture<T> implem
1038          }
1039          final CompletableFuture<V> tryFire(int mode) {
1040              CompletableFuture<V> d; CompletableFuture<T> a;
1041 <            if ((d = dep) == null ||
1042 <                !d.uniCompose(a = src, fn, mode > 0 ? null : this))
1041 >            Function<? super T, ? extends CompletionStage<V>> f;
1042 >            Object r; Throwable x;
1043 >            if ((d = dep) == null || (f = fn) == null
1044 >                || (a = src) == null || (r = a.result) == null)
1045                  return null;
1046 <            dep = null; src = null; fn = null;
1047 <            return d.postFire(a, mode);
1048 <        }
1049 <    }
1050 <
1051 <    final <S> boolean uniCompose(
1052 <        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;
1046 >            tryComplete: if (d.result == null) {
1047 >                if (r instanceof AltResult) {
1048 >                    if ((x = ((AltResult)r).ex) != null) {
1049 >                        d.completeThrowable(x, r);
1050 >                        break tryComplete;
1051 >                    }
1052 >                    r = null;
1053                  }
1054 <                r = null;
1055 <            }
1056 <            try {
1057 <                if (c != null && !c.claim())
1058 <                    return false;
1059 <                @SuppressWarnings("unchecked") S s = (S) r;
1060 <                CompletableFuture<T> g = f.apply(s).toCompletableFuture();
1061 <                if (g.result == null || !uniRelay(g)) {
1062 <                    UniRelay<T> copy = new UniRelay<T>(this, g);
1063 <                    g.push(copy);
1064 <                    copy.tryFire(SYNC);
1065 <                    if (result == null)
1066 <                        return false;
1054 >                try {
1055 >                    if (mode <= 0 && !claim())
1056 >                        return null;
1057 >                    @SuppressWarnings("unchecked") T t = (T) r;
1058 >                    CompletableFuture<V> g = f.apply(t).toCompletableFuture();
1059 >                    if ((r = g.result) != null)
1060 >                        d.completeRelay(r);
1061 >                    else {
1062 >                        g.unipush(new UniRelay<V,V>(d, g));
1063 >                        if (d.result == null)
1064 >                            return null;
1065 >                    }
1066 >                } catch (Throwable ex) {
1067 >                    d.completeThrowable(ex);
1068                  }
1037            } catch (Throwable ex) {
1038                completeThrowable(ex);
1069              }
1070 +            dep = null; src = null; fn = null;
1071 +            return d.postFire(a, mode);
1072          }
1041        return true;
1073      }
1074  
1075      private <V> CompletableFuture<V> uniComposeStage(
1076          Executor e, Function<? super T, ? extends CompletionStage<V>> f) {
1077          if (f == null) throw new NullPointerException();
1047        Object r, s; Throwable x;
1078          CompletableFuture<V> d = newIncompleteFuture();
1079 <        if ((r = result) != null && e == null) {
1079 >        Object r, s; Throwable x;
1080 >        if ((r = result) == null)
1081 >            unipush(new UniCompose<T,V>(e, d, this, f));
1082 >        else if (e == null) {
1083              if (r instanceof AltResult) {
1084                  if ((x = ((AltResult)r).ex) != null) {
1085                      d.result = encodeThrowable(x, r);
# Line 1058 | Line 1091 | public class CompletableFuture<T> implem
1091                  @SuppressWarnings("unchecked") T t = (T) r;
1092                  CompletableFuture<V> g = f.apply(t).toCompletableFuture();
1093                  if ((s = g.result) != null)
1094 <                    d.completeRelay(s);
1094 >                    d.result = encodeRelay(s);
1095                  else {
1096 <                    UniRelay<V> c = new UniRelay<V>(d, g);
1064 <                    g.push(c);
1065 <                    c.tryFire(SYNC);
1096 >                    g.unipush(new UniRelay<V,V>(d, g));
1097                  }
1067                return d;
1098              } catch (Throwable ex) {
1099                  d.result = encodeThrowable(ex);
1070                return d;
1100              }
1101          }
1102 <        UniCompose<T,V> c = new UniCompose<T,V>(e, d, this, f);
1074 <        if (r != null && e != null) {
1102 >        else
1103              try {
1104                  e.execute(new UniCompose<T,V>(null, d, this, f));
1105              } catch (Throwable ex) {
1106 <                d.completeThrowable(ex);
1106 >                d.result = encodeThrowable(ex);
1107              }
1080        }
1081        else {
1082            push(c);
1083            c.tryFire(SYNC);
1084        }
1108          return d;
1109      }
1110  
# Line 1111 | Line 1134 | public class CompletableFuture<T> implem
1134          }
1135          final boolean isLive() {
1136              BiCompletion<?,?,?> c;
1137 <            return (c = base) != null && c.dep != null;
1137 >            return (c = base) != null
1138 >                // && c.isLive()
1139 >                && c.dep != null;
1140          }
1141      }
1142  
1143 <    /** Pushes completion to this and b unless both done. */
1143 >    /**
1144 >     * Pushes completion to this and b unless both done.
1145 >     * Caller should first check that either result or b.result is null.
1146 >     */
1147      final void bipush(CompletableFuture<?> b, BiCompletion<?,?,?> c) {
1148          if (c != null) {
1149 <            Object r;
1150 <            while ((r = result) == null && !tryPushStack(c))
1151 <                lazySetNext(c, null); // clear on failure
1152 <            if (b != null && b != this && b.result == null) {
1153 <                Completion q = (r != null) ? c : new CoCompletion(c);
1154 <                while (b.result == null && !b.tryPushStack(q))
1155 <                    lazySetNext(q, null); // clear on failure
1149 >            while (result == null) {
1150 >                if (tryPushStack(c)) {
1151 >                    if (b.result == null)
1152 >                        b.unipush(new CoCompletion(c));
1153 >                    else if (result != null)
1154 >                        c.tryFire(SYNC);
1155 >                    return;
1156 >                }
1157              }
1158 +            b.unipush(c);
1159          }
1160      }
1161  
# Line 1154 | Line 1184 | public class CompletableFuture<T> implem
1184              CompletableFuture<V> d;
1185              CompletableFuture<T> a;
1186              CompletableFuture<U> b;
1187 <            if ((d = dep) == null ||
1188 <                !d.biApply(a = src, b = snd, fn, mode > 0 ? null : this))
1187 >            Object r, s; BiFunction<? super T,? super U,? extends V> f;
1188 >            if ((d = dep) == null || (f = fn) == null
1189 >                || (a = src) == null || (r = a.result) == null
1190 >                || (b = snd) == null || (s = b.result) == null
1191 >                || !d.biApply(r, s, f, mode > 0 ? null : this))
1192                  return null;
1193              dep = null; src = null; snd = null; fn = null;
1194              return d.postFire(a, b, mode);
1195          }
1196      }
1197  
1198 <    final <R,S> boolean biApply(CompletableFuture<R> a,
1166 <                                CompletableFuture<S> b,
1198 >    final <R,S> boolean biApply(Object r, Object s,
1199                                  BiFunction<? super R,? super S,? extends T> f,
1200                                  BiApply<R,S,T> c) {
1201 <        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;
1201 >        Throwable x;
1202          tryComplete: if (result == null) {
1203              if (r instanceof AltResult) {
1204                  if ((x = ((AltResult)r).ex) != null) {
# Line 1201 | Line 1230 | public class CompletableFuture<T> implem
1230      private <U,V> CompletableFuture<V> biApplyStage(
1231          Executor e, CompletionStage<U> o,
1232          BiFunction<? super T,? super U,? extends V> f) {
1233 <        CompletableFuture<U> b;
1233 >        CompletableFuture<U> b; Object r, s;
1234          if (f == null || (b = o.toCompletableFuture()) == null)
1235              throw new NullPointerException();
1236          CompletableFuture<V> d = newIncompleteFuture();
1237 <        if (e != null || !d.biApply(this, b, f, null)) {
1238 <            BiApply<T,U,V> c = new BiApply<T,U,V>(e, d, this, b, f);
1239 <            if (e != null && result != null && b.result != null) {
1240 <                try {
1241 <                    e.execute(c);
1242 <                } catch (Throwable ex) {
1243 <                    d.completeThrowable(ex);
1244 <                }
1245 <            }
1217 <            else {
1218 <                bipush(b, c);
1219 <                c.tryFire(SYNC);
1237 >        if ((r = result) == null || (s = b.result) == null)
1238 >            bipush(b, new BiApply<T,U,V>(e, d, this, b, f));
1239 >        else if (e == null)
1240 >            d.biApply(r, s, f, null);
1241 >        else
1242 >            try {
1243 >                e.execute(new BiApply<T,U,V>(null, d, this, b, f));
1244 >            } catch (Throwable ex) {
1245 >                d.result = encodeThrowable(ex);
1246              }
1221        }
1247          return d;
1248      }
1249  
# Line 1234 | Line 1259 | public class CompletableFuture<T> implem
1259              CompletableFuture<Void> d;
1260              CompletableFuture<T> a;
1261              CompletableFuture<U> b;
1262 <            if ((d = dep) == null ||
1263 <                !d.biAccept(a = src, b = snd, fn, mode > 0 ? null : this))
1262 >            Object r, s; BiConsumer<? super T,? super U> f;
1263 >            if ((d = dep) == null || (f = fn) == null
1264 >                || (a = src) == null || (r = a.result) == null
1265 >                || (b = snd) == null || (s = b.result) == null
1266 >                || !d.biAccept(r, s, f, mode > 0 ? null : this))
1267                  return null;
1268              dep = null; src = null; snd = null; fn = null;
1269              return d.postFire(a, b, mode);
1270          }
1271      }
1272  
1273 <    final <R,S> boolean biAccept(CompletableFuture<R> a,
1246 <                                 CompletableFuture<S> b,
1273 >    final <R,S> boolean biAccept(Object r, Object s,
1274                                   BiConsumer<? super R,? super S> f,
1275                                   BiAccept<R,S> c) {
1276 <        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;
1276 >        Throwable x;
1277          tryComplete: if (result == null) {
1278              if (r instanceof AltResult) {
1279                  if ((x = ((AltResult)r).ex) != null) {
# Line 1282 | Line 1306 | public class CompletableFuture<T> implem
1306      private <U> CompletableFuture<Void> biAcceptStage(
1307          Executor e, CompletionStage<U> o,
1308          BiConsumer<? super T,? super U> f) {
1309 <        CompletableFuture<U> b;
1309 >        CompletableFuture<U> b; Object r, s;
1310          if (f == null || (b = o.toCompletableFuture()) == null)
1311              throw new NullPointerException();
1312          CompletableFuture<Void> d = newIncompleteFuture();
1313 <        if (e != null || !d.biAccept(this, b, f, null)) {
1314 <            BiAccept<T,U> c = new BiAccept<T,U>(e, d, this, b, f);
1315 <            if (e != null && result != null && b.result != null) {
1316 <                try {
1317 <                    e.execute(c);
1318 <                } catch (Throwable ex) {
1319 <                    d.completeThrowable(ex);
1320 <                }
1321 <            }
1298 <            else {
1299 <                bipush(b, c);
1300 <                c.tryFire(SYNC);
1313 >        if ((r = result) == null || (s = b.result) == null)
1314 >            bipush(b, new BiAccept<T,U>(e, d, this, b, f));
1315 >        else if (e == null)
1316 >            d.biAccept(r, s, f, null);
1317 >        else
1318 >            try {
1319 >                e.execute(new BiAccept<T,U>(null, d, this, b, f));
1320 >            } catch (Throwable ex) {
1321 >                d.result = encodeThrowable(ex);
1322              }
1302        }
1323          return d;
1324      }
1325  
# Line 1307 | Line 1327 | public class CompletableFuture<T> implem
1327      static final class BiRun<T,U> extends BiCompletion<T,U,Void> {
1328          Runnable fn;
1329          BiRun(Executor executor, CompletableFuture<Void> dep,
1330 <              CompletableFuture<T> src,
1311 <              CompletableFuture<U> snd,
1330 >              CompletableFuture<T> src, CompletableFuture<U> snd,
1331                Runnable fn) {
1332              super(executor, dep, src, snd); this.fn = fn;
1333          }
# Line 1316 | Line 1335 | public class CompletableFuture<T> implem
1335              CompletableFuture<Void> d;
1336              CompletableFuture<T> a;
1337              CompletableFuture<U> b;
1338 <            if ((d = dep) == null ||
1339 <                !d.biRun(a = src, b = snd, fn, mode > 0 ? null : this))
1338 >            Object r, s; Runnable f;
1339 >            if ((d = dep) == null || (f = fn) == null
1340 >                || (a = src) == null || (r = a.result) == null
1341 >                || (b = snd) == null || (s = b.result) == null
1342 >                || !d.biRun(r, s, f, mode > 0 ? null : this))
1343                  return null;
1344              dep = null; src = null; snd = null; fn = null;
1345              return d.postFire(a, b, mode);
1346          }
1347      }
1348  
1349 <    final boolean biRun(CompletableFuture<?> a, CompletableFuture<?> b,
1350 <                        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;
1349 >    final boolean biRun(Object r, Object s, Runnable f, BiRun<?,?> c) {
1350 >        Throwable x; Object z;
1351          if (result == null) {
1352 <            if (r instanceof AltResult && (x = ((AltResult)r).ex) != null)
1353 <                completeThrowable(x, r);
1354 <            else if (s instanceof AltResult && (x = ((AltResult)s).ex) != null)
1355 <                completeThrowable(x, s);
1352 >            if ((r instanceof AltResult
1353 >                 && (x = ((AltResult)(z = r)).ex) != null) ||
1354 >                (s instanceof AltResult
1355 >                 && (x = ((AltResult)(z = s)).ex) != null))
1356 >                completeThrowable(x, z);
1357              else
1358                  try {
1359                      if (c != null && !c.claim())
# Line 1350 | Line 1369 | public class CompletableFuture<T> implem
1369  
1370      private CompletableFuture<Void> biRunStage(Executor e, CompletionStage<?> o,
1371                                                 Runnable f) {
1372 <        CompletableFuture<?> b;
1372 >        CompletableFuture<?> b; Object r, s;
1373          if (f == null || (b = o.toCompletableFuture()) == null)
1374              throw new NullPointerException();
1375          CompletableFuture<Void> d = newIncompleteFuture();
1376 <        if (e != null || !d.biRun(this, b, f, null)) {
1377 <            BiRun<T,?> c = new BiRun<>(e, d, this, b, f);
1378 <            if (e != null && result != null && b.result != null) {
1379 <                try {
1380 <                    e.execute(c);
1381 <                } catch (Throwable ex) {
1382 <                    d.completeThrowable(ex);
1383 <                }
1384 <            }
1366 <            else {
1367 <                bipush(b, c);
1368 <                c.tryFire(SYNC);
1376 >        if ((r = result) == null || (s = b.result) == null)
1377 >            bipush(b, new BiRun<>(e, d, this, b, f));
1378 >        else if (e == null)
1379 >            d.biRun(r, s, f, null);
1380 >        else
1381 >            try {
1382 >                e.execute(new BiRun<>(null, d, this, b, f));
1383 >            } catch (Throwable ex) {
1384 >                d.result = encodeThrowable(ex);
1385              }
1370        }
1386          return d;
1387      }
1388  
1389      @SuppressWarnings("serial")
1390      static final class BiRelay<T,U> extends BiCompletion<T,U,Void> { // for And
1391          BiRelay(CompletableFuture<Void> dep,
1392 <                CompletableFuture<T> src,
1378 <                CompletableFuture<U> snd) {
1392 >                CompletableFuture<T> src, CompletableFuture<U> snd) {
1393              super(null, dep, src, snd);
1394          }
1395          final CompletableFuture<Void> tryFire(int mode) {
1396              CompletableFuture<Void> d;
1397              CompletableFuture<T> a;
1398              CompletableFuture<U> b;
1399 <            if ((d = dep) == null || !d.biRelay(a = src, b = snd))
1399 >            Object r, s, z; Throwable x;
1400 >            if ((d = dep) == null
1401 >                || (a = src) == null || (r = a.result) == null
1402 >                || (b = snd) == null || (s = b.result) == null)
1403                  return null;
1404 +            if (d.result == null) {
1405 +                if ((r instanceof AltResult
1406 +                     && (x = ((AltResult)(z = r)).ex) != null) ||
1407 +                    (s instanceof AltResult
1408 +                     && (x = ((AltResult)(z = s)).ex) != null))
1409 +                    d.completeThrowable(x, z);
1410 +                else
1411 +                    d.completeNull();
1412 +            }
1413              src = null; snd = null; dep = null;
1414              return d.postFire(a, b, mode);
1415          }
1416      }
1417  
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
1418      /** Recursively constructs a tree of completions. */
1419      static CompletableFuture<Void> andTree(CompletableFuture<?>[] cfs,
1420                                             int lo, int hi) {
# Line 1412 | Line 1422 | public class CompletableFuture<T> implem
1422          if (lo > hi) // empty
1423              d.result = NIL;
1424          else {
1425 <            CompletableFuture<?> a, b;
1425 >            CompletableFuture<?> a, b; Object r, s, z; Throwable x;
1426              int mid = (lo + hi) >>> 1;
1427              if ((a = (lo == mid ? cfs[lo] :
1428                        andTree(cfs, lo, mid))) == null ||
1429                  (b = (lo == hi ? a : (hi == mid+1) ? cfs[hi] :
1430                        andTree(cfs, mid+1, hi))) == null)
1431                  throw new NullPointerException();
1432 <            if (!d.biRelay(a, b)) {
1433 <                BiRelay<?,?> c = new BiRelay<>(d, a, b);
1434 <                a.bipush(b, c);
1435 <                c.tryFire(SYNC);
1436 <            }
1432 >            if ((r = a.result) == null || (s = b.result) == null)
1433 >                a.bipush(b, new BiRelay<>(d, a, b));
1434 >            else if ((r instanceof AltResult
1435 >                      && (x = ((AltResult)(z = r)).ex) != null) ||
1436 >                     (s instanceof AltResult
1437 >                      && (x = ((AltResult)(z = s)).ex) != null))
1438 >                d.result = encodeThrowable(x, z);
1439 >            else
1440 >                d.result = NIL;
1441          }
1442          return d;
1443      }
1444  
1445      /* ------------- Projected (Ored) BiCompletions -------------- */
1446  
1447 <    /** Pushes completion to this and b unless either done. */
1447 >    /**
1448 >     * Pushes completion to this and b unless either done.
1449 >     * Caller should first check that result and b.result are both null.
1450 >     */
1451      final void orpush(CompletableFuture<?> b, BiCompletion<?,?,?> c) {
1452          if (c != null) {
1453 <            while ((b == null || b.result == null) && result == null) {
1454 <                if (tryPushStack(c)) {
1455 <                    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 <                    }
1453 >            while (!tryPushStack(c)) {
1454 >                if (result != null) {
1455 >                    lazySetNext(c, null);
1456                      break;
1457                  }
1446                lazySetNext(c, null); // clear on failure
1458              }
1459 +            if (result != null)
1460 +                c.tryFire(SYNC);
1461 +            else
1462 +                b.unipush(new CoCompletion(c));
1463          }
1464      }
1465  
# Line 1452 | Line 1467 | public class CompletableFuture<T> implem
1467      static final class OrApply<T,U extends T,V> extends BiCompletion<T,U,V> {
1468          Function<? super T,? extends V> fn;
1469          OrApply(Executor executor, CompletableFuture<V> dep,
1470 <                CompletableFuture<T> src,
1456 <                CompletableFuture<U> snd,
1470 >                CompletableFuture<T> src, CompletableFuture<U> snd,
1471                  Function<? super T,? extends V> fn) {
1472              super(executor, dep, src, snd); this.fn = fn;
1473          }
# Line 1461 | Line 1475 | public class CompletableFuture<T> implem
1475              CompletableFuture<V> d;
1476              CompletableFuture<T> a;
1477              CompletableFuture<U> b;
1478 <            if ((d = dep) == null ||
1479 <                !d.orApply(a = src, b = snd, fn, mode > 0 ? null : this))
1478 >            Object r; Throwable x; Function<? super T,? extends V> f;
1479 >            if ((d = dep) == null || (f = fn) == null
1480 >                || (a = src) == null || (b = snd) == null
1481 >                || ((r = a.result) == null && (r = b.result) == null))
1482                  return null;
1483 <            dep = null; src = null; snd = null; fn = null;
1484 <            return d.postFire(a, b, mode);
1485 <        }
1486 <    }
1487 <
1488 <    final <R,S extends R> boolean orApply(CompletableFuture<R> a,
1489 <                                          CompletableFuture<S> b,
1490 <                                          Function<? super R, ? extends T> f,
1491 <                                          OrApply<R,S,T> c) {
1492 <        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;
1483 >            tryComplete: if (d.result == null) {
1484 >                try {
1485 >                    if (mode <= 0 && !claim())
1486 >                        return null;
1487 >                    if (r instanceof AltResult) {
1488 >                        if ((x = ((AltResult)r).ex) != null) {
1489 >                            d.completeThrowable(x, r);
1490 >                            break tryComplete;
1491 >                        }
1492 >                        r = null;
1493                      }
1494 <                    r = null;
1494 >                    @SuppressWarnings("unchecked") T t = (T) r;
1495 >                    d.completeValue(f.apply(t));
1496 >                } catch (Throwable ex) {
1497 >                    d.completeThrowable(ex);
1498                  }
1491                @SuppressWarnings("unchecked") R rr = (R) r;
1492                completeValue(f.apply(rr));
1493            } catch (Throwable ex) {
1494                completeThrowable(ex);
1499              }
1500 +            dep = null; src = null; snd = null; fn = null;
1501 +            return d.postFire(a, b, mode);
1502          }
1497        return true;
1503      }
1504  
1505      private <U extends T,V> CompletableFuture<V> orApplyStage(
1506 <        Executor e, CompletionStage<U> o,
1502 <        Function<? super T, ? extends V> f) {
1506 >        Executor e, CompletionStage<U> o, Function<? super T, ? extends V> f) {
1507          CompletableFuture<U> b;
1508          if (f == null || (b = o.toCompletableFuture()) == null)
1509              throw new NullPointerException();
1510 +
1511 +        Object r; CompletableFuture<? extends T> z;
1512 +        if ((r = (z = this).result) != null ||
1513 +            (r = (z = b).result) != null)
1514 +            return z.uniApplyNow(r, e, f);
1515 +
1516          CompletableFuture<V> d = newIncompleteFuture();
1517 <        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 <        }
1517 >        orpush(b, new OrApply<T,U,V>(e, d, this, b, f));
1518          return d;
1519      }
1520  
# Line 1525 | Line 1522 | public class CompletableFuture<T> implem
1522      static final class OrAccept<T,U extends T> extends BiCompletion<T,U,Void> {
1523          Consumer<? super T> fn;
1524          OrAccept(Executor executor, CompletableFuture<Void> dep,
1525 <                 CompletableFuture<T> src,
1529 <                 CompletableFuture<U> snd,
1525 >                 CompletableFuture<T> src, CompletableFuture<U> snd,
1526                   Consumer<? super T> fn) {
1527              super(executor, dep, src, snd); this.fn = fn;
1528          }
# Line 1534 | Line 1530 | public class CompletableFuture<T> implem
1530              CompletableFuture<Void> d;
1531              CompletableFuture<T> a;
1532              CompletableFuture<U> b;
1533 <            if ((d = dep) == null ||
1534 <                !d.orAccept(a = src, b = snd, fn, mode > 0 ? null : this))
1533 >            Object r; Throwable x; Consumer<? super T> f;
1534 >            if ((d = dep) == null || (f = fn) == null
1535 >                || (a = src) == null || (b = snd) == null
1536 >                || ((r = a.result) == null && (r = b.result) == null))
1537                  return null;
1538 <            dep = null; src = null; snd = null; fn = null;
1539 <            return d.postFire(a, b, mode);
1540 <        }
1541 <    }
1542 <
1543 <    final <R,S extends R> boolean orAccept(CompletableFuture<R> a,
1544 <                                           CompletableFuture<S> b,
1545 <                                           Consumer<? super R> f,
1546 <                                           OrAccept<R,S> c) {
1547 <        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;
1538 >            tryComplete: if (d.result == null) {
1539 >                try {
1540 >                    if (mode <= 0 && !claim())
1541 >                        return null;
1542 >                    if (r instanceof AltResult) {
1543 >                        if ((x = ((AltResult)r).ex) != null) {
1544 >                            d.completeThrowable(x, r);
1545 >                            break tryComplete;
1546 >                        }
1547 >                        r = null;
1548                      }
1549 <                    r = null;
1549 >                    @SuppressWarnings("unchecked") T t = (T) r;
1550 >                    f.accept(t);
1551 >                    d.completeNull();
1552 >                } catch (Throwable ex) {
1553 >                    d.completeThrowable(ex);
1554                  }
1564                @SuppressWarnings("unchecked") R rr = (R) r;
1565                f.accept(rr);
1566                completeNull();
1567            } catch (Throwable ex) {
1568                completeThrowable(ex);
1555              }
1556 +            dep = null; src = null; snd = null; fn = null;
1557 +            return d.postFire(a, b, mode);
1558          }
1571        return true;
1559      }
1560  
1561      private <U extends T> CompletableFuture<Void> orAcceptStage(
# Line 1576 | Line 1563 | public class CompletableFuture<T> implem
1563          CompletableFuture<U> b;
1564          if (f == null || (b = o.toCompletableFuture()) == null)
1565              throw new NullPointerException();
1566 +
1567 +        Object r; CompletableFuture<? extends T> z;
1568 +        if ((r = (z = this).result) != null ||
1569 +            (r = (z = b).result) != null)
1570 +            return z.uniAcceptNow(r, e, f);
1571 +
1572          CompletableFuture<Void> d = newIncompleteFuture();
1573 <        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 <        }
1573 >        orpush(b, new OrAccept<T,U>(e, d, this, b, f));
1574          return d;
1575      }
1576  
# Line 1598 | Line 1578 | public class CompletableFuture<T> implem
1578      static final class OrRun<T,U> extends BiCompletion<T,U,Void> {
1579          Runnable fn;
1580          OrRun(Executor executor, CompletableFuture<Void> dep,
1581 <              CompletableFuture<T> src,
1602 <              CompletableFuture<U> snd,
1581 >              CompletableFuture<T> src, CompletableFuture<U> snd,
1582                Runnable fn) {
1583              super(executor, dep, src, snd); this.fn = fn;
1584          }
# Line 1607 | Line 1586 | public class CompletableFuture<T> implem
1586              CompletableFuture<Void> d;
1587              CompletableFuture<T> a;
1588              CompletableFuture<U> b;
1589 <            if ((d = dep) == null ||
1590 <                !d.orRun(a = src, b = snd, fn, mode > 0 ? null : this))
1589 >            Object r; Throwable x; Runnable f;
1590 >            if ((d = dep) == null || (f = fn) == null
1591 >                || (a = src) == null || (b = snd) == null
1592 >                || ((r = a.result) == null && (r = b.result) == null))
1593                  return null;
1594 <            dep = null; src = null; snd = null; fn = null;
1595 <            return d.postFire(a, b, mode);
1596 <        }
1597 <    }
1598 <
1599 <    final boolean orRun(CompletableFuture<?> a, CompletableFuture<?> b,
1600 <                        Runnable f, OrRun<?,?> c) {
1601 <        Object r; Throwable x;
1602 <        if (a == null || b == null ||
1603 <            ((r = a.result) == null && (r = b.result) == null) || f == null)
1604 <            return false;
1605 <        if (result == null) {
1606 <            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();
1594 >            if (d.result == null) {
1595 >                try {
1596 >                    if (mode <= 0 && !claim())
1597 >                        return null;
1598 >                    else if (r instanceof AltResult
1599 >                        && (x = ((AltResult)r).ex) != null)
1600 >                        d.completeThrowable(x, r);
1601 >                    else {
1602 >                        f.run();
1603 >                        d.completeNull();
1604 >                    }
1605 >                } catch (Throwable ex) {
1606 >                    d.completeThrowable(ex);
1607                  }
1634            } catch (Throwable ex) {
1635                completeThrowable(ex);
1608              }
1609 +            dep = null; src = null; snd = null; fn = null;
1610 +            return d.postFire(a, b, mode);
1611          }
1638        return true;
1612      }
1613  
1614      private CompletableFuture<Void> orRunStage(Executor e, CompletionStage<?> o,
# Line 1643 | Line 1616 | public class CompletableFuture<T> implem
1616          CompletableFuture<?> b;
1617          if (f == null || (b = o.toCompletableFuture()) == null)
1618              throw new NullPointerException();
1619 +
1620 +        Object r; CompletableFuture<?> z;
1621 +        if ((r = (z = this).result) != null ||
1622 +            (r = (z = b).result) != null)
1623 +            return z.uniRunNow(r, e, f);
1624 +
1625          CompletableFuture<Void> d = newIncompleteFuture();
1626 <        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 <        }
1626 >        orpush(b, new OrRun<>(e, d, this, b, f));
1627          return d;
1628      }
1629  
1630 +    /** Completion for an anyOf input future. */
1631      @SuppressWarnings("serial")
1632 <    static final class OrRelay<T,U> extends BiCompletion<T,U,Object> { // for Or
1633 <        OrRelay(CompletableFuture<Object> dep, CompletableFuture<T> src,
1634 <                CompletableFuture<U> snd) {
1635 <            super(null, dep, src, snd);
1632 >    static class AnyOf extends Completion {
1633 >        CompletableFuture<Object> dep; CompletableFuture<?> src;
1634 >        CompletableFuture<?>[] srcs;
1635 >        AnyOf(CompletableFuture<Object> dep, CompletableFuture<?> src,
1636 >              CompletableFuture<?>[] srcs) {
1637 >            this.dep = dep; this.src = src; this.srcs = srcs;
1638          }
1639          final CompletableFuture<Object> tryFire(int mode) {
1640 <            CompletableFuture<Object> d;
1641 <            CompletableFuture<T> a;
1642 <            CompletableFuture<U> b;
1643 <            if ((d = dep) == null || !d.orRelay(a = src, b = snd))
1640 >            // assert mode != ASYNC;
1641 >            CompletableFuture<Object> d; CompletableFuture<?> a;
1642 >            CompletableFuture<?>[] as;
1643 >            Object r;
1644 >            if ((d = dep) == null
1645 >                || (a = src) == null || (r = a.result) == null
1646 >                || (as = srcs) == null)
1647                  return null;
1648 <            src = null; snd = null; dep = null;
1649 <            return d.postFire(a, b, mode);
1650 <        }
1651 <    }
1652 <
1653 <    final boolean orRelay(CompletableFuture<?> a, CompletableFuture<?> b) {
1654 <        Object r;
1655 <        if (a == null || b == null ||
1656 <            ((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);
1648 >            dep = null; src = null; srcs = null;
1649 >            if (d.completeRelay(r)) {
1650 >                for (CompletableFuture<?> b : as)
1651 >                    if (b != a)
1652 >                        b.cleanStack();
1653 >                if (mode < 0)
1654 >                    return d;
1655 >                else
1656 >                    d.postComplete();
1657              }
1658 +            return null;
1659 +        }
1660 +        final boolean isLive() {
1661 +            CompletableFuture<Object> d;
1662 +            return (d = dep) != null && d.result == null;
1663          }
1709        return d;
1664      }
1665  
1666      /* ------------- Zero-input Async forms -------------- */
# Line 1721 | Line 1675 | public class CompletableFuture<T> implem
1675  
1676          public final Void getRawResult() { return null; }
1677          public final void setRawResult(Void v) {}
1678 <        public final boolean exec() { run(); return true; }
1678 >        public final boolean exec() { run(); return false; }
1679  
1680          public void run() {
1681              CompletableFuture<T> d; Supplier<? extends T> f;
# Line 1757 | Line 1711 | public class CompletableFuture<T> implem
1711  
1712          public final Void getRawResult() { return null; }
1713          public final void setRawResult(Void v) {}
1714 <        public final boolean exec() { run(); return true; }
1714 >        public final boolean exec() { run(); return false; }
1715  
1716          public void run() {
1717              CompletableFuture<Void> d; Runnable f;
# Line 1845 | Line 1799 | public class CompletableFuture<T> implem
1799          while ((r = result) == null) {
1800              if (q == null) {
1801                  q = new Signaller(interruptible, 0L, 0L);
1802 <                ForkJoinPool.helpAsyncBlocker(defaultExecutor(), q);
1802 >                if (Thread.currentThread() instanceof ForkJoinWorkerThread)
1803 >                    ForkJoinPool.helpAsyncBlocker(defaultExecutor(), q);
1804              }
1805              else if (!queued)
1806                  queued = tryPushStack(q);
# Line 1887 | Line 1842 | public class CompletableFuture<T> implem
1842              while ((r = result) == null) { // similar to untimed
1843                  if (q == null) {
1844                      q = new Signaller(true, nanos, deadline);
1845 <                    ForkJoinPool.helpAsyncBlocker(defaultExecutor(), q);
1845 >                    if (Thread.currentThread() instanceof ForkJoinWorkerThread)
1846 >                        ForkJoinPool.helpAsyncBlocker(defaultExecutor(), q);
1847                  }
1848                  else if (!queued)
1849                      queued = tryPushStack(q);
# Line 2021 | Line 1977 | public class CompletableFuture<T> implem
1977       * @throws InterruptedException if the current thread was interrupted
1978       * while waiting
1979       */
1980 +    @SuppressWarnings("unchecked")
1981      public T get() throws InterruptedException, ExecutionException {
1982          Object r;
1983 <        return reportGet((r = result) == null ? waitingGet(true) : r);
1983 >        if ((r = result) == null)
1984 >            r = waitingGet(true);
1985 >        return (T) reportGet(r);
1986      }
1987  
1988      /**
# Line 2039 | Line 1998 | public class CompletableFuture<T> implem
1998       * while waiting
1999       * @throws TimeoutException if the wait timed out
2000       */
2001 +    @SuppressWarnings("unchecked")
2002      public T get(long timeout, TimeUnit unit)
2003          throws InterruptedException, ExecutionException, TimeoutException {
2044        Object r;
2004          long nanos = unit.toNanos(timeout);
2005 <        return reportGet((r = result) == null ? timedGet(nanos) : r);
2005 >        Object r;
2006 >        if ((r = result) == null)
2007 >            r = timedGet(nanos);
2008 >        return (T) reportGet(r);
2009      }
2010  
2011      /**
# Line 2060 | Line 2022 | public class CompletableFuture<T> implem
2022       * @throws CompletionException if this future completed
2023       * exceptionally or a completion computation threw an exception
2024       */
2025 +    @SuppressWarnings("unchecked")
2026      public T join() {
2027          Object r;
2028 <        return reportJoin((r = result) == null ? waitingGet(false) : r);
2028 >        if ((r = result) == null)
2029 >            r = waitingGet(false);
2030 >        return (T) reportJoin(r);
2031      }
2032  
2033      /**
# Line 2075 | Line 2040 | public class CompletableFuture<T> implem
2040       * @throws CompletionException if this future completed
2041       * exceptionally or a completion computation threw an exception
2042       */
2043 +    @SuppressWarnings("unchecked")
2044      public T getNow(T valueIfAbsent) {
2045          Object r;
2046 <        return ((r = result) == null) ? valueIfAbsent : reportJoin(r);
2046 >        return ((r = result) == null) ? valueIfAbsent : (T) reportJoin(r);
2047      }
2048  
2049      /**
# Line 2373 | Line 2339 | public class CompletableFuture<T> implem
2339       * {@code null}
2340       */
2341      public static CompletableFuture<Object> anyOf(CompletableFuture<?>... cfs) {
2342 <        return orTree(cfs, 0, cfs.length - 1);
2342 >        int n; Object r;
2343 >        if ((n = cfs.length) <= 1)
2344 >            return (n == 0)
2345 >                ? new CompletableFuture<Object>()
2346 >                : uniCopyStage(cfs[0]);
2347 >        for (CompletableFuture<?> cf : cfs)
2348 >            if ((r = cf.result) != null)
2349 >                return new CompletableFuture<Object>(encodeRelay(r));
2350 >        cfs = cfs.clone();
2351 >        CompletableFuture<Object> d = new CompletableFuture<>();
2352 >        for (CompletableFuture<?> cf : cfs)
2353 >            cf.unipush(new AnyOf(d, cf, cfs));
2354 >        // If d was completed while we were adding completions, we should
2355 >        // clean the stack of any sources that may have had completions
2356 >        // pushed on their stack after d was completed.
2357 >        if (d.result != null)
2358 >            for (int i = 0, len = cfs.length; i < len; i++)
2359 >                if (cfs[i].result != null)
2360 >                    for (i++; i < len; i++)
2361 >                        if (cfs[i].result == null)
2362 >                            cfs[i].cleanStack();
2363 >        return d;
2364      }
2365  
2366      /* ------------- Control and status methods -------------- */
# Line 2489 | Line 2476 | public class CompletableFuture<T> implem
2476          for (Completion p = stack; p != null; p = p.next)
2477              ++count;
2478          return super.toString() +
2479 <            ((r == null) ?
2480 <             ((count == 0) ?
2481 <              "[Not completed]" :
2482 <              "[Not completed, " + count + " dependents]") :
2483 <             (((r instanceof AltResult) && ((AltResult)r).ex != null) ?
2484 <              "[Completed exceptionally]" :
2485 <              "[Completed normally]"));
2479 >            ((r == null)
2480 >             ? ((count == 0)
2481 >                ? "[Not completed]"
2482 >                : "[Not completed, " + count + " dependents]")
2483 >             : (((r instanceof AltResult) && ((AltResult)r).ex != null)
2484 >                ? "[Completed exceptionally: " + ((AltResult)r).ex + "]"
2485 >                : "[Completed normally]"));
2486      }
2487  
2488      // jdk9 additions
# Line 2545 | Line 2532 | public class CompletableFuture<T> implem
2532       * @since 9
2533       */
2534      public CompletableFuture<T> copy() {
2535 <        return uniCopyStage();
2535 >        return uniCopyStage(this);
2536      }
2537  
2538      /**
# Line 2558 | Line 2545 | public class CompletableFuture<T> implem
2545       * exceptionally with a CompletionException with this exception as
2546       * cause.
2547       *
2548 +     * <p>Unless overridden by a subclass, a new non-minimal
2549 +     * CompletableFuture with all methods available can be obtained from
2550 +     * a minimal CompletionStage via {@link #toCompletableFuture()}.
2551 +     * For example, completion of a minimal stage can be awaited by
2552 +     *
2553 +     * <pre> {@code minimalStage.toCompletableFuture().join(); }</pre>
2554 +     *
2555       * @return the new CompletionStage
2556       * @since 9
2557       */
# Line 2852 | Line 2846 | public class CompletableFuture<T> implem
2846          @Override public CompletableFuture<T> completeOnTimeout
2847              (T value, long timeout, TimeUnit unit) {
2848              throw new UnsupportedOperationException(); }
2849 +        @Override public CompletableFuture<T> toCompletableFuture() {
2850 +            Object r;
2851 +            if ((r = result) != null)
2852 +                return new CompletableFuture<T>(encodeRelay(r));
2853 +            else {
2854 +                CompletableFuture<T> d = new CompletableFuture<>();
2855 +                unipush(new UniRelay<T,T>(d, this));
2856 +                return d;
2857 +            }
2858 +        }
2859      }
2860  
2861      // Unsafe mechanics

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines