@Override public void andThen(ExecutionCallback<V> callback) { andThen(callback, defaultExecutor); }
/** * Can be called multiple times, but only the first answer will lead to the * future getting triggered. All subsequent complete calls are ignored. * * @param value The type of response to offer. * @return <tt>true</tt> if offered response, either a final response or an * internal response, is set/applied, <tt>false</tt> otherwise. If <tt>false</tt> * is returned, that means offered response is ignored because a final response * is already set to this future. */ @Override public final boolean complete(Object value) { for (; ; ) { final Object oldState = state; if (isDone(oldState)) { warnIfSuspiciousDoubleCompletion(oldState, value); return false; } if (compareAndSetState(oldState, value)) { onComplete(); unblockAll(oldState, defaultExecutor); return true; } } }
@Override public boolean cancel(boolean mayInterruptIfRunning) { return complete(new CancellationException()); }
@Override public String toString() { Object state = getState(); if (isDone(state)) { return "InvocationFuture{invocation=" + invocationToString() + ", value=" + state + '}'; } else { return "InvocationFuture{invocation=" + invocationToString() + ", done=false}"; } }
@Override public V get(final long timeout, final TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException { Object response = registerWaiter(Thread.currentThread(), null); if (response != VOID) { return resolveAndThrowIfException(response); } long deadlineNanos = System.nanoTime() + unit.toNanos(timeout); boolean interrupted = false; try { long timeoutNanos = unit.toNanos(timeout); while (timeoutNanos > 0) { parkNanos(timeoutNanos); timeoutNanos = deadlineNanos - System.nanoTime(); if (isDone()) { return resolveAndThrowIfException(state); } else if (Thread.interrupted()) { interrupted = true; onInterruptDetected(); } } } finally { restoreInterrupt(interrupted); } unregisterWaiter(Thread.currentThread()); throw newTimeoutException(timeout, unit); }
@Override public final V get() throws InterruptedException, ExecutionException { Object response = registerWaiter(Thread.currentThread(), null); if (response != VOID) { // no registration was done since a value is available. return resolveAndThrowIfException(response); } boolean interrupted = false; try { for (; ; ) { park(); if (isDone()) { return resolveAndThrowIfException(state); } else if (Thread.interrupted()) { interrupted = true; onInterruptDetected(); } } } finally { restoreInterrupt(interrupted); } }
@Override public void run() { try { Object value = resolve(state); if (value instanceof Throwable) { Throwable error = unwrap((Throwable) value); callback.onFailure(error); } else { callback.onResponse((V) value); } } catch (Throwable cause) { logger.severe("Failed asynchronous execution of execution callback: " + callback + "for call " + invocationToString(), cause); } }
for (; ; ) { final Object oldState = state; if (isDone(oldState)) { return oldState; if (compareAndSetState(oldState, newState)) {
@Override public E get(final long timeout, final TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException { // assert (!Thread.currentThread().getName().contains("client.thread")); return super.get(timeout, unit); } }
private void warnIfSuspiciousDoubleCompletion(Object s0, Object s1) { if (s0 != s1 && !(s0 instanceof CancellationException) && !(s1 instanceof CancellationException)) { logger.warning(String.format("Future.complete(Object) on completed future. " + "Request: %s, current value: %s, offered value: %s", invocationToString(), s0, s1)); } }
@Override public final boolean isDone() { return isDone(state); }
void unregisterWaiter(Thread waiter) { WaitNode prev = null; Object current = state; while (current != null) { Object currentWaiter = current.getClass() == WaitNode.class ? ((WaitNode) current).waiter : current; Object next = current.getClass() == WaitNode.class ? ((WaitNode) current).next : null; if (currentWaiter == waiter) { // it is the item we are looking for, so lets try to remove it if (prev == null) { // it's the first item of the stack, so we need to change the head to the next Object n = next == null ? VOID : next; // if we manage to CAS we are done, else we need to restart current = compareAndSetState(current, n) ? null : state; } else { // remove the current item (this is done by letting the prev.next point to the next instead of current) prev.next = next; // end the loop current = null; } } else { // it isn't the item we are looking for, so lets move on to the next prev = current.getClass() == WaitNode.class ? (WaitNode) current : null; current = next; } } }
@Override public final V get(final long timeout, final TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException { Object response = registerWaiter(Thread.currentThread(), null); if (response != VOID) { return resolveAndThrowIfException(response); } long deadlineNanos = System.nanoTime() + unit.toNanos(timeout); boolean interrupted = false; try { long timeoutNanos = unit.toNanos(timeout); while (timeoutNanos > 0) { parkNanos(timeoutNanos); timeoutNanos = deadlineNanos - System.nanoTime(); if (isDone()) { return resolveAndThrowIfException(state); } else if (Thread.interrupted()) { interrupted = true; onInterruptDetected(); } } } finally { restoreInterrupt(interrupted); } unregisterWaiter(Thread.currentThread()); throw newTimeoutException(timeout, unit); }
@Override public V get() throws InterruptedException, ExecutionException { Object response = registerWaiter(Thread.currentThread(), null); if (response != VOID) { // no registration was done since a value is available. return resolveAndThrowIfException(response); } boolean interrupted = false; try { for (; ; ) { park(); if (isDone()) { return resolveAndThrowIfException(state); } else if (Thread.interrupted()) { interrupted = true; onInterruptDetected(); } } } finally { restoreInterrupt(interrupted); } }
@Override public String toString() { Object state = getState(); if (isDone(state)) { return "InvocationFuture{invocation=" + invocationToString() + ", value=" + state + '}'; } else { return "InvocationFuture{invocation=" + invocationToString() + ", done=false}"; } }
@Override public void run() { try { Object value = resolve(state); if (value instanceof Throwable) { Throwable error = unwrap((Throwable) value); callback.onFailure(error); } else { callback.onResponse((V) value); } } catch (Throwable cause) { logger.severe("Failed asynchronous execution of execution callback: " + callback + "for call " + invocationToString(), cause); } }
for (; ; ) { final Object oldState = state; if (isDone(oldState)) { return oldState; if (compareAndSetState(oldState, newState)) {
@Override public E get() throws InterruptedException, ExecutionException { // assert (!Thread.currentThread().getName().contains("client.thread")); return super.get(); }
private void warnIfSuspiciousDoubleCompletion(Object s0, Object s1) { if (s0 != s1 && !(s0 instanceof CancellationException) && !(s1 instanceof CancellationException)) { logger.warning(String.format("Future.complete(Object) on completed future. " + "Request: %s, current value: %s, offered value: %s", invocationToString(), s0, s1)); } }
@Override public final boolean isDone() { return isDone(state); }