001    /*
002     * Copyright (C) 2009 The Guava Authors
003     *
004     * Licensed under the Apache License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of the License at
007     *
008     * http://www.apache.org/licenses/LICENSE-2.0
009     *
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     * See the License for the specific language governing permissions and
014     * limitations under the License.
015     */
016    
017    package com.google.common.util.concurrent;
018    
019    import static com.google.common.base.Preconditions.checkNotNull;
020    
021    import com.google.common.annotations.Beta;
022    
023    import java.util.concurrent.Executor;
024    import java.util.concurrent.Executors;
025    import java.util.concurrent.Future;
026    import java.util.concurrent.ThreadFactory;
027    import java.util.concurrent.atomic.AtomicBoolean;
028    
029    /**
030     * Utilities necessary for working with libraries that supply plain {@link
031     * Future} instances. Note that, whenver possible, it is strongly preferred to
032     * modify those libraries to return {@code ListenableFuture} directly.
033     *
034     * @author Sven Mawson
035     * @since 10.0 (replacing {@code Futures.makeListenable}, which
036     *     existed in 1.0)
037     */
038    @Beta
039    public final class JdkFutureAdapters {
040      /**
041       * Assigns a thread to the given {@link Future} to provide {@link
042       * ListenableFuture} functionality.
043       *
044       * <p><b>Warning:</b> If the input future does not already implement {@code
045       * ListenableFuture}, the returned future will emulate {@link
046       * ListenableFuture#addListener} by taking a thread from an internal,
047       * unbounded pool at the first call to {@code addListener} and holding it
048       * until the future is {@linkplain Future#isDone() done}.
049       *
050       * <p>Prefer to create {@code ListenableFuture} instances with {@link
051       * SettableFuture}, {@link MoreExecutors#listeningDecorator(
052       * java.util.concurrent.ExecutorService)}, {@link ListenableFutureTask},
053       * {@link AbstractFuture}, and other utilities over creating plain {@code
054       * Future} instances to be upgraded to {@code ListenableFuture} after the
055       * fact.
056       */
057      public static <V> ListenableFuture<V> listenInPoolThread(
058          Future<V> future) {
059        if (future instanceof ListenableFuture<?>) {
060          return (ListenableFuture<V>) future;
061        }
062        return new ListenableFutureAdapter<V>(future);
063      }
064    
065      /**
066       * Submits a blocking task for the given {@link Future} to provide {@link
067       * ListenableFuture} functionality.
068       *
069       * <p><b>Warning:</b> If the input future does not already implement {@code
070       * ListenableFuture}, the returned future will emulate {@link
071       * ListenableFuture#addListener} by submitting a task to the given executor at
072       * at the first call to {@code addListener}. The task must be started by the
073       * executor promptly, or else the returned {@code ListenableFuture} may fail
074       * to work.  The task's execution consists of blocking until the input future
075       * is {@linkplain Future#isDone() done}, so each call to this method may
076       * claim and hold a thread for an arbitrary length of time. Use of bounded
077       * executors or other executors that may fail to execute a task promptly may
078       * result in deadlocks.
079       *
080       * <p>Prefer to create {@code ListenableFuture} instances with {@link
081       * SettableFuture}, {@link MoreExecutors#listeningDecorator(
082       * java.util.concurrent.ExecutorService)}, {@link ListenableFutureTask},
083       * {@link AbstractFuture}, and other utilities over creating plain {@code
084       * Future} instances to be upgraded to {@code ListenableFuture} after the
085       * fact.
086       *
087       * @since 12.0
088       */
089      public static <V> ListenableFuture<V> listenInPoolThread(
090          Future<V> future, Executor executor) {
091        checkNotNull(executor);
092        if (future instanceof ListenableFuture<?>) {
093          return (ListenableFuture<V>) future;
094        }
095        return new ListenableFutureAdapter<V>(future, executor);
096      }
097    
098      /**
099       * An adapter to turn a {@link Future} into a {@link ListenableFuture}.  This
100       * will wait on the future to finish, and when it completes, run the
101       * listeners.  This implementation will wait on the source future
102       * indefinitely, so if the source future never completes, the adapter will
103       * never complete either.
104       *
105       * <p>If the delegate future is interrupted or throws an unexpected unchecked
106       * exception, the listeners will not be invoked.
107       */
108      private static class ListenableFutureAdapter<V> extends ForwardingFuture<V>
109          implements ListenableFuture<V> {
110    
111        private static final ThreadFactory threadFactory =
112            new ThreadFactoryBuilder()
113                .setDaemon(true)
114                .setNameFormat("ListenableFutureAdapter-thread-%d")
115                .build();
116        private static final Executor defaultAdapterExecutor =
117            Executors.newCachedThreadPool(threadFactory);
118    
119        private final Executor adapterExecutor;
120    
121        // The execution list to hold our listeners.
122        private final ExecutionList executionList = new ExecutionList();
123    
124        // This allows us to only start up a thread waiting on the delegate future
125        // when the first listener is added.
126        private final AtomicBoolean hasListeners = new AtomicBoolean(false);
127    
128        // The delegate future.
129        private final Future<V> delegate;
130    
131        ListenableFutureAdapter(Future<V> delegate) {
132          this(delegate, defaultAdapterExecutor);
133        }
134    
135        ListenableFutureAdapter(Future<V> delegate, Executor adapterExecutor) {
136          this.delegate = checkNotNull(delegate);
137          this.adapterExecutor = checkNotNull(adapterExecutor);
138        }
139    
140        @Override
141        protected Future<V> delegate() {
142          return delegate;
143        }
144    
145        @Override
146        public void addListener(Runnable listener, Executor exec) {
147          executionList.add(listener, exec);
148    
149          // When a listener is first added, we run a task that will wait for
150          // the delegate to finish, and when it is done will run the listeners.
151          if (hasListeners.compareAndSet(false, true)) {
152            if (delegate.isDone()) {
153              // If the delegate is already done, run the execution list
154              // immediately on the current thread.
155              executionList.execute();
156              return;
157            }
158    
159            adapterExecutor.execute(new Runnable() {
160              @Override
161              public void run() {
162                try {
163                  delegate.get();
164                } catch (Error e) {
165                  throw e;
166                } catch (InterruptedException e) {
167                  Thread.currentThread().interrupt();
168                  // Threads from our private pool are never interrupted.
169                  throw new AssertionError(e);
170                } catch (Throwable e) {
171                  // ExecutionException / CancellationException / RuntimeException
172                  // The task is done, run the listeners.
173                }
174                executionList.execute();
175              }
176            });
177          }
178        }
179      }
180    
181      private JdkFutureAdapters() {}
182    }