();
executor.execute(new AsyncRun(runnable, f));
return f;
}
/**
* Returns a new CompletableFuture that is already completed with
* the given value.
*
* @param value the value
* @param the type of the value
* @return the completed CompletableFuture
*/
public static CompletableFuture completedFuture(U value) {
CompletableFuture f = new CompletableFuture();
f.result = (value == null) ? NIL : value;
return f;
}
/**
* Returns {@code true} if completed in any fashion: normally,
* exceptionally, or via cancellation.
*
* @return {@code true} if completed
*/
public boolean isDone() {
return result != null;
}
/**
* Waits if necessary for this future to complete, and then
* returns its result.
*
* @return the result value
* @throws CancellationException if this future was cancelled
* @throws ExecutionException if this future completed exceptionally
* @throws InterruptedException if the current thread was interrupted
* while waiting
*/
public T get() throws InterruptedException, ExecutionException {
Object r; Throwable ex, cause;
if ((r = result) == null && (r = waitingGet(true)) == null)
throw new InterruptedException();
if (!(r instanceof AltResult)) {
@SuppressWarnings("unchecked") T tr = (T) r;
return tr;
}
if ((ex = ((AltResult)r).ex) == null)
return null;
if (ex instanceof CancellationException)
throw (CancellationException)ex;
if ((ex instanceof CompletionException) &&
(cause = ex.getCause()) != null)
ex = cause;
throw new ExecutionException(ex);
}
/**
* Waits if necessary for at most the given time for this future
* to complete, and then returns its result, if available.
*
* @param timeout the maximum time to wait
* @param unit the time unit of the timeout argument
* @return the result value
* @throws CancellationException if this future was cancelled
* @throws ExecutionException if this future completed exceptionally
* @throws InterruptedException if the current thread was interrupted
* while waiting
* @throws TimeoutException if the wait timed out
*/
public T get(long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException {
Object r; Throwable ex, cause;
long nanos = unit.toNanos(timeout);
if (Thread.interrupted())
throw new InterruptedException();
if ((r = result) == null)
r = timedAwaitDone(nanos);
if (!(r instanceof AltResult)) {
@SuppressWarnings("unchecked") T tr = (T) r;
return tr;
}
if ((ex = ((AltResult)r).ex) == null)
return null;
if (ex instanceof CancellationException)
throw (CancellationException)ex;
if ((ex instanceof CompletionException) &&
(cause = ex.getCause()) != null)
ex = cause;
throw new ExecutionException(ex);
}
/**
* Returns the result value when complete, or throws an
* (unchecked) exception if completed exceptionally. To better
* conform with the use of common functional forms, if a
* computation involved in the completion of this
* CompletableFuture threw an exception, this method throws an
* (unchecked) {@link CompletionException} with the underlying
* exception as its cause.
*
* @return the result value
* @throws CancellationException if the computation was cancelled
* @throws CompletionException if this future completed
* exceptionally or a completion computation threw an exception
*/
public T join() {
Object r; Throwable ex;
if ((r = result) == null)
r = waitingGet(false);
if (!(r instanceof AltResult)) {
@SuppressWarnings("unchecked") T tr = (T) r;
return tr;
}
if ((ex = ((AltResult)r).ex) == null)
return null;
if (ex instanceof CancellationException)
throw (CancellationException)ex;
if (ex instanceof CompletionException)
throw (CompletionException)ex;
throw new CompletionException(ex);
}
/**
* Returns the result value (or throws any encountered exception)
* if completed, else returns the given valueIfAbsent.
*
* @param valueIfAbsent the value to return if not completed
* @return the result value, if completed, else the given valueIfAbsent
* @throws CancellationException if the computation was cancelled
* @throws CompletionException if this future completed
* exceptionally or a completion computation threw an exception
*/
public T getNow(T valueIfAbsent) {
Object r; Throwable ex;
if ((r = result) == null)
return valueIfAbsent;
if (!(r instanceof AltResult)) {
@SuppressWarnings("unchecked") T tr = (T) r;
return tr;
}
if ((ex = ((AltResult)r).ex) == null)
return null;
if (ex instanceof CancellationException)
throw (CancellationException)ex;
if (ex instanceof CompletionException)
throw (CompletionException)ex;
throw new CompletionException(ex);
}
/**
* If not already completed, sets the value returned by {@link
* #get()} and related methods to the given value.
*
* @param value the result value
* @return {@code true} if this invocation caused this CompletableFuture
* to transition to a completed state, else {@code false}
*/
public boolean complete(T value) {
boolean triggered = result == null &&
UNSAFE.compareAndSwapObject(this, RESULT, null,
value == null ? NIL : value);
postComplete();
return triggered;
}
/**
* If not already completed, causes invocations of {@link #get()}
* and related methods to throw the given exception.
*
* @param ex the exception
* @return {@code true} if this invocation caused this CompletableFuture
* to transition to a completed state, else {@code false}
*/
public boolean completeExceptionally(Throwable ex) {
if (ex == null) throw new NullPointerException();
boolean triggered = result == null &&
UNSAFE.compareAndSwapObject(this, RESULT, null, new AltResult(ex));
postComplete();
return triggered;
}
/**
* Returns a new CompletableFuture that is completed
* when this CompletableFuture completes, with the result of the
* given function of this CompletableFuture's result.
*
* If this CompletableFuture completes exceptionally, or the
* supplied function throws an exception, then the returned
* CompletableFuture completes exceptionally with a
* CompletionException holding the exception as its cause.
*
* @param fn the function to use to compute the value of
* the returned CompletableFuture
* @return the new CompletableFuture
*/
public CompletableFuture thenApply(Fun super T,? extends U> fn) {
return doThenApply(fn, null);
}
/**
* Returns a new CompletableFuture that is asynchronously completed
* when this CompletableFuture completes, with the result of the
* given function of this CompletableFuture's result from a
* task running in the {@link ForkJoinPool#commonPool()}.
*
*
If this CompletableFuture completes exceptionally, or the
* supplied function throws an exception, then the returned
* CompletableFuture completes exceptionally with a
* CompletionException holding the exception as its cause.
*
* @param fn the function to use to compute the value of
* the returned CompletableFuture
* @return the new CompletableFuture
*/
public CompletableFuture thenApplyAsync
(Fun super T,? extends U> fn) {
return doThenApply(fn, ForkJoinPool.commonPool());
}
/**
* Returns a new CompletableFuture that is asynchronously completed
* when this CompletableFuture completes, with the result of the
* given function of this CompletableFuture's result from a
* task running in the given executor.
*
*
If this CompletableFuture completes exceptionally, or the
* supplied function throws an exception, then the returned
* CompletableFuture completes exceptionally with a
* CompletionException holding the exception as its cause.
*
* @param fn the function to use to compute the value of
* the returned CompletableFuture
* @param executor the executor to use for asynchronous execution
* @return the new CompletableFuture
*/
public CompletableFuture thenApplyAsync
(Fun super T,? extends U> fn,
Executor executor) {
if (executor == null) throw new NullPointerException();
return doThenApply(fn, executor);
}
private CompletableFuture doThenApply
(Fun super T,? extends U> fn,
Executor e) {
if (fn == null) throw new NullPointerException();
CompletableFuture dst = new CompletableFuture();
ThenApply d = null;
Object r;
if ((r = result) == null) {
CompletionNode p = new CompletionNode
(d = new ThenApply(this, fn, dst, e));
while ((r = result) == null) {
if (UNSAFE.compareAndSwapObject
(this, COMPLETIONS, p.next = completions, p))
break;
}
}
if (r != null && (d == null || d.compareAndSet(0, 1))) {
T t; Throwable ex;
if (r instanceof AltResult) {
ex = ((AltResult)r).ex;
t = null;
}
else {
ex = null;
@SuppressWarnings("unchecked") T tr = (T) r;
t = tr;
}
U u = null;
if (ex == null) {
try {
if (e != null)
e.execute(new AsyncApply(t, fn, dst));
else
u = fn.apply(t);
} catch (Throwable rex) {
ex = rex;
}
}
if (e == null || ex != null)
dst.internalComplete(u, ex);
}
helpPostComplete();
return dst;
}
/**
* Returns a new CompletableFuture that is completed
* when this CompletableFuture completes, after performing the given
* action with this CompletableFuture's result.
*
* If this CompletableFuture completes exceptionally, or the
* supplied action throws an exception, then the returned
* CompletableFuture completes exceptionally with a
* CompletionException holding the exception as its cause.
*
* @param block the action to perform before completing the
* returned CompletableFuture
* @return the new CompletableFuture
*/
public CompletableFuture thenAccept(Action super T> block) {
return doThenAccept(block, null);
}
/**
* Returns a new CompletableFuture that is asynchronously completed
* when this CompletableFuture completes, after performing the given
* action with this CompletableFuture's result from a task running
* in the {@link ForkJoinPool#commonPool()}.
*
* If this CompletableFuture completes exceptionally, or the
* supplied action throws an exception, then the returned
* CompletableFuture completes exceptionally with a
* CompletionException holding the exception as its cause.
*
* @param block the action to perform before completing the
* returned CompletableFuture
* @return the new CompletableFuture
*/
public CompletableFuture thenAcceptAsync(Action super T> block) {
return doThenAccept(block, ForkJoinPool.commonPool());
}
/**
* Returns a new CompletableFuture that is asynchronously completed
* when this CompletableFuture completes, after performing the given
* action with this CompletableFuture's result from a task running
* in the given executor.
*
* If this CompletableFuture completes exceptionally, or the
* supplied action throws an exception, then the returned
* CompletableFuture completes exceptionally with a
* CompletionException holding the exception as its cause.
*
* @param block the action to perform before completing the
* returned CompletableFuture
* @param executor the executor to use for asynchronous execution
* @return the new CompletableFuture
*/
public CompletableFuture thenAcceptAsync(Action super T> block,
Executor executor) {
if (executor == null) throw new NullPointerException();
return doThenAccept(block, executor);
}
private CompletableFuture doThenAccept(Action super T> fn,
Executor e) {
if (fn == null) throw new NullPointerException();
CompletableFuture dst = new CompletableFuture();
ThenAccept d = null;
Object r;
if ((r = result) == null) {
CompletionNode p = new CompletionNode
(d = new ThenAccept(this, fn, dst, e));
while ((r = result) == null) {
if (UNSAFE.compareAndSwapObject
(this, COMPLETIONS, p.next = completions, p))
break;
}
}
if (r != null && (d == null || d.compareAndSet(0, 1))) {
T t; Throwable ex;
if (r instanceof AltResult) {
ex = ((AltResult)r).ex;
t = null;
}
else {
ex = null;
@SuppressWarnings("unchecked") T tr = (T) r;
t = tr;
}
if (ex == null) {
try {
if (e != null)
e.execute(new AsyncAccept(t, fn, dst));
else
fn.accept(t);
} catch (Throwable rex) {
ex = rex;
}
}
if (e == null || ex != null)
dst.internalComplete(null, ex);
}
helpPostComplete();
return dst;
}
/**
* Returns a new CompletableFuture that is completed
* when this CompletableFuture completes, after performing the given
* action.
*
* If this CompletableFuture completes exceptionally, or the
* supplied action throws an exception, then the returned
* CompletableFuture completes exceptionally with a
* CompletionException holding the exception as its cause.
*
* @param action the action to perform before completing the
* returned CompletableFuture
* @return the new CompletableFuture
*/
public CompletableFuture thenRun(Runnable action) {
return doThenRun(action, null);
}
/**
* Returns a new CompletableFuture that is asynchronously completed
* when this CompletableFuture completes, after performing the given
* action from a task running in the {@link ForkJoinPool#commonPool()}.
*
* If this CompletableFuture completes exceptionally, or the
* supplied action throws an exception, then the returned
* CompletableFuture completes exceptionally with a
* CompletionException holding the exception as its cause.
*
* @param action the action to perform before completing the
* returned CompletableFuture
* @return the new CompletableFuture
*/
public CompletableFuture thenRunAsync(Runnable action) {
return doThenRun(action, ForkJoinPool.commonPool());
}
/**
* Returns a new CompletableFuture that is asynchronously completed
* when this CompletableFuture completes, after performing the given
* action from a task running in the given executor.
*
* If this CompletableFuture completes exceptionally, or the
* supplied action throws an exception, then the returned
* CompletableFuture completes exceptionally with a
* CompletionException holding the exception as its cause.
*
* @param action the action to perform before completing the
* returned CompletableFuture
* @param executor the executor to use for asynchronous execution
* @return the new CompletableFuture
*/
public CompletableFuture thenRunAsync(Runnable action,
Executor executor) {
if (executor == null) throw new NullPointerException();
return doThenRun(action, executor);
}
private CompletableFuture doThenRun(Runnable action,
Executor e) {
if (action == null) throw new NullPointerException();
CompletableFuture dst = new CompletableFuture();
ThenRun d = null;
Object r;
if ((r = result) == null) {
CompletionNode p = new CompletionNode
(d = new ThenRun(this, action, dst, e));
while ((r = result) == null) {
if (UNSAFE.compareAndSwapObject
(this, COMPLETIONS, p.next = completions, p))
break;
}
}
if (r != null && (d == null || d.compareAndSet(0, 1))) {
Throwable ex;
if (r instanceof AltResult)
ex = ((AltResult)r).ex;
else
ex = null;
if (ex == null) {
try {
if (e != null)
e.execute(new AsyncRun(action, dst));
else
action.run();
} catch (Throwable rex) {
ex = rex;
}
}
if (e == null || ex != null)
dst.internalComplete(null, ex);
}
helpPostComplete();
return dst;
}
/**
* Returns a new CompletableFuture that is completed
* when both this and the other given CompletableFuture complete,
* with the result of the given function of the results of the two
* CompletableFutures.
*
* If this and/or the other CompletableFuture complete
* exceptionally, or the supplied function throws an exception,
* then the returned CompletableFuture completes exceptionally
* with a CompletionException holding the exception as its cause.
*
* @param other the other CompletableFuture
* @param fn the function to use to compute the value of
* the returned CompletableFuture
* @return the new CompletableFuture
*/
public CompletableFuture thenCombine
(CompletableFuture extends U> other,
BiFun super T,? super U,? extends V> fn) {
return doThenCombine(other, fn, null);
}
/**
* Returns a new CompletableFuture that is asynchronously completed
* when both this and the other given CompletableFuture complete,
* with the result of the given function of the results of the two
* CompletableFutures from a task running in the
* {@link ForkJoinPool#commonPool()}.
*
* If this and/or the other CompletableFuture complete
* exceptionally, or the supplied function throws an exception,
* then the returned CompletableFuture completes exceptionally
* with a CompletionException holding the exception as its cause.
*
* @param other the other CompletableFuture
* @param fn the function to use to compute the value of
* the returned CompletableFuture
* @return the new CompletableFuture
*/
public CompletableFuture thenCombineAsync
(CompletableFuture extends U> other,
BiFun super T,? super U,? extends V> fn) {
return doThenCombine(other, fn, ForkJoinPool.commonPool());
}
/**
* Returns a new CompletableFuture that is asynchronously completed
* when both this and the other given CompletableFuture complete,
* with the result of the given function of the results of the two
* CompletableFutures from a task running in the given executor.
*
* If this and/or the other CompletableFuture complete
* exceptionally, or the supplied function throws an exception,
* then the returned CompletableFuture completes exceptionally
* with a CompletionException holding the exception as its cause.
*
* @param other the other CompletableFuture
* @param fn the function to use to compute the value of
* the returned CompletableFuture
* @param executor the executor to use for asynchronous execution
* @return the new CompletableFuture
*/
public CompletableFuture thenCombineAsync
(CompletableFuture extends U> other,
BiFun super T,? super U,? extends V> fn,
Executor executor) {
if (executor == null) throw new NullPointerException();
return doThenCombine(other, fn, executor);
}
private CompletableFuture doThenCombine
(CompletableFuture extends U> other,
BiFun super T,? super U,? extends V> fn,
Executor e) {
if (other == null || fn == null) throw new NullPointerException();
CompletableFuture dst = new CompletableFuture();
ThenCombine d = null;
Object r, s = null;
if ((r = result) == null || (s = other.result) == null) {
d = new ThenCombine(this, other, fn, dst, e);
CompletionNode q = null, p = new CompletionNode(d);
while ((r == null && (r = result) == null) ||
(s == null && (s = other.result) == null)) {
if (q != null) {
if (s != null ||
UNSAFE.compareAndSwapObject
(other, COMPLETIONS, q.next = other.completions, q))
break;
}
else if (r != null ||
UNSAFE.compareAndSwapObject
(this, COMPLETIONS, p.next = completions, p)) {
if (s != null)
break;
q = new CompletionNode(d);
}
}
}
if (r != null && s != null && (d == null || d.compareAndSet(0, 1))) {
T t; U u; Throwable ex;
if (r instanceof AltResult) {
ex = ((AltResult)r).ex;
t = null;
}
else {
ex = null;
@SuppressWarnings("unchecked") T tr = (T) r;
t = tr;
}
if (ex != null)
u = null;
else if (s instanceof AltResult) {
ex = ((AltResult)s).ex;
u = null;
}
else {
@SuppressWarnings("unchecked") U us = (U) s;
u = us;
}
V v = null;
if (ex == null) {
try {
if (e != null)
e.execute(new AsyncCombine(t, u, fn, dst));
else
v = fn.apply(t, u);
} catch (Throwable rex) {
ex = rex;
}
}
if (e == null || ex != null)
dst.internalComplete(v, ex);
}
helpPostComplete();
other.helpPostComplete();
return dst;
}
/**
* Returns a new CompletableFuture that is completed
* when both this and the other given CompletableFuture complete,
* after performing the given action with the results of the two
* CompletableFutures.
*
* If this and/or the other CompletableFuture complete
* exceptionally, or the supplied action throws an exception,
* then the returned CompletableFuture completes exceptionally
* with a CompletionException holding the exception as its cause.
*
* @param other the other CompletableFuture
* @param block the action to perform before completing the
* returned CompletableFuture
* @return the new CompletableFuture
*/
public CompletableFuture thenAcceptBoth
(CompletableFuture extends U> other,
BiAction super T, ? super U> block) {
return doThenAcceptBoth(other, block, null);
}
/**
* Returns a new CompletableFuture that is asynchronously completed
* when both this and the other given CompletableFuture complete,
* after performing the given action with the results of the two
* CompletableFutures from a task running in the {@link
* ForkJoinPool#commonPool()}.
*
* If this and/or the other CompletableFuture complete
* exceptionally, or the supplied action throws an exception,
* then the returned CompletableFuture completes exceptionally
* with a CompletionException holding the exception as its cause.
*
* @param other the other CompletableFuture
* @param block the action to perform before completing the
* returned CompletableFuture
* @return the new CompletableFuture
*/
public CompletableFuture thenAcceptBothAsync
(CompletableFuture extends U> other,
BiAction super T, ? super U> block) {
return doThenAcceptBoth(other, block, ForkJoinPool.commonPool());
}
/**
* Returns a new CompletableFuture that is asynchronously completed
* when both this and the other given CompletableFuture complete,
* after performing the given action with the results of the two
* CompletableFutures from a task running in the given executor.
*
* If this and/or the other CompletableFuture complete
* exceptionally, or the supplied action throws an exception,
* then the returned CompletableFuture completes exceptionally
* with a CompletionException holding the exception as its cause.
*
* @param other the other CompletableFuture
* @param block the action to perform before completing the
* returned CompletableFuture
* @param executor the executor to use for asynchronous execution
* @return the new CompletableFuture
*/
public CompletableFuture thenAcceptBothAsync
(CompletableFuture extends U> other,
BiAction super T, ? super U> block,
Executor executor) {
if (executor == null) throw new NullPointerException();
return doThenAcceptBoth(other, block, executor);
}
private CompletableFuture doThenAcceptBoth
(CompletableFuture extends U> other,
BiAction super T,? super U> fn,
Executor e) {
if (other == null || fn == null) throw new NullPointerException();
CompletableFuture dst = new CompletableFuture();
ThenAcceptBoth d = null;
Object r, s = null;
if ((r = result) == null || (s = other.result) == null) {
d = new ThenAcceptBoth(this, other, fn, dst, e);
CompletionNode q = null, p = new CompletionNode(d);
while ((r == null && (r = result) == null) ||
(s == null && (s = other.result) == null)) {
if (q != null) {
if (s != null ||
UNSAFE.compareAndSwapObject
(other, COMPLETIONS, q.next = other.completions, q))
break;
}
else if (r != null ||
UNSAFE.compareAndSwapObject
(this, COMPLETIONS, p.next = completions, p)) {
if (s != null)
break;
q = new CompletionNode(d);
}
}
}
if (r != null && s != null && (d == null || d.compareAndSet(0, 1))) {
T t; U u; Throwable ex;
if (r instanceof AltResult) {
ex = ((AltResult)r).ex;
t = null;
}
else {
ex = null;
@SuppressWarnings("unchecked") T tr = (T) r;
t = tr;
}
if (ex != null)
u = null;
else if (s instanceof AltResult) {
ex = ((AltResult)s).ex;
u = null;
}
else {
@SuppressWarnings("unchecked") U us = (U) s;
u = us;
}
if (ex == null) {
try {
if (e != null)
e.execute(new AsyncAcceptBoth(t, u, fn, dst));
else
fn.accept(t, u);
} catch (Throwable rex) {
ex = rex;
}
}
if (e == null || ex != null)
dst.internalComplete(null, ex);
}
helpPostComplete();
other.helpPostComplete();
return dst;
}
/**
* Returns a new CompletableFuture that is completed
* when both this and the other given CompletableFuture complete,
* after performing the given action.
*
* If this and/or the other CompletableFuture complete
* exceptionally, or the supplied action throws an exception,
* then the returned CompletableFuture completes exceptionally
* with a CompletionException holding the exception as its cause.
*
* @param other the other CompletableFuture
* @param action the action to perform before completing the
* returned CompletableFuture
* @return the new CompletableFuture
*/
public CompletableFuture runAfterBoth(CompletableFuture> other,
Runnable action) {
return doRunAfterBoth(other, action, null);
}
/**
* Returns a new CompletableFuture that is asynchronously completed
* when both this and the other given CompletableFuture complete,
* after performing the given action from a task running in the
* {@link ForkJoinPool#commonPool()}.
*
* If this and/or the other CompletableFuture complete
* exceptionally, or the supplied action throws an exception,
* then the returned CompletableFuture completes exceptionally
* with a CompletionException holding the exception as its cause.
*
* @param other the other CompletableFuture
* @param action the action to perform before completing the
* returned CompletableFuture
* @return the new CompletableFuture
*/
public CompletableFuture runAfterBothAsync(CompletableFuture> other,
Runnable action) {
return doRunAfterBoth(other, action, ForkJoinPool.commonPool());
}
/**
* Returns a new CompletableFuture that is asynchronously completed
* when both this and the other given CompletableFuture complete,
* after performing the given action from a task running in the
* given executor.
*
* If this and/or the other CompletableFuture complete
* exceptionally, or the supplied action throws an exception,
* then the returned CompletableFuture completes exceptionally
* with a CompletionException holding the exception as its cause.
*
* @param other the other CompletableFuture
* @param action the action to perform before completing the
* returned CompletableFuture
* @param executor the executor to use for asynchronous execution
* @return the new CompletableFuture
*/
public CompletableFuture runAfterBothAsync(CompletableFuture> other,
Runnable action,
Executor executor) {
if (executor == null) throw new NullPointerException();
return doRunAfterBoth(other, action, executor);
}
private CompletableFuture doRunAfterBoth(CompletableFuture> other,
Runnable action,
Executor e) {
if (other == null || action == null) throw new NullPointerException();
CompletableFuture dst = new CompletableFuture();
RunAfterBoth d = null;
Object r, s = null;
if ((r = result) == null || (s = other.result) == null) {
d = new RunAfterBoth(this, other, action, dst, e);
CompletionNode q = null, p = new CompletionNode(d);
while ((r == null && (r = result) == null) ||
(s == null && (s = other.result) == null)) {
if (q != null) {
if (s != null ||
UNSAFE.compareAndSwapObject
(other, COMPLETIONS, q.next = other.completions, q))
break;
}
else if (r != null ||
UNSAFE.compareAndSwapObject
(this, COMPLETIONS, p.next = completions, p)) {
if (s != null)
break;
q = new CompletionNode(d);
}
}
}
if (r != null && s != null && (d == null || d.compareAndSet(0, 1))) {
Throwable ex;
if (r instanceof AltResult)
ex = ((AltResult)r).ex;
else
ex = null;
if (ex == null && (s instanceof AltResult))
ex = ((AltResult)s).ex;
if (ex == null) {
try {
if (e != null)
e.execute(new AsyncRun(action, dst));
else
action.run();
} catch (Throwable rex) {
ex = rex;
}
}
if (e == null || ex != null)
dst.internalComplete(null, ex);
}
helpPostComplete();
other.helpPostComplete();
return dst;
}
/**
* Returns a new CompletableFuture that is completed
* when either this or the other given CompletableFuture completes,
* with the result of the given function of either this or the other
* CompletableFuture's result.
*
* If this and/or the other CompletableFuture complete
* exceptionally, then the returned CompletableFuture may also do so,
* with a CompletionException holding one of these exceptions as its
* cause. No guarantees are made about which result or exception is
* used in the returned CompletableFuture. If the supplied function
* throws an exception, then the returned CompletableFuture completes
* exceptionally with a CompletionException holding the exception as
* its cause.
*
* @param other the other CompletableFuture
* @param fn the function to use to compute the value of
* the returned CompletableFuture
* @return the new CompletableFuture
*/
public CompletableFuture applyToEither
(CompletableFuture extends T> other,
Fun super T, U> fn) {
return doApplyToEither(other, fn, null);
}
/**
* Returns a new CompletableFuture that is asynchronously completed
* when either this or the other given CompletableFuture completes,
* with the result of the given function of either this or the other
* CompletableFuture's result from a task running in the
* {@link ForkJoinPool#commonPool()}.
*
*
If this and/or the other CompletableFuture complete
* exceptionally, then the returned CompletableFuture may also do so,
* with a CompletionException holding one of these exceptions as its
* cause. No guarantees are made about which result or exception is
* used in the returned CompletableFuture. If the supplied function
* throws an exception, then the returned CompletableFuture completes
* exceptionally with a CompletionException holding the exception as
* its cause.
*
* @param other the other CompletableFuture
* @param fn the function to use to compute the value of
* the returned CompletableFuture
* @return the new CompletableFuture
*/
public CompletableFuture applyToEitherAsync
(CompletableFuture extends T> other,
Fun super T, U> fn) {
return doApplyToEither(other, fn, ForkJoinPool.commonPool());
}
/**
* Returns a new CompletableFuture that is asynchronously completed
* when either this or the other given CompletableFuture completes,
* with the result of the given function of either this or the other
* CompletableFuture's result from a task running in the
* given executor.
*
*
If this and/or the other CompletableFuture complete
* exceptionally, then the returned CompletableFuture may also do so,
* with a CompletionException holding one of these exceptions as its
* cause. No guarantees are made about which result or exception is
* used in the returned CompletableFuture. If the supplied function
* throws an exception, then the returned CompletableFuture completes
* exceptionally with a CompletionException holding the exception as
* its cause.
*
* @param other the other CompletableFuture
* @param fn the function to use to compute the value of
* the returned CompletableFuture
* @param executor the executor to use for asynchronous execution
* @return the new CompletableFuture
*/
public CompletableFuture applyToEitherAsync
(CompletableFuture extends T> other,
Fun super T, U> fn,
Executor executor) {
if (executor == null) throw new NullPointerException();
return doApplyToEither(other, fn, executor);
}
private CompletableFuture doApplyToEither
(CompletableFuture extends T> other,
Fun super T, U> fn,
Executor e) {
if (other == null || fn == null) throw new NullPointerException();
CompletableFuture dst = new CompletableFuture();
ApplyToEither d = null;
Object r;
if ((r = result) == null && (r = other.result) == null) {
d = new ApplyToEither(this, other, fn, dst, e);
CompletionNode q = null, p = new CompletionNode(d);
while ((r = result) == null && (r = other.result) == null) {
if (q != null) {
if (UNSAFE.compareAndSwapObject
(other, COMPLETIONS, q.next = other.completions, q))
break;
}
else if (UNSAFE.compareAndSwapObject
(this, COMPLETIONS, p.next = completions, p))
q = new CompletionNode(d);
}
}
if (r != null && (d == null || d.compareAndSet(0, 1))) {
T t; Throwable ex;
if (r instanceof AltResult) {
ex = ((AltResult)r).ex;
t = null;
}
else {
ex = null;
@SuppressWarnings("unchecked") T tr = (T) r;
t = tr;
}
U u = null;
if (ex == null) {
try {
if (e != null)
e.execute(new AsyncApply(t, fn, dst));
else
u = fn.apply(t);
} catch (Throwable rex) {
ex = rex;
}
}
if (e == null || ex != null)
dst.internalComplete(u, ex);
}
helpPostComplete();
other.helpPostComplete();
return dst;
}
/**
* Returns a new CompletableFuture that is completed
* when either this or the other given CompletableFuture completes,
* after performing the given action with the result of either this
* or the other CompletableFuture's result.
*
* If this and/or the other CompletableFuture complete
* exceptionally, then the returned CompletableFuture may also do so,
* with a CompletionException holding one of these exceptions as its
* cause. No guarantees are made about which result or exception is
* used in the returned CompletableFuture. If the supplied action
* throws an exception, then the returned CompletableFuture completes
* exceptionally with a CompletionException holding the exception as
* its cause.
*
* @param other the other CompletableFuture
* @param block the action to perform before completing the
* returned CompletableFuture
* @return the new CompletableFuture
*/
public CompletableFuture acceptEither
(CompletableFuture extends T> other,
Action super T> block) {
return doAcceptEither(other, block, null);
}
/**
* Returns a new CompletableFuture that is asynchronously completed
* when either this or the other given CompletableFuture completes,
* after performing the given action with the result of either this
* or the other CompletableFuture's result from a task running in
* the {@link ForkJoinPool#commonPool()}.
*
* If this and/or the other CompletableFuture complete
* exceptionally, then the returned CompletableFuture may also do so,
* with a CompletionException holding one of these exceptions as its
* cause. No guarantees are made about which result or exception is
* used in the returned CompletableFuture. If the supplied action
* throws an exception, then the returned CompletableFuture completes
* exceptionally with a CompletionException holding the exception as
* its cause.
*
* @param other the other CompletableFuture
* @param block the action to perform before completing the
* returned CompletableFuture
* @return the new CompletableFuture
*/
public CompletableFuture acceptEitherAsync
(CompletableFuture extends T> other,
Action super T> block) {
return doAcceptEither(other, block, ForkJoinPool.commonPool());
}
/**
* Returns a new CompletableFuture that is asynchronously completed
* when either this or the other given CompletableFuture completes,
* after performing the given action with the result of either this
* or the other CompletableFuture's result from a task running in
* the given executor.
*
* If this and/or the other CompletableFuture complete
* exceptionally, then the returned CompletableFuture may also do so,
* with a CompletionException holding one of these exceptions as its
* cause. No guarantees are made about which result or exception is
* used in the returned CompletableFuture. If the supplied action
* throws an exception, then the returned CompletableFuture completes
* exceptionally with a CompletionException holding the exception as
* its cause.
*
* @param other the other CompletableFuture
* @param block the action to perform before completing the
* returned CompletableFuture
* @param executor the executor to use for asynchronous execution
* @return the new CompletableFuture
*/
public CompletableFuture acceptEitherAsync
(CompletableFuture extends T> other,
Action super T> block,
Executor executor) {
if (executor == null) throw new NullPointerException();
return doAcceptEither(other, block, executor);
}
private CompletableFuture doAcceptEither
(CompletableFuture extends T> other,
Action super T> fn,
Executor e) {
if (other == null || fn == null) throw new NullPointerException();
CompletableFuture dst = new CompletableFuture();
AcceptEither d = null;
Object r;
if ((r = result) == null && (r = other.result) == null) {
d = new AcceptEither(this, other, fn, dst, e);
CompletionNode q = null, p = new CompletionNode(d);
while ((r = result) == null && (r = other.result) == null) {
if (q != null) {
if (UNSAFE.compareAndSwapObject
(other, COMPLETIONS, q.next = other.completions, q))
break;
}
else if (UNSAFE.compareAndSwapObject
(this, COMPLETIONS, p.next = completions, p))
q = new CompletionNode(d);
}
}
if (r != null && (d == null || d.compareAndSet(0, 1))) {
T t; Throwable ex;
if (r instanceof AltResult) {
ex = ((AltResult)r).ex;
t = null;
}
else {
ex = null;
@SuppressWarnings("unchecked") T tr = (T) r;
t = tr;
}
if (ex == null) {
try {
if (e != null)
e.execute(new AsyncAccept(t, fn, dst));
else
fn.accept(t);
} catch (Throwable rex) {
ex = rex;
}
}
if (e == null || ex != null)
dst.internalComplete(null, ex);
}
helpPostComplete();
other.helpPostComplete();
return dst;
}
/**
* Returns a new CompletableFuture that is completed
* when either this or the other given CompletableFuture completes,
* after performing the given action.
*
* If this and/or the other CompletableFuture complete
* exceptionally, then the returned CompletableFuture may also do so,
* with a CompletionException holding one of these exceptions as its
* cause. No guarantees are made about which result or exception is
* used in the returned CompletableFuture. If the supplied action
* throws an exception, then the returned CompletableFuture completes
* exceptionally with a CompletionException holding the exception as
* its cause.
*
* @param other the other CompletableFuture
* @param action the action to perform before completing the
* returned CompletableFuture
* @return the new CompletableFuture
*/
public CompletableFuture runAfterEither(CompletableFuture> other,
Runnable action) {
return doRunAfterEither(other, action, null);
}
/**
* Returns a new CompletableFuture that is asynchronously completed
* when either this or the other given CompletableFuture completes,
* after performing the given action from a task running in the
* {@link ForkJoinPool#commonPool()}.
*
* If this and/or the other CompletableFuture complete
* exceptionally, then the returned CompletableFuture may also do so,
* with a CompletionException holding one of these exceptions as its
* cause. No guarantees are made about which result or exception is
* used in the returned CompletableFuture. If the supplied action
* throws an exception, then the returned CompletableFuture completes
* exceptionally with a CompletionException holding the exception as
* its cause.
*
* @param other the other CompletableFuture
* @param action the action to perform before completing the
* returned CompletableFuture
* @return the new CompletableFuture
*/
public CompletableFuture runAfterEitherAsync
(CompletableFuture> other,
Runnable action) {
return doRunAfterEither(other, action, ForkJoinPool.commonPool());
}
/**
* Returns a new CompletableFuture that is asynchronously completed
* when either this or the other given CompletableFuture completes,
* after performing the given action from a task running in the
* given executor.
*
* If this and/or the other CompletableFuture complete
* exceptionally, then the returned CompletableFuture may also do so,
* with a CompletionException holding one of these exceptions as its
* cause. No guarantees are made about which result or exception is
* used in the returned CompletableFuture. If the supplied action
* throws an exception, then the returned CompletableFuture completes
* exceptionally with a CompletionException holding the exception as
* its cause.
*
* @param other the other CompletableFuture
* @param action the action to perform before completing the
* returned CompletableFuture
* @param executor the executor to use for asynchronous execution
* @return the new CompletableFuture
*/
public CompletableFuture runAfterEitherAsync
(CompletableFuture> other,
Runnable action,
Executor executor) {
if (executor == null) throw new NullPointerException();
return doRunAfterEither(other, action, executor);
}
private CompletableFuture doRunAfterEither
(CompletableFuture> other,
Runnable action,
Executor e) {
if (other == null || action == null) throw new NullPointerException();
CompletableFuture dst = new CompletableFuture();
RunAfterEither d = null;
Object r;
if ((r = result) == null && (r = other.result) == null) {
d = new RunAfterEither(this, other, action, dst, e);
CompletionNode q = null, p = new CompletionNode(d);
while ((r = result) == null && (r = other.result) == null) {
if (q != null) {
if (UNSAFE.compareAndSwapObject
(other, COMPLETIONS, q.next = other.completions, q))
break;
}
else if (UNSAFE.compareAndSwapObject
(this, COMPLETIONS, p.next = completions, p))
q = new CompletionNode(d);
}
}
if (r != null && (d == null || d.compareAndSet(0, 1))) {
Throwable ex;
if (r instanceof AltResult)
ex = ((AltResult)r).ex;
else
ex = null;
if (ex == null) {
try {
if (e != null)
e.execute(new AsyncRun(action, dst));
else
action.run();
} catch (Throwable rex) {
ex = rex;
}
}
if (e == null || ex != null)
dst.internalComplete(null, ex);
}
helpPostComplete();
other.helpPostComplete();
return dst;
}
/**
* Returns a CompletableFuture that upon completion, has the same
* value as produced by the given function of the result of this
* CompletableFuture.
*
* If this CompletableFuture completes exceptionally, then the
* returned CompletableFuture also does so, with a
* CompletionException holding this exception as its cause.
* Similarly, if the computed CompletableFuture completes
* exceptionally, then so does the returned CompletableFuture.
*
* @param fn the function returning a new CompletableFuture
* @return the CompletableFuture
*/
public CompletableFuture thenCompose
(Fun super T, CompletableFuture> fn) {
return doThenCompose(fn, null);
}
/**
* Returns a CompletableFuture that upon completion, has the same
* value as that produced asynchronously using the {@link
* ForkJoinPool#commonPool()} by the given function of the result
* of this CompletableFuture.
*
*
If this CompletableFuture completes exceptionally, then the
* returned CompletableFuture also does so, with a
* CompletionException holding this exception as its cause.
* Similarly, if the computed CompletableFuture completes
* exceptionally, then so does the returned CompletableFuture.
*
* @param fn the function returning a new CompletableFuture
* @return the CompletableFuture
*/
public CompletableFuture thenComposeAsync
(Fun super T, CompletableFuture> fn) {
return doThenCompose(fn, ForkJoinPool.commonPool());
}
/**
* Returns a CompletableFuture that upon completion, has the same
* value as that produced asynchronously using the given executor
* by the given function of this CompletableFuture.
*
*
If this CompletableFuture completes exceptionally, then the
* returned CompletableFuture also does so, with a
* CompletionException holding this exception as its cause.
* Similarly, if the computed CompletableFuture completes
* exceptionally, then so does the returned CompletableFuture.
*
* @param fn the function returning a new CompletableFuture
* @param executor the executor to use for asynchronous execution
* @return the CompletableFuture
*/
public CompletableFuture thenComposeAsync
(Fun super T, CompletableFuture> fn,
Executor executor) {
if (executor == null) throw new NullPointerException();
return doThenCompose(fn, executor);
}
private CompletableFuture doThenCompose
(Fun super T, CompletableFuture> fn,
Executor e) {
if (fn == null) throw new NullPointerException();
CompletableFuture dst = null;
ThenCompose d = null;
Object r;
if ((r = result) == null) {
dst = new CompletableFuture();
CompletionNode p = new CompletionNode
(d = new ThenCompose(this, fn, dst, e));
while ((r = result) == null) {
if (UNSAFE.compareAndSwapObject
(this, COMPLETIONS, p.next = completions, p))
break;
}
}
if (r != null && (d == null || d.compareAndSet(0, 1))) {
T t; Throwable ex;
if (r instanceof AltResult) {
ex = ((AltResult)r).ex;
t = null;
}
else {
ex = null;
@SuppressWarnings("unchecked") T tr = (T) r;
t = tr;
}
if (ex == null) {
if (e != null) {
if (dst == null)
dst = new CompletableFuture();
e.execute(new AsyncCompose(t, fn, dst));
}
else {
try {
if ((dst = fn.apply(t)) == null)
ex = new NullPointerException();
} catch (Throwable rex) {
ex = rex;
}
}
}
if (dst == null)
dst = new CompletableFuture();
if (ex != null)
dst.internalComplete(null, ex);
}
helpPostComplete();
dst.helpPostComplete();
return dst;
}
/**
* Returns a new CompletableFuture that is completed when this
* CompletableFuture completes, with the result of the given
* function of the exception triggering this CompletableFuture's
* completion when it completes exceptionally; otherwise, if this
* CompletableFuture completes normally, then the returned
* CompletableFuture also completes normally with the same value.
*
* @param fn the function to use to compute the value of the
* returned CompletableFuture if this CompletableFuture completed
* exceptionally
* @return the new CompletableFuture
*/
public CompletableFuture exceptionally
(Fun fn) {
if (fn == null) throw new NullPointerException();
CompletableFuture dst = new CompletableFuture();
ExceptionCompletion d = null;
Object r;
if ((r = result) == null) {
CompletionNode p =
new CompletionNode(d = new ExceptionCompletion(this, fn, dst));
while ((r = result) == null) {
if (UNSAFE.compareAndSwapObject(this, COMPLETIONS,
p.next = completions, p))
break;
}
}
if (r != null && (d == null || d.compareAndSet(0, 1))) {
T t = null; Throwable ex, dx = null;
if (r instanceof AltResult) {
if ((ex = ((AltResult)r).ex) != null) {
try {
t = fn.apply(ex);
} catch (Throwable rex) {
dx = rex;
}
}
}
else {
@SuppressWarnings("unchecked") T tr = (T) r;
t = tr;
}
dst.internalComplete(t, dx);
}
helpPostComplete();
return dst;
}
/**
* Returns a new CompletableFuture that is completed when this
* CompletableFuture completes, with the result of the given
* function of the result and exception of this CompletableFuture's
* completion. The given function is invoked with the result (or
* {@code null} if none) and the exception (or {@code null} if none)
* of this CompletableFuture when complete.
*
* @param fn the function to use to compute the value of the
* returned CompletableFuture
* @return the new CompletableFuture
*/
public CompletableFuture handle
(BiFun super T, Throwable, ? extends U> fn) {
if (fn == null) throw new NullPointerException();
CompletableFuture dst = new CompletableFuture