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.2 by dl, Sat Apr 2 17:45:34 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 207 | Line 218 | public class CompletableFuture<T> implem
218       * pointing back to its sources. So we null out fields as soon as
219       * possible.  The screening checks needed anyway harmlessly ignore
220       * null arguments that may have been obtained during races with
221 <     * threads nulling out fields.  We also try to unlink fired
222 <     * Completions from stacks that might never be popped (see method
223 <     * postFire).  Completion fields need not be declared as final or
224 <     * volatile because they are only visible to other threads upon
225 <     * safe publication.
221 >     * threads nulling out fields.  We also try to unlink non-isLive
222 >     * (fired or cancelled) Completions from stacks that might
223 >     * otherwise never be popped: Method cleanStack always unlinks non
224 >     * isLive completions from the head of stack; others may
225 >     * occasionally remain if racing with other cancellations or
226 >     * removals.
227 >     *
228 >     * Completion fields need not be declared as final or volatile
229 >     * because they are only visible to other threads upon safe
230 >     * publication.
231       */
232  
233      volatile Object result;       // Either the result or boxed AltResult
# Line 322 | 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 340 | 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 355 | Line 372 | public class CompletableFuture<T> implem
372                  x = cause;
373              throw new ExecutionException(x);
374          }
375 <        @SuppressWarnings("unchecked") T t = (T) r;
359 <        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 373 | Line 389 | public class CompletableFuture<T> implem
389                  throw (CompletionException)x;
390              throw new CompletionException(x);
391          }
392 <        @SuppressWarnings("unchecked") T t = (T) r;
377 <        return t;
392 >        return r;
393      }
394  
395      /* ------------- Async task preliminaries -------------- */
# Line 448 | Line 463 | public class CompletableFuture<T> implem
463          U.putOrderedObject(c, NEXT, next);
464      }
465  
466 +    static boolean casNext(Completion c, Completion cmp, Completion val) {
467 +        return U.compareAndSwapObject(c, NEXT, cmp, val);
468 +    }
469 +
470      /**
471       * Pops and tries to trigger all reachable dependents.  Call only
472       * when known to be done.
# Line 468 | Line 487 | public class CompletableFuture<T> implem
487                          pushStack(h);
488                          continue;
489                      }
490 <                    h.next = null;    // detach
490 >                    casNext(h, t, null);    // try to detach
491                  }
492                  f = (d = h.tryFire(NESTED)) == null ? this : d;
493              }
494          }
495      }
496  
497 <    /** Traverses stack and unlinks dead Completions. */
497 >    /** Traverses stack and unlinks one or more dead Completions, if found. */
498      final void cleanStack() {
499 <        for (Completion p = null, q = stack; q != null;) {
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;
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 <            }
522 <            else if (p == null) {
523 <                casStack(q, s);
524 <                q = stack;
489 <            }
490 <            else {
491 <                p.next = s;
492 <                if (p.isLive())
493 <                    q = s;
494 <                else {
495 <                    p = null;  // restart
496 <                    q = stack;
497 <                }
498 <            }
521 >            } else if (casNext(p, q, s))
522 >                break;
523 >            else
524 >                q = p.next;
525          }
526      }
527  
# Line 533 | 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) {
586 <            if (a.result == null)
586 >            Object r;
587 >            if ((r = a.result) == null)
588                  a.cleanStack();
589 <            else if (mode >= 0)
589 >            if (mode >= 0 && (r != null || a.result != null))
590                  a.postComplete();
591          }
592          if (result != null && stack != null) {
# Line 572 | 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                  }
595                r = null;
596            }
597            try {
598                if (c != null && !c.claim())
599                    return false;
600                @SuppressWarnings("unchecked") S s = (S) r;
601                completeValue(f.apply(s));
602            } catch (Throwable ex) {
603                completeThrowable(ex);
633              }
634 +            dep = null; src = null; fn = null;
635 +            return d.postFire(a, mode);
636          }
606        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 636 | 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                  }
658                r = null;
659            }
660            try {
661                if (c != null && !c.claim())
662                    return false;
663                @SuppressWarnings("unchecked") S s = (S) r;
664                f.accept(s);
665                completeNull();
666            } catch (Throwable ex) {
667                completeThrowable(ex);
706              }
707 +            dep = null; src = null; fn = null;
708 +            return d.postFire(a, mode);
709          }
670        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 700 | 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  
711    final boolean uniRun(CompletableFuture<?> a, Runnable f, UniRun<?> c) {
712        Object r; Throwable x;
713        if (a == null || (r = a.result) == null || f == null)
714            return false;
715        if (result == null) {
716            if (r instanceof AltResult && (x = ((AltResult)r).ex) != null)
717                completeThrowable(x, r);
718            else
719                try {
720                    if (c != null && !c.claim())
721                        return false;
722                    f.run();
723                    completeNull();
724                } catch (Throwable ex) {
725                    completeThrowable(ex);
726                }
727        }
728        return true;
729    }
730
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              }
743            else {
744                push(c);
745                c.tryFire(SYNC);
746            }
747        }
807          return d;
808      }
809  
# Line 758 | 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;
773 <        if (a == null || (r = a.result) == null || f == null)
774 <            return false;
833 >        T t; Throwable x = null;
834          if (result == null) {
835              try {
836                  if (c != null && !c.claim())
# Line 803 | 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 {
816 <                push(c);
817 <                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 830 | 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;
845 <        if (a == null || (r = a.result) == null || f == null)
846 <            return false;
903 >        S s; Throwable x;
904          if (result == null) {
905              try {
906                  if (c != null && !c.claim())
# Line 868 | 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 {
881 <                push(c);
882 <                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 888 | 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
896 <            // 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;
909 <        if (a == null || (r = a.result) == null || f == null)
910 <            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 924 | 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 976 | 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);
980 <        push(c);
981 <        c.tryFire(SYNC);
1101 >        unipush(new UniRelay<T,T>(d, this));
1102          return d;
1103      }
1104  
# Line 992 | 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,
1005 <        Function<? super S, ? extends CompletionStage<T>> f,
1006 <        UniCompose<S,T> c) {
1007 <        Object r; Throwable x;
1008 <        if (a == null || (r = a.result) == null || f == null)
1009 <            return false;
1010 <        tryComplete: if (result == null) {
1011 <            if (r instanceof AltResult) {
1012 <                if ((x = ((AltResult)r).ex) != null) {
1013 <                    completeThrowable(x, r);
1014 <                    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                  }
1030            } catch (Throwable ex) {
1031                completeThrowable(ex);
1143              }
1144 +            dep = null; src = null; fn = null;
1145 +            return d.postFire(a, mode);
1146          }
1034        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();
1040        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 1051 | 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);
1057 <                    g.push(c);
1058 <                    c.tryFire(SYNC);
1170 >                    g.unipush(new UniRelay<V,V>(d, g));
1171                  }
1060                return d;
1172              } catch (Throwable ex) {
1173                  d.result = encodeThrowable(ex);
1063                return d;
1174              }
1175          }
1176 <        UniCompose<T,V> c = new UniCompose<T,V>(e, d, this, f);
1067 <        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              }
1073        }
1074        else {
1075            push(c);
1076            c.tryFire(SYNC);
1077        }
1182          return d;
1183      }
1184  
# Line 1104 | 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 1126 | Line 1237 | public class CompletableFuture<T> implem
1237      final CompletableFuture<T> postFire(CompletableFuture<?> a,
1238                                          CompletableFuture<?> b, int mode) {
1239          if (b != null && b.stack != null) { // clean second source
1240 <            if (b.result == null)
1240 >            Object r;
1241 >            if ((r = b.result) == null)
1242                  b.cleanStack();
1243 <            else if (mode >= 0)
1243 >            if (mode >= 0 && (r != null || b.result != null))
1244                  b.postComplete();
1245          }
1246          return postFire(a, mode);
# Line 1146 | 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,
1158 <                                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;
1162 <        if (a == null || (r = a.result) == null ||
1163 <            b == null || (s = b.result) == null || f == null)
1164 <            return false;
1275 >        Throwable x;
1276          tryComplete: if (result == null) {
1277              if (r instanceof AltResult) {
1278                  if ((x = ((AltResult)r).ex) != null) {
# Line 1193 | 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 <            }
1209 <            else {
1210 <                bipush(b, c);
1211 <                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              }
1213        }
1321          return d;
1322      }
1323  
# Line 1226 | 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,
1238 <                                 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;
1242 <        if (a == null || (r = a.result) == null ||
1243 <            b == null || (s = b.result) == null || f == null)
1244 <            return false;
1350 >        Throwable x;
1351          tryComplete: if (result == null) {
1352              if (r instanceof AltResult) {
1353                  if ((x = ((AltResult)r).ex) != null) {
# Line 1274 | 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 <            }
1290 <            else {
1291 <                bipush(b, c);
1292 <                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              }
1294        }
1397          return d;
1398      }
1399  
# Line 1299 | 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,
1303 <              CompletableFuture<U> snd,
1404 >              CompletableFuture<T> src, CompletableFuture<U> snd,
1405                Runnable fn) {
1406              super(executor, dep, src, snd); this.fn = fn;
1407          }
# Line 1308 | 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) {
1321 <        Object r, s; Throwable x;
1322 <        if (a == null || (r = a.result) == null ||
1323 <            b == null || (s = b.result) == null || f == null)
1324 <            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 1342 | 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 <            }
1358 <            else {
1359 <                bipush(b, c);
1360 <                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              }
1362        }
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,
1370 <                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  
1384    boolean biRelay(CompletableFuture<?> a, CompletableFuture<?> b) {
1385        Object r, s; Throwable x;
1386        if (a == null || (r = a.result) == null ||
1387            b == null || (s = b.result) == null)
1388            return false;
1389        if (result == null) {
1390            if (r instanceof AltResult && (x = ((AltResult)r).ex) != null)
1391                completeThrowable(x, r);
1392            else if (s instanceof AltResult && (x = ((AltResult)s).ex) != null)
1393                completeThrowable(x, s);
1394            else
1395                completeNull();
1396        }
1397        return true;
1398    }
1399
1492      /** Recursively constructs a tree of completions. */
1493      static CompletableFuture<Void> andTree(CompletableFuture<?>[] cfs,
1494                                             int lo, int hi) {
# Line 1404 | 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) {
1431 <                        Completion q = new CoCompletion(c);
1432 <                        while (result == null && b.result == null &&
1433 <                               !b.tryPushStack(q))
1434 <                            lazySetNext(q, null); // clear on failure
1435 <                    }
1527 >            while (!tryPushStack(c)) {
1528 >                if (result != null) {
1529 >                    lazySetNext(c, null);
1530                      break;
1531                  }
1438                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 1444 | 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,
1448 <                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 1453 | 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;
1469 <        if (a == null || b == null ||
1470 <            ((r = a.result) == null && (r = b.result) == null) || f == null)
1471 <            return false;
1472 <        tryComplete: if (result == null) {
1473 <            try {
1474 <                if (c != null && !c.claim())
1475 <                    return false;
1476 <                if (r instanceof AltResult) {
1477 <                    if ((x = ((AltResult)r).ex) != null) {
1478 <                        completeThrowable(x, r);
1479 <                        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                  }
1483                @SuppressWarnings("unchecked") R rr = (R) r;
1484                completeValue(f.apply(rr));
1485            } catch (Throwable ex) {
1486                completeThrowable(ex);
1573              }
1574 +            dep = null; src = null; snd = null; fn = null;
1575 +            return d.postFire(a, b, mode);
1576          }
1489        return true;
1577      }
1578  
1579      private <U extends T,V> CompletableFuture<V> orApplyStage(
1580 <        Executor e, CompletionStage<U> o,
1494 <        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)) {
1500 <            OrApply<T,U,V> c = new OrApply<T,U,V>(e, d, this, b, f);
1501 <            if (e != null && (result != null || b.result != null)) {
1502 <                try {
1503 <                    e.execute(c);
1504 <                } catch (Throwable ex) {
1505 <                    d.completeThrowable(ex);
1506 <                }
1507 <            }
1508 <            else {
1509 <                orpush(b, c);
1510 <                c.tryFire(SYNC);
1511 <            }
1512 <        }
1591 >        orpush(b, new OrApply<T,U,V>(e, d, this, b, f));
1592          return d;
1593      }
1594  
# Line 1517 | 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,
1521 <                 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 1526 | 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;
1542 <        if (a == null || b == null ||
1543 <            ((r = a.result) == null && (r = b.result) == null) || f == null)
1544 <            return false;
1545 <        tryComplete: if (result == null) {
1546 <            try {
1547 <                if (c != null && !c.claim())
1548 <                    return false;
1549 <                if (r instanceof AltResult) {
1550 <                    if ((x = ((AltResult)r).ex) != null) {
1551 <                        completeThrowable(x, r);
1552 <                        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                  }
1556                @SuppressWarnings("unchecked") R rr = (R) r;
1557                f.accept(rr);
1558                completeNull();
1559            } catch (Throwable ex) {
1560                completeThrowable(ex);
1629              }
1630 +            dep = null; src = null; snd = null; fn = null;
1631 +            return d.postFire(a, b, mode);
1632          }
1563        return true;
1633      }
1634  
1635      private <U extends T> CompletableFuture<Void> orAcceptStage(
# Line 1568 | 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)) {
1573 <            OrAccept<T,U> c = new OrAccept<T,U>(e, d, this, b, f);
1574 <            if (e != null && (result != null || b.result != null)) {
1575 <                try {
1576 <                    e.execute(c);
1577 <                } catch (Throwable ex) {
1578 <                    d.completeThrowable(ex);
1579 <                }
1580 <            }
1581 <            else {
1582 <                orpush(b, c);
1583 <                c.tryFire(SYNC);
1584 <            }
1585 <        }
1647 >        orpush(b, new OrAccept<T,U>(e, d, this, b, f));
1648          return d;
1649      }
1650  
# Line 1590 | 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,
1594 <              CompletableFuture<U> snd,
1655 >              CompletableFuture<T> src, CompletableFuture<U> snd,
1656                Runnable fn) {
1657              super(executor, dep, src, snd); this.fn = fn;
1658          }
# Line 1599 | 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 {
1618 <                if (c != null && !c.claim())
1619 <                    return false;
1620 <                if (r instanceof AltResult && (x = ((AltResult)r).ex) != null)
1621 <                    completeThrowable(x, r);
1622 <                else {
1623 <                    f.run();
1624 <                    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                  }
1626            } catch (Throwable ex) {
1627                completeThrowable(ex);
1682              }
1683 +            dep = null; src = null; snd = null; fn = null;
1684 +            return d.postFire(a, b, mode);
1685          }
1630        return true;
1686      }
1687  
1688      private CompletableFuture<Void> orRunStage(Executor e, CompletionStage<?> o,
# Line 1635 | 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)) {
1640 <            OrRun<T,?> c = new OrRun<>(e, d, this, b, f);
1641 <            if (e != null && (result != null || b.result != null)) {
1642 <                try {
1643 <                    e.execute(c);
1644 <                } catch (Throwable ex) {
1645 <                    d.completeThrowable(ex);
1646 <                }
1647 <            }
1648 <            else {
1649 <                orpush(b, c);
1650 <                c.tryFire(SYNC);
1651 <            }
1652 <        }
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))
1677 <            return false;
1678 <        if (result == null)
1679 <            completeRelay(r);
1680 <        return true;
1681 <    }
1682 <
1683 <    /** Recursively constructs a tree of completions. */
1684 <    static CompletableFuture<Object> orTree(CompletableFuture<?>[] cfs,
1685 <                                            int lo, int hi) {
1686 <        CompletableFuture<Object> d = new CompletableFuture<Object>();
1687 <        if (lo <= hi) {
1688 <            CompletableFuture<?> a, b;
1689 <            int mid = (lo + hi) >>> 1;
1690 <            if ((a = (lo == mid ? cfs[lo] :
1691 <                      orTree(cfs, lo, mid))) == null ||
1692 <                (b = (lo == hi ? a : (hi == mid+1) ? cfs[hi] :
1693 <                      orTree(cfs, mid+1, hi))) == null)
1694 <                throw new NullPointerException();
1695 <            if (!d.orRelay(a, b)) {
1696 <                OrRelay<?,?> c = new OrRelay<>(d, a, b);
1697 <                a.orpush(b, c);
1698 <                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          }
1701        return d;
1738      }
1739  
1740      /* ------------- Zero-input Async forms -------------- */
# Line 1713 | 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 1749 | 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 1837 | 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 1851 | Line 1888 | public class CompletableFuture<T> implem
1888                      break;
1889              }
1890          }
1891 <        if (q != null) {
1891 >        if (q != null && queued) {
1892              q.thread = null;
1893 <            if (q.interrupted) {
1894 <                if (interruptible)
1895 <                    cleanStack();
1896 <                else
1860 <                    Thread.currentThread().interrupt();
1861 <            }
1893 >            if (!interruptible && q.interrupted)
1894 >                Thread.currentThread().interrupt();
1895 >            if (r == null)
1896 >                cleanStack();
1897          }
1898 <        if (r != null)
1898 >        if (r != null || (r = result) != null)
1899              postComplete();
1900          return r;
1901      }
# Line 1881 | 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 1897 | Line 1933 | public class CompletableFuture<T> implem
1933                          break;
1934                  }
1935              }
1936 <            if (q != null)
1936 >            if (q != null && queued) {
1937                  q.thread = null;
1938 <            if (r != null)
1938 >                if (r == null)
1939 >                    cleanStack();
1940 >            }
1941 >            if (r != null || (r = result) != null)
1942                  postComplete();
1904            else
1905                cleanStack();
1943              if (r != null || (q != null && q.interrupted))
1944                  return r;
1945          }
# Line 2014 | 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 2032 | 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 {
2037        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 2053 | 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 2068 | 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 2298 | Line 2345 | public class CompletableFuture<T> implem
2345          return this;
2346      }
2347  
2301    // not in interface CompletionStage
2302
2303    /**
2304     * Returns a new CompletableFuture that is completed when this
2305     * CompletableFuture completes, with the result of the given
2306     * function of the exception triggering this CompletableFuture's
2307     * completion when it completes exceptionally; otherwise, if this
2308     * CompletableFuture completes normally, then the returned
2309     * CompletableFuture also completes normally with the same value.
2310     * Note: More flexible versions of this functionality are
2311     * available using methods {@code whenComplete} and {@code handle}.
2312     *
2313     * @param fn the function to use to compute the value of the
2314     * returned CompletableFuture if this CompletableFuture completed
2315     * exceptionally
2316     * @return the new CompletableFuture
2317     */
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 2366 | 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 2482 | 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 2538 | 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 2551 | 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 2845 | 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