1bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor/*
21d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Copyright (C) 2007 The Guava Authors
3bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor *
4bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * Licensed under the Apache License, Version 2.0 (the "License");
5bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * you may not use this file except in compliance with the License.
6bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * You may obtain a copy of the License at
7bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor *
8bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * http://www.apache.org/licenses/LICENSE-2.0
9bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor *
10bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * Unless required by applicable law or agreed to in writing, software
11bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * distributed under the License is distributed on an "AS IS" BASIS,
12bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * See the License for the specific language governing permissions and
14bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * limitations under the License.
15bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor */
16bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor
17bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnorpackage com.google.common.util.concurrent;
18bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor
191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static com.google.common.base.Preconditions.checkNotNull;
201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
21bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnorimport java.util.concurrent.CancellationException;
22bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnorimport java.util.concurrent.ExecutionException;
231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.concurrent.Executor;
24bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnorimport java.util.concurrent.TimeUnit;
25bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnorimport java.util.concurrent.TimeoutException;
26bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnorimport java.util.concurrent.locks.AbstractQueuedSynchronizer;
27bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor
281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport javax.annotation.Nullable;
291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
30bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor/**
311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * An abstract implementation of the {@link ListenableFuture} interface. This
321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * class is preferable to {@link java.util.concurrent.FutureTask} for two
331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * reasons: It implements {@code ListenableFuture}, and it does not implement
341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@code Runnable}. (If you want a {@code Runnable} implementation of {@code
351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * ListenableFuture}, create a {@link ListenableFutureTask}, or submit your
361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * tasks to a {@link ListeningExecutorService}.)
371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>This class implements all methods in {@code ListenableFuture}.
391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Subclasses should provide a way to set the result of the computation through
401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * the protected methods {@link #set(Object)} and
411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@link #setException(Throwable)}. Subclasses may also override {@link
421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * #interruptTask()}, which will be invoked automatically if a call to {@link
431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * #cancel(boolean) cancel(true)} succeeds in canceling the future.
44bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor *
451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>{@code AbstractFuture} uses an {@link AbstractQueuedSynchronizer} to deal
461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * with concurrency issues and guarantee thread safety.
47bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor *
48bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * <p>The state changing methods all return a boolean indicating success or
49bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * failure in changing the future's state.  Valid states are running,
501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * completed, failed, or cancelled.
511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>This class uses an {@link ExecutionList} to guarantee that all registered
531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * listeners will be executed, either when the future finishes or, for listeners
541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * that are added after the future completes, immediately.
551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@code Runnable}-{@code Executor} pairs are stored in the execution list but
561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * are not necessarily executed in the order in which they were added.  (If a
571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * listener is added after the Future is complete, it will be executed
581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * immediately, even if earlier listeners have not been executed. Additionally,
591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * executors need not guarantee FIFO execution, or different listeners may run
601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * in different executors.)
61bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor *
62bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @author Sven Mawson
631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @since 1.0
64bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor */
651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertpublic abstract class AbstractFuture<V> implements ListenableFuture<V> {
66bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor
67bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  /** Synchronization control for AbstractFutures. */
68bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  private final Sync<V> sync = new Sync<V>();
69bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor
701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  // The execution list to hold our executors.
711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private final ExecutionList executionList = new ExecutionList();
721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
73bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  /*
741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Improve the documentation of when InterruptedException is thrown. Our
751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * behavior matches the JDK's, but the JDK's documentation is misleading.
761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * {@inheritDoc}
791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>The default {@link AbstractFuture} implementation throws {@code
811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * InterruptedException} if the current thread is interrupted before or during
821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * the call, even if the value is already available.
831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @throws InterruptedException if the current thread was interrupted before
851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *     or during the call (optional but recommended).
861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @throws CancellationException {@inheritDoc}
87bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   */
881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @Override
89bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  public V get(long timeout, TimeUnit unit) throws InterruptedException,
90bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor      TimeoutException, ExecutionException {
91bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    return sync.get(unit.toNanos(timeout));
92bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  }
93bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor
94bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  /*
951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Improve the documentation of when InterruptedException is thrown. Our
961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * behavior matches the JDK's, but the JDK's documentation is misleading.
971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * {@inheritDoc}
1001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
1011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>The default {@link AbstractFuture} implementation throws {@code
1021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * InterruptedException} if the current thread is interrupted before or during
1031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * the call, even if the value is already available.
1041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
1051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @throws InterruptedException if the current thread was interrupted before
1061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *     or during the call (optional but recommended).
1071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @throws CancellationException {@inheritDoc}
108bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   */
1091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @Override
110bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  public V get() throws InterruptedException, ExecutionException {
111bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    return sync.get();
112bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  }
113bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor
1141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @Override
115bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  public boolean isDone() {
116bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    return sync.isDone();
117bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  }
118bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor
1191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @Override
120bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  public boolean isCancelled() {
121bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    return sync.isCancelled();
122bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  }
123bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor
1241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @Override
125bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  public boolean cancel(boolean mayInterruptIfRunning) {
1261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    if (!sync.cancel()) {
1271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return false;
1281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    executionList.execute();
1301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    if (mayInterruptIfRunning) {
1311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      interruptTask();
1321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return true;
1341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
1371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Subclasses can override this method to implement interruption of the
1381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * future's computation. The method is invoked automatically by a successful
1391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * call to {@link #cancel(boolean) cancel(true)}.
1401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
1411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>The default implementation does nothing.
1421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
1431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @since 10.0
1441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
1451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  protected void interruptTask() {
1461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
1491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * {@inheritDoc}
1501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
1511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @since 10.0
1521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
1531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @Override
1541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void addListener(Runnable listener, Executor exec) {
1551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    executionList.add(listener, exec);
156bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  }
157bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor
158bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  /**
159bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * Subclasses should invoke this method to set the result of the computation
160bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * to {@code value}.  This will set the state of the future to
1611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * {@link AbstractFuture.Sync#COMPLETED} and invoke the listeners if the
162bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * state was successfully changed.
163bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   *
164bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * @param value the value that was the result of the task.
165bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * @return true if the state was successfully changed.
166bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   */
1671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  protected boolean set(@Nullable V value) {
168bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    boolean result = sync.set(value);
169bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    if (result) {
1701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      executionList.execute();
171bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    }
172bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    return result;
173bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  }
174bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor
175bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  /**
176bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * Subclasses should invoke this method to set the result of the computation
177bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * to an error, {@code throwable}.  This will set the state of the future to
1781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * {@link AbstractFuture.Sync#COMPLETED} and invoke the listeners if the
179bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * state was successfully changed.
180bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   *
181bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * @param throwable the exception that the task failed with.
182bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * @return true if the state was successfully changed.
183bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * @throws Error if the throwable was an {@link Error}.
184bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   */
185bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  protected boolean setException(Throwable throwable) {
1861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    boolean result = sync.setException(checkNotNull(throwable));
187bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    if (result) {
1881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      executionList.execute();
189bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    }
190bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor
191bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    // If it's an Error, we want to make sure it reaches the top of the
192bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    // call stack, so we rethrow it.
193bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    if (throwable instanceof Error) {
194bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor      throw (Error) throwable;
195bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    }
196bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    return result;
197bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  }
198bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor
199bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  /**
200bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * <p>Following the contract of {@link AbstractQueuedSynchronizer} we create a
201bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * private subclass to hold the synchronizer.  This synchronizer is used to
202bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * implement the blocking and waiting calls as well as to handle state changes
203bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * in a thread-safe manner.  The current state of the future is held in the
204bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * Sync state, and the lock is released whenever the state changes to either
205bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * {@link #COMPLETED} or {@link #CANCELLED}.
206bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   *
207bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * <p>To avoid races between threads doing release and acquire, we transition
208bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * to the final state in two steps.  One thread will successfully CAS from
209bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * RUNNING to COMPLETING, that thread will then set the result of the
210bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * computation, and only then transition to COMPLETED or CANCELLED.
211bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   *
212bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * <p>We don't use the integer argument passed between acquire methods so we
213bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * pass around a -1 everywhere.
214bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   */
215bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  static final class Sync<V> extends AbstractQueuedSynchronizer {
216bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor
217bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    private static final long serialVersionUID = 0L;
218bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor
219bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    /* Valid states. */
220bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    static final int RUNNING = 0;
221bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    static final int COMPLETING = 1;
222bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    static final int COMPLETED = 2;
223bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    static final int CANCELLED = 4;
224bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor
225bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    private V value;
2261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    private Throwable exception;
227bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor
228bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    /*
229bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor     * Acquisition succeeds if the future is done, otherwise it fails.
230bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor     */
231bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    @Override
232bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    protected int tryAcquireShared(int ignored) {
233bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor      if (isDone()) {
234bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor        return 1;
235bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor      }
236bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor      return -1;
237bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    }
238bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor
239bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    /*
240bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor     * We always allow a release to go through, this means the state has been
241bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor     * successfully changed and the result is available.
242bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor     */
243bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    @Override
244bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    protected boolean tryReleaseShared(int finalState) {
245bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor      setState(finalState);
246bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor      return true;
247bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    }
248bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor
249bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    /**
250bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor     * Blocks until the task is complete or the timeout expires.  Throws a
251bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor     * {@link TimeoutException} if the timer expires, otherwise behaves like
252bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor     * {@link #get()}.
253bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor     */
254bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    V get(long nanos) throws TimeoutException, CancellationException,
255bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor        ExecutionException, InterruptedException {
256bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor
257bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor      // Attempt to acquire the shared lock with a timeout.
258bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor      if (!tryAcquireSharedNanos(-1, nanos)) {
259bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor        throw new TimeoutException("Timeout waiting for task.");
260bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor      }
261bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor
262bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor      return getValue();
263bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    }
264bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor
265bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    /**
266bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor     * Blocks until {@link #complete(Object, Throwable, int)} has been
267bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor     * successfully called.  Throws a {@link CancellationException} if the task
268bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor     * was cancelled, or a {@link ExecutionException} if the task completed with
269bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor     * an error.
270bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor     */
271bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    V get() throws CancellationException, ExecutionException,
272bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor        InterruptedException {
273bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor
274bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor      // Acquire the shared lock allowing interruption.
275bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor      acquireSharedInterruptibly(-1);
276bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor      return getValue();
277bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    }
278bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor
279bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    /**
280bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor     * Implementation of the actual value retrieval.  Will return the value
281bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor     * on success, an exception on failure, a cancellation on cancellation, or
282bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor     * an illegal state if the synchronizer is in an invalid state.
283bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor     */
284bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    private V getValue() throws CancellationException, ExecutionException {
285bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor      int state = getState();
286bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor      switch (state) {
287bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor        case COMPLETED:
288bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor          if (exception != null) {
2891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            throw new ExecutionException(exception);
290bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor          } else {
291bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor            return value;
292bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor          }
293bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor
294bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor        case CANCELLED:
295bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor          throw new CancellationException("Task was cancelled.");
296bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor
297bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor        default:
298bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor          throw new IllegalStateException(
299bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor              "Error, synchronizer in invalid state: " + state);
300bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor      }
301bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    }
302bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor
303bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    /**
304bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor     * Checks if the state is {@link #COMPLETED} or {@link #CANCELLED}.
305bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor     */
306bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    boolean isDone() {
307bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor      return (getState() & (COMPLETED | CANCELLED)) != 0;
308bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    }
309bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor
310bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    /**
311bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor     * Checks if the state is {@link #CANCELLED}.
312bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor     */
313bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    boolean isCancelled() {
314bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor      return getState() == CANCELLED;
315bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    }
316bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor
317bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    /**
318bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor     * Transition to the COMPLETED state and set the value.
319bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor     */
3201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    boolean set(@Nullable V v) {
321bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor      return complete(v, null, COMPLETED);
322bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    }
323bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor
324bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    /**
325bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor     * Transition to the COMPLETED state and set the exception.
326bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor     */
327bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    boolean setException(Throwable t) {
328bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor      return complete(null, t, COMPLETED);
329bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    }
330bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor
331bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    /**
332bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor     * Transition to the CANCELLED state.
333bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor     */
334bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    boolean cancel() {
335bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor      return complete(null, null, CANCELLED);
336bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    }
337bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor
338bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    /**
339bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor     * Implementation of completing a task.  Either {@code v} or {@code t} will
340bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor     * be set but not both.  The {@code finalState} is the state to change to
341bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor     * from {@link #RUNNING}.  If the state is not in the RUNNING state we
3421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert     * return {@code false} after waiting for the state to be set to a valid
3431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert     * final state ({@link #COMPLETED} or {@link #CANCELLED}).
344bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor     *
345bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor     * @param v the value to set as the result of the computation.
346bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor     * @param t the exception to set as the result of the computation.
347bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor     * @param finalState the state to transition to.
348bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor     */
3491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    private boolean complete(@Nullable V v, @Nullable Throwable t,
3501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        int finalState) {
3511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      boolean doCompletion = compareAndSetState(RUNNING, COMPLETING);
3521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      if (doCompletion) {
3531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        // If this thread successfully transitioned to COMPLETING, set the value
3541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        // and exception and then release to the final state.
355bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor        this.value = v;
3561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        this.exception = t;
357bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor        releaseShared(finalState);
3581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      } else if (getState() == COMPLETING) {
3591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        // If some other thread is currently completing the future, block until
3601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        // they are done so we can guarantee completion.
3611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        acquireShared(-1);
362bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor      }
3631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return doCompletion;
364bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    }
365bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  }
366bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor}
367