@Override public final void addListener(@Nonnull Runnable listener, @Nonnull Executor executor) { super.addListener(listener, executor); } }
/** * Unboxes {@code obj}. Assumes that obj is not {@code null} or a {@link SetFuture}. */ private V getDoneValue(Object obj) throws ExecutionException { // While this seems like it might be too branch-y, simple benchmarking proves it to be // unmeasurable (comparing done AbstractFutures with immediateFuture) if (obj instanceof Cancellation) { throw cancellationExceptionWithCause("Task was cancelled.", ((Cancellation) obj).cause); } else if (obj instanceof Failure) { throw new ExecutionException(((Failure) obj).exception); } else if (obj == NULL) { return null; } else { @SuppressWarnings("unchecked") // this is the only other option V asV = (V) obj; return asV; } }
/** Unblocks all threads and runs all listeners. */ private void complete() { for (Waiter currentWaiter = clearWaiters(); currentWaiter != null; currentWaiter = currentWaiter.next) { currentWaiter.unpark(); } // We need to reverse the list to handle buggy listeners that depend on ordering. Listener currentListener = clearListeners(); Listener reversedList = null; while (currentListener != null) { Listener tmp = currentListener; currentListener = currentListener.next; tmp.next = reversedList; reversedList = tmp; } for (; reversedList != null; reversedList = reversedList.next) { executeListener(reversedList.task, reversedList.executor); } // We call this after the listeners on the theory that done() will only be used for 'cleanup' // oriented tasks (e.g. clearing fields) and so can wait behind listeners which may be executing // more important work. A counter argument would be that done() is trusted code and therefore // it would be safe to run before potentially slow or poorly behaved listeners. Reevaluate this // once we have more examples of done() implementations. done(); }
Throwable cause = GENERATE_CANCELLATION_CAUSES ? newCancellationCause() : null; Object valueToSet = new Cancellation(mayInterruptIfRunning, cause); do { interruptTask(); complete(); if (localValue instanceof AbstractFuture.SetFuture) {
return getDoneValue(localValue); removeWaiter(node); throw new InterruptedException(); return getDoneValue(localValue); return getDoneValue(value);
/** * Sets the result of this {@code Future} unless this {@code Future} has already been cancelled or * set (including {@linkplain #setFuture set asynchronously}). When a call to this method returns, * the {@code Future} is guaranteed to be {@linkplain #isDone done} <b>only if</b> the call was * accepted (in which case it returns {@code true}). If it returns {@code false}, the {@code * Future} may have previously been set asynchronously, in which case its result may not be known * yet. That result, though not yet known, cannot by overridden by a call to a {@code set*} * method, only by a call to {@link #cancel}. * * @param value the value to be used as the result * @return true if the attempt was accepted, completing the {@code Future} */ protected boolean set(@Nullable V value) { Object valueToSet = value == null ? NULL : value; if (ATOMIC_HELPER.casValue(this, null, valueToSet)) { complete(); return true; } return false; }
@Nullable @Override public final V get() throws InterruptedException, ExecutionException { return super.get(); }
/** * {@inheritDoc} * * @since 10.0 */ @Override public void addListener(@Nonnull Runnable listener, @Nonnull Executor executor) { Preconditions.checkNotNull(listener, "Runnable was null."); Preconditions.checkNotNull(executor, "Executor was null."); Listener oldHead = listeners; if (oldHead != Listener.TOMBSTONE) { Listener newNode = new Listener(listener, executor); do { newNode.next = oldHead; if (ATOMIC_HELPER.casListeners(this, oldHead, newNode)) { return; } oldHead = listeners; // re-read } while (oldHead != Listener.TOMBSTONE); } // If we get here then the Listener TOMBSTONE was set, which means the future is done, call // the listener. executeListener(listener, executor); }
if (localValue == null) { if (future.isDone()) { return completeWithFuture(future, null);
return getDoneValue(localValue); removeWaiter(node); throw new InterruptedException(); return getDoneValue(localValue); if (remainingNanos < SPIN_THRESHOLD_NANOS) { removeWaiter(node); break long_wait_loop; // jump down to the busy wait loop return getDoneValue(value); localValue = value; if (localValue != null & !(localValue instanceof AbstractFuture.SetFuture)) { return getDoneValue(localValue);
/** * Sets the failed result of this {@code Future} unless this {@code Future} has already been * cancelled or set (including {@linkplain #setFuture set asynchronously}). When a call to this * method returns, the {@code Future} is guaranteed to be {@linkplain #isDone done} <b>only if</b> * the call was accepted (in which case it returns {@code true}). If it returns {@code false}, the * {@code Future} may have previously been set asynchronously, in which case its result may not be * known yet. That result, though not yet known, cannot by overridden by a call to a {@code set*} * method, only by a call to {@link #cancel}. * * @param throwable the exception to be used as the failed result * @return true if the attempt was accepted, completing the {@code Future} */ protected boolean setException(Throwable throwable) { Object valueToSet = new Failure(Preconditions.checkNotNull(throwable)); if (ATOMIC_HELPER.casValue(this, null, valueToSet)) { complete(); return true; } return false; }
@Nullable @Override public final V get(long timeout, @Nonnull TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException { return super.get(timeout, unit); }
complete(); return true;