usedKeys = new HashSet<>();
diff --git a/sources/net.sf.j2s.java.core/src/java/util/concurrent/CompletableFuture.java b/sources/net.sf.j2s.java.core/src/java/util/concurrent/CompletableFuture.java
index f4a111ea2..b712bd38d 100644
--- a/sources/net.sf.j2s.java.core/src/java/util/concurrent/CompletableFuture.java
+++ b/sources/net.sf.j2s.java.core/src/java/util/concurrent/CompletableFuture.java
@@ -34,6 +34,7 @@
*/
package java.util.concurrent;
+
import java.util.function.Supplier;
import java.util.function.Consumer;
import java.util.function.BiConsumer;
@@ -53,2334 +54,2348 @@
import java.util.concurrent.locks.LockSupport;
/**
- * A {@link Future} that may be explicitly completed (setting its
- * value and status), and may be used as a {@link CompletionStage},
- * supporting dependent functions and actions that trigger upon its
- * completion.
+ * A {@link Future} that may be explicitly completed (setting its value and
+ * status), and may be used as a {@link CompletionStage}, supporting dependent
+ * functions and actions that trigger upon its completion.
*
- * When two or more threads attempt to
- * {@link #complete complete},
- * {@link #completeExceptionally completeExceptionally}, or
- * {@link #cancel cancel}
- * a CompletableFuture, only one of them succeeds.
+ *
+ * When two or more threads attempt to {@link #complete complete},
+ * {@link #completeExceptionally completeExceptionally}, or {@link #cancel
+ * cancel} a CompletableFuture, only one of them succeeds.
*
- *
In addition to these and related methods for directly
- * manipulating status and results, CompletableFuture implements
- * interface {@link CompletionStage} with the following policies:
+ *
+ * In addition to these and related methods for directly manipulating status and
+ * results, CompletableFuture implements interface {@link CompletionStage} with
+ * the following policies:
+ *
*
- * - Actions supplied for dependent completions of
- * non-async methods may be performed by the thread that
- * completes the current CompletableFuture, or by any other caller of
- * a completion method.
+ * - Actions supplied for dependent completions of non-async methods
+ * may be performed by the thread that completes the current CompletableFuture,
+ * or by any other caller of a completion method.
*
- * - All async methods without an explicit Executor
- * argument are performed using the {@link ForkJoinPool#commonPool()}
- * (unless it does not support a parallelism level of at least two, in
- * which case, a new Thread is created to run each task). To simplify
- * monitoring, debugging, and tracking, all generated asynchronous
- * tasks are instances of the marker interface {@link
- * AsynchronousCompletionTask}.
+ * - All async methods without an explicit Executor argument are
+ * performed using the {@link ForkJoinPool#commonPool()} (unless it does not
+ * support a parallelism level of at least two, in which case, a new Thread is
+ * created to run each task). To simplify monitoring, debugging, and tracking,
+ * all generated asynchronous tasks are instances of the marker interface
+ * {@link AsynchronousCompletionTask}.
*
- * - All CompletionStage methods are implemented independently of
- * other public methods, so the behavior of one method is not impacted
- * by overrides of others in subclasses.
+ * - All CompletionStage methods are implemented independently of other public
+ * methods, so the behavior of one method is not impacted by overrides of others
+ * in subclasses.
+ *
*
- * CompletableFuture also implements {@link Future} with the following
- * policies:
*
* @author Doug Lea
* @since 1.8
*/
public class CompletableFuture implements Future, CompletionStage {
- /*
- * Overview:
- *
- * A CompletableFuture may have dependent completion actions,
- * collected in a linked stack. It atomically completes by CASing
- * a result field, and then pops off and runs those actions. This
- * applies across normal vs exceptional outcomes, sync vs async
- * actions, binary triggers, and various forms of completions.
- *
- * Non-nullness of field result (set via CAS) indicates done. An
- * AltResult is used to box null as a result, as well as to hold
- * exceptions. Using a single field makes completion simple to
- * detect and trigger. Encoding and decoding is straightforward
- * but adds to the sprawl of trapping and associating exceptions
- * with targets. Minor simplifications rely on (static) NIL (to
- * box null results) being the only AltResult with a null
- * exception field, so we don't usually need explicit comparisons.
- * Even though some of the generics casts are unchecked (see
- * SuppressWarnings annotations), they are placed to be
- * appropriate even if checked.
- *
- * Dependent actions are represented by Completion objects linked
- * as Treiber stacks headed by field "stack". There are Completion
- * classes for each kind of action, grouped into single-input
- * (UniCompletion), two-input (BiCompletion), projected
- * (BiCompletions using either (not both) of two inputs), shared
- * (CoCompletion, used by the second of two sources), zero-input
- * source actions, and Signallers that unblock waiters. Class
- * Completion extends ForkJoinTask to enable async execution
- * (adding no space overhead because we exploit its "tag" methods
- * to maintain claims). It is also declared as Runnable to allow
- * usage with arbitrary executors.
- *
- * Support for each kind of CompletionStage relies on a separate
- * class, along with two CompletableFuture methods:
- *
- * * A Completion class with name X corresponding to function,
- * prefaced with "Uni", "Bi", or "Or". Each class contains
- * fields for source(s), actions, and dependent. They are
- * boringly similar, differing from others only with respect to
- * underlying functional forms. We do this so that users don't
- * encounter layers of adaptors in common usages. We also
- * include "Relay" classes/methods that don't correspond to user
- * methods; they copy results from one stage to another.
- *
- * * Boolean CompletableFuture method x(...) (for example
- * uniApply) takes all of the arguments needed to check that an
- * action is triggerable, and then either runs the action or
- * arranges its async execution by executing its Completion
- * argument, if present. The method returns true if known to be
- * complete.
- *
- * * Completion method tryFire(int mode) invokes the associated x
- * method with its held arguments, and on success cleans up.
- * The mode argument allows tryFire to be called twice (SYNC,
- * then ASYNC); the first to screen and trap exceptions while
- * arranging to execute, and the second when called from a
- * task. (A few classes are not used async so take slightly
- * different forms.) The claim() callback suppresses function
- * invocation if already claimed by another thread.
- *
- * * CompletableFuture method xStage(...) is called from a public
- * stage method of CompletableFuture x. It screens user
- * arguments and invokes and/or creates the stage object. If
- * not async and x is already complete, the action is run
- * immediately. Otherwise a Completion c is created, pushed to
- * x's stack (unless done), and started or triggered via
- * c.tryFire. This also covers races possible if x completes
- * while pushing. Classes with two inputs (for example BiApply)
- * deal with races across both while pushing actions. The
- * second completion is a CoCompletion pointing to the first,
- * shared so that at most one performs the action. The
- * multiple-arity methods allOf and anyOf do this pairwise to
- * form trees of completions.
- *
- * Note that the generic type parameters of methods vary according
- * to whether "this" is a source, dependent, or completion.
- *
- * Method postComplete is called upon completion unless the target
- * is guaranteed not to be observable (i.e., not yet returned or
- * linked). Multiple threads can call postComplete, which
- * atomically pops each dependent action, and tries to trigger it
- * via method tryFire, in NESTED mode. Triggering can propagate
- * recursively, so NESTED mode returns its completed dependent (if
- * one exists) for further processing by its caller (see method
- * postFire).
- *
- * Blocking methods get() and join() rely on Signaller Completions
- * that wake up waiting threads. The mechanics are similar to
- * Treiber stack wait-nodes used in FutureTask, Phaser, and
- * SynchronousQueue. See their internal documentation for
- * algorithmic details.
- *
- * Without precautions, CompletableFutures would be prone to
- * garbage accumulation as chains of Completions build up, each
- * pointing back to its sources. So we null out fields as soon as
- * possible (see especially method Completion.detach). The
- * screening checks needed anyway harmlessly ignore null arguments
- * that may have been obtained during races with threads nulling
- * out fields. We also try to unlink fired Completions from
- * stacks that might never be popped (see method postFire).
- * Completion fields need not be declared as final or volatile
- * because they are only visible to other threads upon safe
- * publication.
- */
-
- volatile Object result; // Either the result or boxed AltResult
- volatile Completion stack; // Top of Treiber stack of dependent actions
-
- final boolean internalComplete(Object r) { // CAS from null to r
- return UNSAFE.compareAndSwapObject(this, RESULT, null, r);
- }
-
- final boolean casStack(Completion cmp, Completion val) {
- return UNSAFE.compareAndSwapObject(this, STACK, cmp, val);
- }
-
- /** Returns true if successfully pushed c onto stack. */
- final boolean tryPushStack(Completion c) {
- Completion h = stack;
- lazySetNext(c, h);
- return UNSAFE.compareAndSwapObject(this, STACK, h, c);
- }
-
- /** Unconditionally pushes c onto stack, retrying if necessary. */
- final void pushStack(Completion c) {
- do {} while (!tryPushStack(c));
- }
-
- /* ------------- Encoding and decoding outcomes -------------- */
-
- static final class AltResult { // See above
- final Throwable ex; // null only for NIL
- AltResult(Throwable x) { this.ex = x; }
- }
-
- /** The encoding of the null value. */
- static final AltResult NIL = new AltResult(null);
-
- /** Completes with the null value, unless already completed. */
- final boolean completeNull() {
- return UNSAFE.compareAndSwapObject(this, RESULT, null,
- NIL);
- }
-
- /** Returns the encoding of the given non-exceptional value. */
- final Object encodeValue(T t) {
- return (t == null) ? NIL : t;
- }
-
- /** Completes with a non-exceptional result, unless already completed. */
- final boolean completeValue(T t) {
- return UNSAFE.compareAndSwapObject(this, RESULT, null,
- (t == null) ? NIL : t);
- }
-
- /**
- * Returns the encoding of the given (non-null) exception as a
- * wrapped CompletionException unless it is one already.
- */
- static AltResult encodeThrowable(Throwable x) {
- return new AltResult((x instanceof CompletionException) ? x :
- new CompletionException(x));
- }
-
- /** Completes with an exceptional result, unless already completed. */
- final boolean completeThrowable(Throwable x) {
- return UNSAFE.compareAndSwapObject(this, RESULT, null,
- encodeThrowable(x));
- }
-
- /**
- * Returns the encoding of the given (non-null) exception as a
- * wrapped CompletionException unless it is one already. May
- * return the given Object r (which must have been the result of a
- * source future) if it is equivalent, i.e. if this is a simple
- * relay of an existing CompletionException.
- */
- static Object encodeThrowable(Throwable x, Object r) {
- if (!(x instanceof CompletionException))
- x = new CompletionException(x);
- else if (r instanceof AltResult && x == ((AltResult)r).ex)
- return r;
- return new AltResult(x);
- }
-
- /**
- * Completes with the given (non-null) exceptional result as a
- * wrapped CompletionException unless it is one already, unless
- * already completed. May complete with the given Object r
- * (which must have been the result of a source future) if it is
- * equivalent, i.e. if this is a simple propagation of an
- * existing CompletionException.
- */
- final boolean completeThrowable(Throwable x, Object r) {
- return UNSAFE.compareAndSwapObject(this, RESULT, null,
- encodeThrowable(x, r));
- }
-
- /**
- * Returns the encoding of the given arguments: if the exception
- * is non-null, encodes as AltResult. Otherwise uses the given
- * value, boxed as NIL if null.
- */
- Object encodeOutcome(T t, Throwable x) {
- return (x == null) ? (t == null) ? NIL : t : encodeThrowable(x);
- }
-
- /**
- * Returns the encoding of a copied outcome; if exceptional,
- * rewraps as a CompletionException, else returns argument.
- */
- static Object encodeRelay(Object r) {
- Throwable x;
- return (((r instanceof AltResult) &&
- (x = ((AltResult)r).ex) != null &&
- !(x instanceof CompletionException)) ?
- new AltResult(new CompletionException(x)) : r);
- }
-
- /**
- * Completes with r or a copy of r, unless already completed.
- * If exceptional, r is first coerced to a CompletionException.
- */
- final boolean completeRelay(Object r) {
- return UNSAFE.compareAndSwapObject(this, RESULT, null,
- encodeRelay(r));
- }
-
- /**
- * Reports result using Future.get conventions.
- */
- private static T reportGet(Object r)
- throws InterruptedException, ExecutionException {
- if (r == null) // by convention below, null means interrupted
- throw new InterruptedException();
- if (r instanceof AltResult) {
- Throwable x, cause;
- if ((x = ((AltResult)r).ex) == null)
- return null;
- if (x instanceof CancellationException)
- throw (CancellationException)x;
- if ((x instanceof CompletionException) &&
- (cause = x.getCause()) != null)
- x = cause;
- throw new ExecutionException(x);
- }
- @SuppressWarnings("unchecked") T t = (T) r;
- return t;
- }
-
- /**
- * Decodes outcome to return result or throw unchecked exception.
- */
- private static T reportJoin(Object r) {
- if (r instanceof AltResult) {
- Throwable x;
- if ((x = ((AltResult)r).ex) == null)
- return null;
- if (x instanceof CancellationException)
- throw (CancellationException)x;
- if (x instanceof CompletionException)
- throw (CompletionException)x;
- throw new CompletionException(x);
- }
- @SuppressWarnings("unchecked") T t = (T) r;
- return t;
- }
-
- /* ------------- Async task preliminaries -------------- */
-
- /**
- * A marker interface identifying asynchronous tasks produced by
- * {@code async} methods. This may be useful for monitoring,
- * debugging, and tracking asynchronous activities.
- *
- * @since 1.8
- */
- public static interface AsynchronousCompletionTask {
- }
-
- private static final boolean useCommonPool =
- (ForkJoinPool.getCommonPoolParallelism() > 1);
-
- /**
- * Default executor -- ForkJoinPool.commonPool() unless it cannot
- * support parallelism.
- */
- private static final Executor asyncPool = useCommonPool ?
- ForkJoinPool.commonPool() : new ThreadPerTaskExecutor();
-
- /** Fallback if ForkJoinPool.commonPool() cannot support parallelism */
- static final class ThreadPerTaskExecutor implements Executor {
- public void execute(Runnable r) { new Thread(r).start(); }
- }
-
- /**
- * Null-checks user executor argument, and translates uses of
- * commonPool to asyncPool in case parallelism disabled.
- */
- static Executor screenExecutor(Executor e) {
- if (!useCommonPool && e == ForkJoinPool.commonPool())
- return asyncPool;
- if (e == null) throw new NullPointerException();
- return e;
- }
-
- // Modes for Completion.tryFire. Signedness matters.
- static final int SYNC = 0;
- static final int ASYNC = 1;
- static final int NESTED = -1;
-
- /* ------------- Base Completion classes and operations -------------- */
-
- @SuppressWarnings("serial")
- abstract static class Completion extends ForkJoinTask
- implements Runnable, AsynchronousCompletionTask {
- volatile Completion next; // Treiber stack link
-
- /**
- * Performs completion action if triggered, returning a
- * dependent that may need propagation, if one exists.
- *
- * @param mode SYNC, ASYNC, or NESTED
- */
- abstract CompletableFuture> tryFire(int mode);
-
- /** Returns true if possibly still triggerable. Used by cleanStack. */
- abstract boolean isLive();
-
- public final void run() { tryFire(ASYNC); }
- public final boolean exec() { tryFire(ASYNC); return true; }
- public final Void getRawResult() { return null; }
- public final void setRawResult(Void v) {}
- }
-
- static void lazySetNext(Completion c, Completion next) {
- UNSAFE.putOrderedObject(c, NEXT, next);
- }
-
- /**
- * Pops and tries to trigger all reachable dependents. Call only
- * when known to be done.
- */
- final void postComplete() {
- /*
- * On each step, variable f holds current dependents to pop
- * and run. It is extended along only one path at a time,
- * pushing others to avoid unbounded recursion.
- */
- CompletableFuture> f = this; Completion h;
- while ((h = f.stack) != null ||
- (f != this && (h = (f = this).stack) != null)) {
- CompletableFuture> d; Completion t;
- if (f.casStack(h, t = h.next)) {
- if (t != null) {
- if (f != this) {
- pushStack(h);
- continue;
- }
- h.next = null; // detach
- }
- f = (d = h.tryFire(NESTED)) == null ? this : d;
- }
- }
- }
-
- /** Traverses stack and unlinks dead Completions. */
- final void cleanStack() {
- for (Completion p = null, q = stack; q != null;) {
- Completion s = q.next;
- if (q.isLive()) {
- p = q;
- q = s;
- }
- else if (p == null) {
- casStack(q, s);
- q = stack;
- }
- else {
- p.next = s;
- if (p.isLive())
- q = s;
- else {
- p = null; // restart
- q = stack;
- }
- }
- }
- }
-
- /* ------------- One-input Completions -------------- */
-
- /** A Completion with a source, dependent, and executor. */
- @SuppressWarnings("serial")
- abstract static class UniCompletion extends Completion {
- Executor executor; // executor to use (null if none)
- CompletableFuture dep; // the dependent to complete
- CompletableFuture src; // source for action
-
- UniCompletion(Executor executor, CompletableFuture dep,
- CompletableFuture src) {
- this.executor = executor; this.dep = dep; this.src = src;
- }
-
- /**
- * Returns true if action can be run. Call only when known to
- * be triggerable. Uses FJ tag bit to ensure that only one
- * thread claims ownership. If async, starts as task -- a
- * later call to tryFire will run action.
- */
- final boolean claim() {
- Executor e = executor;
- if (compareAndSetForkJoinTaskTag((short)0, (short)1)) {
- if (e == null)
- return true;
- executor = null; // disable
- e.execute(this);
- }
- return false;
- }
-
- final boolean isLive() { return dep != null; }
- }
-
- /** Pushes the given completion (if it exists) unless done. */
- final void push(UniCompletion,?> c) {
- if (c != null) {
- while (result == null && !tryPushStack(c))
- lazySetNext(c, null); // clear on failure
- }
- }
-
- /**
- * Post-processing by dependent after successful UniCompletion
- * tryFire. Tries to clean stack of source a, and then either runs
- * postComplete or returns this to caller, depending on mode.
- */
- final CompletableFuture postFire(CompletableFuture> a, int mode) {
- if (a != null && a.stack != null) {
- if (mode < 0 || a.result == null)
- a.cleanStack();
- else
- a.postComplete();
- }
- if (result != null && stack != null) {
- if (mode < 0)
- return this;
- else
- postComplete();
- }
- return null;
- }
-
- @SuppressWarnings("serial")
- static final class UniApply extends UniCompletion {
- Function super T,? extends V> fn;
- UniApply(Executor executor, CompletableFuture dep,
- CompletableFuture src,
- Function super T,? extends V> fn) {
- super(executor, dep, src); this.fn = fn;
- }
- final CompletableFuture tryFire(int mode) {
- CompletableFuture d; CompletableFuture a;
- if ((d = dep) == null ||
- !d.uniApply(a = src, fn, mode > 0 ? null : this))
- return null;
- dep = null; src = null; fn = null;
- return d.postFire(a, mode);
- }
- }
-
- final boolean uniApply(CompletableFuture a,
- Function super S,? extends T> f,
- UniApply c) {
- Object r; Throwable x;
- if (a == null || (r = a.result) == null || f == null)
- return false;
- tryComplete: if (result == null) {
- if (r instanceof AltResult) {
- if ((x = ((AltResult)r).ex) != null) {
- completeThrowable(x, r);
- break tryComplete;
- }
- r = null;
- }
- try {
- if (c != null && !c.claim())
- return false;
- @SuppressWarnings("unchecked") S s = (S) r;
- completeValue(f.apply(s));
- } catch (Throwable ex) {
- completeThrowable(ex);
- }
- }
- return true;
- }
-
- private CompletableFuture uniApplyStage(
- Executor e, Function super T,? extends V> f) {
- if (f == null) throw new NullPointerException();
- CompletableFuture d = new CompletableFuture();
- if (e != null || !d.uniApply(this, f, null)) {
- UniApply c = new UniApply(e, d, this, f);
- push(c);
- c.tryFire(SYNC);
- }
- return d;
- }
-
- @SuppressWarnings("serial")
- static final class UniAccept extends UniCompletion {
- Consumer super T> fn;
- UniAccept(Executor executor, CompletableFuture dep,
- CompletableFuture src, Consumer super T> fn) {
- super(executor, dep, src); this.fn = fn;
- }
- final CompletableFuture tryFire(int mode) {
- CompletableFuture d; CompletableFuture a;
- if ((d = dep) == null ||
- !d.uniAccept(a = src, fn, mode > 0 ? null : this))
- return null;
- dep = null; src = null; fn = null;
- return d.postFire(a, mode);
- }
- }
-
- final boolean uniAccept(CompletableFuture a,
- Consumer super S> f, UniAccept c) {
- Object r; Throwable x;
- if (a == null || (r = a.result) == null || f == null)
- return false;
- tryComplete: if (result == null) {
- if (r instanceof AltResult) {
- if ((x = ((AltResult)r).ex) != null) {
- completeThrowable(x, r);
- break tryComplete;
- }
- r = null;
- }
- try {
- if (c != null && !c.claim())
- return false;
- @SuppressWarnings("unchecked") S s = (S) r;
- f.accept(s);
- completeNull();
- } catch (Throwable ex) {
- completeThrowable(ex);
- }
- }
- return true;
- }
-
- private CompletableFuture uniAcceptStage(Executor e,
- Consumer super T> f) {
- if (f == null) throw new NullPointerException();
- CompletableFuture d = new CompletableFuture();
- if (e != null || !d.uniAccept(this, f, null)) {
- UniAccept c = new UniAccept(e, d, this, f);
- push(c);
- c.tryFire(SYNC);
- }
- return d;
- }
-
- @SuppressWarnings("serial")
- static final class UniRun extends UniCompletion {
- Runnable fn;
- UniRun(Executor executor, CompletableFuture dep,
- CompletableFuture src, Runnable fn) {
- super(executor, dep, src); this.fn = fn;
- }
- final CompletableFuture tryFire(int mode) {
- CompletableFuture d; CompletableFuture a;
- if ((d = dep) == null ||
- !d.uniRun(a = src, fn, mode > 0 ? null : this))
- return null;
- dep = null; src = null; fn = null;
- return d.postFire(a, mode);
- }
- }
-
- final boolean uniRun(CompletableFuture> a, Runnable f, UniRun> c) {
- Object r; Throwable x;
- if (a == null || (r = a.result) == null || f == null)
- return false;
- if (result == null) {
- if (r instanceof AltResult && (x = ((AltResult)r).ex) != null)
- completeThrowable(x, r);
- else
- try {
- if (c != null && !c.claim())
- return false;
- f.run();
- completeNull();
- } catch (Throwable ex) {
- completeThrowable(ex);
- }
- }
- return true;
- }
-
- private CompletableFuture uniRunStage(Executor e, Runnable f) {
- if (f == null) throw new NullPointerException();
- CompletableFuture d = new CompletableFuture();
- if (e != null || !d.uniRun(this, f, null)) {
- UniRun c = new UniRun(e, d, this, f);
- push(c);
- c.tryFire(SYNC);
- }
- return d;
- }
-
- @SuppressWarnings("serial")
- static final class UniWhenComplete extends UniCompletion {
- BiConsumer super T, ? super Throwable> fn;
- UniWhenComplete(Executor executor, CompletableFuture dep,
- CompletableFuture src,
- BiConsumer super T, ? super Throwable> fn) {
- super(executor, dep, src); this.fn = fn;
- }
- final CompletableFuture tryFire(int mode) {
- CompletableFuture d; CompletableFuture a;
- if ((d = dep) == null ||
- !d.uniWhenComplete(a = src, fn, mode > 0 ? null : this))
- return null;
- dep = null; src = null; fn = null;
- return d.postFire(a, mode);
- }
- }
-
- final boolean uniWhenComplete(CompletableFuture a,
- BiConsumer super T,? super Throwable> f,
- UniWhenComplete c) {
- Object r; T t; Throwable x = null;
- if (a == null || (r = a.result) == null || f == null)
- return false;
- if (result == null) {
- try {
- if (c != null && !c.claim())
- return false;
- if (r instanceof AltResult) {
- x = ((AltResult)r).ex;
- t = null;
- } else {
- @SuppressWarnings("unchecked") T tr = (T) r;
- t = tr;
- }
- f.accept(t, x);
- if (x == null) {
- internalComplete(r);
- return true;
- }
- } catch (Throwable ex) {
- if (x == null)
- x = ex;
- }
- completeThrowable(x, r);
- }
- return true;
- }
-
- private CompletableFuture uniWhenCompleteStage(
- Executor e, BiConsumer super T, ? super Throwable> f) {
- if (f == null) throw new NullPointerException();
- CompletableFuture d = new CompletableFuture();
- if (e != null || !d.uniWhenComplete(this, f, null)) {
- UniWhenComplete c = new UniWhenComplete(e, d, this, f);
- push(c);
- c.tryFire(SYNC);
- }
- return d;
- }
-
- @SuppressWarnings("serial")
- static final class UniHandle extends UniCompletion {
- BiFunction super T, Throwable, ? extends V> fn;
- UniHandle(Executor executor, CompletableFuture dep,
- CompletableFuture src,
- BiFunction super T, Throwable, ? extends V> fn) {
- super(executor, dep, src); this.fn = fn;
- }
- final CompletableFuture tryFire(int mode) {
- CompletableFuture d; CompletableFuture a;
- if ((d = dep) == null ||
- !d.uniHandle(a = src, fn, mode > 0 ? null : this))
- return null;
- dep = null; src = null; fn = null;
- return d.postFire(a, mode);
- }
- }
-
- final boolean uniHandle(CompletableFuture a,
- BiFunction super S, Throwable, ? extends T> f,
- UniHandle c) {
- Object r; S s; Throwable x;
- if (a == null || (r = a.result) == null || f == null)
- return false;
- if (result == null) {
- try {
- if (c != null && !c.claim())
- return false;
- if (r instanceof AltResult) {
- x = ((AltResult)r).ex;
- s = null;
- } else {
- x = null;
- @SuppressWarnings("unchecked") S ss = (S) r;
- s = ss;
- }
- completeValue(f.apply(s, x));
- } catch (Throwable ex) {
- completeThrowable(ex);
- }
- }
- return true;
- }
-
- private CompletableFuture uniHandleStage(
- Executor e, BiFunction super T, Throwable, ? extends V> f) {
- if (f == null) throw new NullPointerException();
- CompletableFuture d = new CompletableFuture();
- if (e != null || !d.uniHandle(this, f, null)) {
- UniHandle c = new UniHandle(e, d, this, f);
- push(c);
- c.tryFire(SYNC);
- }
- return d;
- }
-
- @SuppressWarnings("serial")
- static final class UniExceptionally extends UniCompletion {
- Function super Throwable, ? extends T> fn;
- UniExceptionally(CompletableFuture dep, CompletableFuture src,
- Function super Throwable, ? extends T> fn) {
- super(null, dep, src); this.fn = fn;
- }
- final CompletableFuture tryFire(int mode) { // never ASYNC
- // assert mode != ASYNC;
- CompletableFuture d; CompletableFuture a;
- if ((d = dep) == null || !d.uniExceptionally(a = src, fn, this))
- return null;
- dep = null; src = null; fn = null;
- return d.postFire(a, mode);
- }
- }
-
- final boolean uniExceptionally(CompletableFuture a,
- Function super Throwable, ? extends T> f,
- UniExceptionally c) {
- Object r; Throwable x;
- if (a == null || (r = a.result) == null || f == null)
- return false;
- if (result == null) {
- try {
- if (r instanceof AltResult && (x = ((AltResult)r).ex) != null) {
- if (c != null && !c.claim())
- return false;
- completeValue(f.apply(x));
- } else
- internalComplete(r);
- } catch (Throwable ex) {
- completeThrowable(ex);
- }
- }
- return true;
- }
-
- private CompletableFuture uniExceptionallyStage(
- Function f) {
- if (f == null) throw new NullPointerException();
- CompletableFuture d = new CompletableFuture();
- if (!d.uniExceptionally(this, f, null)) {
- UniExceptionally c = new UniExceptionally(d, this, f);
- push(c);
- c.tryFire(SYNC);
- }
- return d;
- }
-
- @SuppressWarnings("serial")
- static final class UniRelay extends UniCompletion { // for Compose
- UniRelay(CompletableFuture dep, CompletableFuture src) {
- super(null, dep, src);
- }
- final CompletableFuture tryFire(int mode) {
- CompletableFuture d; CompletableFuture a;
- if ((d = dep) == null || !d.uniRelay(a = src))
- return null;
- src = null; dep = null;
- return d.postFire(a, mode);
- }
- }
-
- final boolean uniRelay(CompletableFuture a) {
- Object r;
- if (a == null || (r = a.result) == null)
- return false;
- if (result == null) // no need to claim
- completeRelay(r);
- return true;
- }
-
- @SuppressWarnings("serial")
- static final class UniCompose extends UniCompletion {
- Function super T, ? extends CompletionStage> fn;
- UniCompose(Executor executor, CompletableFuture dep,
- CompletableFuture src,
- Function super T, ? extends CompletionStage> fn) {
- super(executor, dep, src); this.fn = fn;
- }
- final CompletableFuture tryFire(int mode) {
- CompletableFuture d; CompletableFuture a;
- if ((d = dep) == null ||
- !d.uniCompose(a = src, fn, mode > 0 ? null : this))
- return null;
- dep = null; src = null; fn = null;
- return d.postFire(a, mode);
- }
- }
-
- @Deprecated
- final boolean uniCompose(
- CompletableFuture a,
- Function super S, ? extends CompletionStage> f,
- UniCompose c) {
- Object r; Throwable x;
- if (a == null || (r = a.result) == null || f == null)
- return false;
- tryComplete: if (result == null) {
- if (r instanceof AltResult) {
- if ((x = ((AltResult)r).ex) != null) {
- completeThrowable(x, r);
- break tryComplete;
- }
- r = null;
- }
- try {
- if (c != null && !c.claim())
- return false;
- @SuppressWarnings("unchecked") S s = (S) r;
- CompletableFuture g = f.apply(s).toCompletableFuture();
- if (g.result == null || !uniRelay(g)) {
- UniRelay copy = new UniRelay(this, g);
- g.push(copy);
- copy.tryFire(SYNC);
- if (result == null)
- return false;
- }
- } catch (Throwable ex) {
- completeThrowable(ex);
- }
- }
- return true;
- }
-
- private CompletableFuture uniComposeStage(
- Executor e, Function super T, ? extends CompletionStage> f) {
- if (f == null) throw new NullPointerException();
- Object r; Throwable x;
- if (e == null && (r = result) != null) {
- // try to return function result directly
- if (r instanceof AltResult) {
- if ((x = ((AltResult)r).ex) != null) {
- return new CompletableFuture(encodeThrowable(x, r));
- }
- r = null;
- }
- try {
- @SuppressWarnings("unchecked") T t = (T) r;
- CompletableFuture g = f.apply(t).toCompletableFuture();
- Object s = g.result;
- if (s != null)
- return new CompletableFuture(encodeRelay(s));
- CompletableFuture d = new CompletableFuture();
- UniRelay copy = new UniRelay(d, g);
- g.push(copy);
- copy.tryFire(SYNC);
- return d;
- } catch (Throwable ex) {
- return new CompletableFuture(encodeThrowable(ex));
- }
- }
- CompletableFuture d = new CompletableFuture();
- UniCompose c = new UniCompose(e, d, this, f);
- push(c);
- c.tryFire(SYNC);
- return d;
- }
-
- /* ------------- Two-input Completions -------------- */
-
- /** A Completion for an action with two sources */
- @SuppressWarnings("serial")
- abstract static class BiCompletion extends UniCompletion {
- CompletableFuture snd; // second source for action
- BiCompletion(Executor executor, CompletableFuture dep,
- CompletableFuture src, CompletableFuture snd) {
- super(executor, dep, src); this.snd = snd;
- }
- }
-
- /** A Completion delegating to a BiCompletion */
- @SuppressWarnings("serial")
- static final class CoCompletion extends Completion {
- BiCompletion,?,?> base;
- CoCompletion(BiCompletion,?,?> base) { this.base = base; }
- final CompletableFuture> tryFire(int mode) {
- BiCompletion,?,?> c; CompletableFuture> d;
- if ((c = base) == null || (d = c.tryFire(mode)) == null)
- return null;
- base = null; // detach
- return d;
- }
- final boolean isLive() {
- BiCompletion,?,?> c;
- return (c = base) != null && c.dep != null;
- }
- }
-
- /** Pushes completion to this and b unless both done. */
- final void bipush(CompletableFuture> b, BiCompletion,?,?> c) {
- if (c != null) {
- Object r;
- while ((r = result) == null && !tryPushStack(c))
- lazySetNext(c, null); // clear on failure
- if (b != null && b != this && b.result == null) {
- Completion q = (r != null) ? c : new CoCompletion(c);
- while (b.result == null && !b.tryPushStack(q))
- lazySetNext(q, null); // clear on failure
- }
- }
- }
-
- /** Post-processing after successful BiCompletion tryFire. */
- final CompletableFuture postFire(CompletableFuture> a,
- CompletableFuture> b, int mode) {
- if (b != null && b.stack != null) { // clean second source
- if (mode < 0 || b.result == null)
- b.cleanStack();
- else
- b.postComplete();
- }
- return postFire(a, mode);
- }
-
- @SuppressWarnings("serial")
- static final class BiApply extends BiCompletion {
- BiFunction super T,? super U,? extends V> fn;
- BiApply(Executor executor, CompletableFuture dep,
- CompletableFuture src, CompletableFuture snd,
- BiFunction super T,? super U,? extends V> fn) {
- super(executor, dep, src, snd); this.fn = fn;
- }
- final CompletableFuture tryFire(int mode) {
- CompletableFuture d;
- CompletableFuture a;
- CompletableFuture b;
- if ((d = dep) == null ||
- !d.biApply(a = src, b = snd, fn, mode > 0 ? null : this))
- return null;
- dep = null; src = null; snd = null; fn = null;
- return d.postFire(a, b, mode);
- }
- }
-
- final boolean biApply(CompletableFuture a,
- CompletableFuture b,
- BiFunction super R,? super S,? extends T> f,
- BiApply c) {
- Object r, s; Throwable x;
- if (a == null || (r = a.result) == null ||
- b == null || (s = b.result) == null || f == null)
- return false;
- tryComplete: if (result == null) {
- if (r instanceof AltResult) {
- if ((x = ((AltResult)r).ex) != null) {
- completeThrowable(x, r);
- break tryComplete;
- }
- r = null;
- }
- if (s instanceof AltResult) {
- if ((x = ((AltResult)s).ex) != null) {
- completeThrowable(x, s);
- break tryComplete;
- }
- s = null;
- }
- try {
- if (c != null && !c.claim())
- return false;
- @SuppressWarnings("unchecked") R rr = (R) r;
- @SuppressWarnings("unchecked") S ss = (S) s;
- completeValue(f.apply(rr, ss));
- } catch (Throwable ex) {
- completeThrowable(ex);
- }
- }
- return true;
- }
-
- private CompletableFuture biApplyStage(
- Executor e, CompletionStage o,
- BiFunction super T,? super U,? extends V> f) {
- CompletableFuture b;
- if (f == null || (b = o.toCompletableFuture()) == null)
- throw new NullPointerException();
- CompletableFuture d = new CompletableFuture();
- if (e != null || !d.biApply(this, b, f, null)) {
- BiApply c = new BiApply(e, d, this, b, f);
- bipush(b, c);
- c.tryFire(SYNC);
- }
- return d;
- }
-
- @SuppressWarnings("serial")
- static final class BiAccept extends BiCompletion {
- BiConsumer super T,? super U> fn;
- BiAccept(Executor executor, CompletableFuture dep,
- CompletableFuture src, CompletableFuture snd,
- BiConsumer super T,? super U> fn) {
- super(executor, dep, src, snd); this.fn = fn;
- }
- final CompletableFuture tryFire(int mode) {
- CompletableFuture d;
- CompletableFuture a;
- CompletableFuture b;
- if ((d = dep) == null ||
- !d.biAccept(a = src, b = snd, fn, mode > 0 ? null : this))
- return null;
- dep = null; src = null; snd = null; fn = null;
- return d.postFire(a, b, mode);
- }
- }
-
- final boolean biAccept(CompletableFuture a,
- CompletableFuture b,
- BiConsumer super R,? super S> f,
- BiAccept c) {
- Object r, s; Throwable x;
- if (a == null || (r = a.result) == null ||
- b == null || (s = b.result) == null || f == null)
- return false;
- tryComplete: if (result == null) {
- if (r instanceof AltResult) {
- if ((x = ((AltResult)r).ex) != null) {
- completeThrowable(x, r);
- break tryComplete;
- }
- r = null;
- }
- if (s instanceof AltResult) {
- if ((x = ((AltResult)s).ex) != null) {
- completeThrowable(x, s);
- break tryComplete;
- }
- s = null;
- }
- try {
- if (c != null && !c.claim())
- return false;
- @SuppressWarnings("unchecked") R rr = (R) r;
- @SuppressWarnings("unchecked") S ss = (S) s;
- f.accept(rr, ss);
- completeNull();
- } catch (Throwable ex) {
- completeThrowable(ex);
- }
- }
- return true;
- }
-
- private CompletableFuture biAcceptStage(
- Executor e, CompletionStage o,
- BiConsumer super T,? super U> f) {
- CompletableFuture b;
- if (f == null || (b = o.toCompletableFuture()) == null)
- throw new NullPointerException();
- CompletableFuture d = new CompletableFuture();
- if (e != null || !d.biAccept(this, b, f, null)) {
- BiAccept c = new BiAccept(e, d, this, b, f);
- bipush(b, c);
- c.tryFire(SYNC);
- }
- return d;
- }
-
- @SuppressWarnings("serial")
- static final class BiRun extends BiCompletion {
- Runnable fn;
- BiRun(Executor executor, CompletableFuture dep,
- CompletableFuture src,
- CompletableFuture snd,
- Runnable fn) {
- super(executor, dep, src, snd); this.fn = fn;
- }
- final CompletableFuture tryFire(int mode) {
- CompletableFuture d;
- CompletableFuture a;
- CompletableFuture b;
- if ((d = dep) == null ||
- !d.biRun(a = src, b = snd, fn, mode > 0 ? null : this))
- return null;
- dep = null; src = null; snd = null; fn = null;
- return d.postFire(a, b, mode);
- }
- }
-
- final boolean biRun(CompletableFuture> a, CompletableFuture> b,
- Runnable f, BiRun,?> c) {
- Object r, s; Throwable x;
- if (a == null || (r = a.result) == null ||
- b == null || (s = b.result) == null || f == null)
- return false;
- if (result == null) {
- if (r instanceof AltResult && (x = ((AltResult)r).ex) != null)
- completeThrowable(x, r);
- else if (s instanceof AltResult && (x = ((AltResult)s).ex) != null)
- completeThrowable(x, s);
- else
- try {
- if (c != null && !c.claim())
- return false;
- f.run();
- completeNull();
- } catch (Throwable ex) {
- completeThrowable(ex);
- }
- }
- return true;
- }
-
- private CompletableFuture biRunStage(Executor e, CompletionStage> o,
- Runnable f) {
- CompletableFuture> b;
- if (f == null || (b = o.toCompletableFuture()) == null)
- throw new NullPointerException();
- CompletableFuture d = new CompletableFuture();
- if (e != null || !d.biRun(this, b, f, null)) {
- BiRun c = new BiRun<>(e, d, this, b, f);
- bipush(b, c);
- c.tryFire(SYNC);
- }
- return d;
- }
-
- @SuppressWarnings("serial")
- static final class BiRelay extends BiCompletion { // for And
- BiRelay(CompletableFuture dep,
- CompletableFuture src,
- CompletableFuture snd) {
- super(null, dep, src, snd);
- }
- final CompletableFuture tryFire(int mode) {
- CompletableFuture d;
- CompletableFuture a;
- CompletableFuture b;
- if ((d = dep) == null || !d.biRelay(a = src, b = snd))
- return null;
- src = null; snd = null; dep = null;
- return d.postFire(a, b, mode);
- }
- }
-
- boolean biRelay(CompletableFuture> a, CompletableFuture> b) {
- Object r, s; Throwable x;
- if (a == null || (r = a.result) == null ||
- b == null || (s = b.result) == null)
- return false;
- if (result == null) {
- if (r instanceof AltResult && (x = ((AltResult)r).ex) != null)
- completeThrowable(x, r);
- else if (s instanceof AltResult && (x = ((AltResult)s).ex) != null)
- completeThrowable(x, s);
- else
- completeNull();
- }
- return true;
- }
-
- /** Recursively constructs a tree of completions. */
- static CompletableFuture andTree(CompletableFuture>[] cfs,
- int lo, int hi) {
- CompletableFuture d = new CompletableFuture();
- if (lo > hi) // empty
- d.result = NIL;
- else {
- CompletableFuture> a, b;
- int mid = (lo + hi) >>> 1;
- if ((a = (lo == mid ? cfs[lo] :
- andTree(cfs, lo, mid))) == null ||
- (b = (lo == hi ? a : (hi == mid+1) ? cfs[hi] :
- andTree(cfs, mid+1, hi))) == null)
- throw new NullPointerException();
- if (!d.biRelay(a, b)) {
- BiRelay,?> c = new BiRelay<>(d, a, b);
- a.bipush(b, c);
- c.tryFire(SYNC);
- }
- }
- return d;
- }
-
- /* ------------- Projected (Ored) BiCompletions -------------- */
-
- /** Pushes completion to this and b unless either done. */
- final void orpush(CompletableFuture> b, BiCompletion,?,?> c) {
- if (c != null) {
- while ((b == null || b.result == null) && result == null) {
- if (tryPushStack(c)) {
- if (b != null && b != this && b.result == null) {
- Completion q = new CoCompletion(c);
- while (result == null && b.result == null &&
- !b.tryPushStack(q))
- lazySetNext(q, null); // clear on failure
- }
- break;
- }
- lazySetNext(c, null); // clear on failure
- }
- }
- }
-
- @SuppressWarnings("serial")
- static final class OrApply extends BiCompletion {
- Function super T,? extends V> fn;
- OrApply(Executor executor, CompletableFuture dep,
- CompletableFuture src,
- CompletableFuture snd,
- Function super T,? extends V> fn) {
- super(executor, dep, src, snd); this.fn = fn;
- }
- final CompletableFuture tryFire(int mode) {
- CompletableFuture d;
- CompletableFuture a;
- CompletableFuture b;
- if ((d = dep) == null ||
- !d.orApply(a = src, b = snd, fn, mode > 0 ? null : this))
- return null;
- dep = null; src = null; snd = null; fn = null;
- return d.postFire(a, b, mode);
- }
- }
-
- final boolean orApply(CompletableFuture a,
- CompletableFuture b,
- Function super R, ? extends T> f,
- OrApply c) {
- Object r; Throwable x;
- if (a == null || b == null ||
- ((r = a.result) == null && (r = b.result) == null) || f == null)
- return false;
- tryComplete: if (result == null) {
- try {
- if (c != null && !c.claim())
- return false;
- if (r instanceof AltResult) {
- if ((x = ((AltResult)r).ex) != null) {
- completeThrowable(x, r);
- break tryComplete;
- }
- r = null;
- }
- @SuppressWarnings("unchecked") R rr = (R) r;
- completeValue(f.apply(rr));
- } catch (Throwable ex) {
- completeThrowable(ex);
- }
- }
- return true;
- }
-
- private CompletableFuture orApplyStage(
- Executor e, CompletionStage o,
- Function super T, ? extends V> f) {
- CompletableFuture b;
- if (f == null || (b = o.toCompletableFuture()) == null)
- throw new NullPointerException();
- CompletableFuture d = new CompletableFuture();
- if (e != null || !d.orApply(this, b, f, null)) {
- OrApply c = new OrApply(e, d, this, b, f);
- orpush(b, c);
- c.tryFire(SYNC);
- }
- return d;
- }
-
- @SuppressWarnings("serial")
- static final class OrAccept extends BiCompletion {
- Consumer super T> fn;
- OrAccept(Executor executor, CompletableFuture dep,
- CompletableFuture src,
- CompletableFuture snd,
- Consumer super T> fn) {
- super(executor, dep, src, snd); this.fn = fn;
- }
- final CompletableFuture tryFire(int mode) {
- CompletableFuture d;
- CompletableFuture a;
- CompletableFuture b;
- if ((d = dep) == null ||
- !d.orAccept(a = src, b = snd, fn, mode > 0 ? null : this))
- return null;
- dep = null; src = null; snd = null; fn = null;
- return d.postFire(a, b, mode);
- }
- }
-
- final boolean orAccept(CompletableFuture a,
- CompletableFuture b,
- Consumer super R> f,
- OrAccept c) {
- Object r; Throwable x;
- if (a == null || b == null ||
- ((r = a.result) == null && (r = b.result) == null) || f == null)
- return false;
- tryComplete: if (result == null) {
- try {
- if (c != null && !c.claim())
- return false;
- if (r instanceof AltResult) {
- if ((x = ((AltResult)r).ex) != null) {
- completeThrowable(x, r);
- break tryComplete;
- }
- r = null;
- }
- @SuppressWarnings("unchecked") R rr = (R) r;
- f.accept(rr);
- completeNull();
- } catch (Throwable ex) {
- completeThrowable(ex);
- }
- }
- return true;
- }
-
- private CompletableFuture orAcceptStage(
- Executor e, CompletionStage o, Consumer super T> f) {
- CompletableFuture b;
- if (f == null || (b = o.toCompletableFuture()) == null)
- throw new NullPointerException();
- CompletableFuture d = new CompletableFuture