10888a09821a98ac0680fad765217302858e70fa4Paul Duffin/*
20888a09821a98ac0680fad765217302858e70fa4Paul Duffin * Copyright (C) 2009 The Guava Authors
30888a09821a98ac0680fad765217302858e70fa4Paul Duffin *
40888a09821a98ac0680fad765217302858e70fa4Paul Duffin * Licensed under the Apache License, Version 2.0 (the "License");
50888a09821a98ac0680fad765217302858e70fa4Paul Duffin * you may not use this file except in compliance with the License.
60888a09821a98ac0680fad765217302858e70fa4Paul Duffin * You may obtain a copy of the License at
70888a09821a98ac0680fad765217302858e70fa4Paul Duffin *
80888a09821a98ac0680fad765217302858e70fa4Paul Duffin * http://www.apache.org/licenses/LICENSE-2.0
90888a09821a98ac0680fad765217302858e70fa4Paul Duffin *
100888a09821a98ac0680fad765217302858e70fa4Paul Duffin * Unless required by applicable law or agreed to in writing, software
110888a09821a98ac0680fad765217302858e70fa4Paul Duffin * distributed under the License is distributed on an "AS IS" BASIS,
120888a09821a98ac0680fad765217302858e70fa4Paul Duffin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130888a09821a98ac0680fad765217302858e70fa4Paul Duffin * See the License for the specific language governing permissions and
140888a09821a98ac0680fad765217302858e70fa4Paul Duffin * limitations under the License.
150888a09821a98ac0680fad765217302858e70fa4Paul Duffin */
160888a09821a98ac0680fad765217302858e70fa4Paul Duffin
170888a09821a98ac0680fad765217302858e70fa4Paul Duffinpackage com.google.common.util.concurrent.testing;
180888a09821a98ac0680fad765217302858e70fa4Paul Duffin
193ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffinimport static com.google.common.util.concurrent.MoreExecutors.newDirectExecutorService;
203ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin
210888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport com.google.common.base.Preconditions;
220888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport com.google.common.util.concurrent.ForwardingListenableFuture.SimpleForwardingListenableFuture;
230888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport com.google.common.util.concurrent.ListenableFuture;
240888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport com.google.common.util.concurrent.ListenableScheduledFuture;
250888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport com.google.common.util.concurrent.ListeningExecutorService;
260888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport com.google.common.util.concurrent.ListeningScheduledExecutorService;
270888a09821a98ac0680fad765217302858e70fa4Paul Duffin
280888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport java.util.Collection;
290888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport java.util.List;
300888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport java.util.concurrent.AbstractExecutorService;
310888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport java.util.concurrent.Callable;
320888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport java.util.concurrent.Delayed;
330888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport java.util.concurrent.ExecutionException;
340888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport java.util.concurrent.Future;
350888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport java.util.concurrent.TimeUnit;
360888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport java.util.concurrent.TimeoutException;
370888a09821a98ac0680fad765217302858e70fa4Paul Duffin
380888a09821a98ac0680fad765217302858e70fa4Paul Duffin/**
390888a09821a98ac0680fad765217302858e70fa4Paul Duffin * A ScheduledExecutorService that executes all scheduled actions immediately
400888a09821a98ac0680fad765217302858e70fa4Paul Duffin * in the calling thread.
410888a09821a98ac0680fad765217302858e70fa4Paul Duffin *
420888a09821a98ac0680fad765217302858e70fa4Paul Duffin * See {@link TestingExecutors#sameThreadScheduledExecutor()} for a full list of
430888a09821a98ac0680fad765217302858e70fa4Paul Duffin * constraints.
440888a09821a98ac0680fad765217302858e70fa4Paul Duffin *
450888a09821a98ac0680fad765217302858e70fa4Paul Duffin * @author John Sirois
460888a09821a98ac0680fad765217302858e70fa4Paul Duffin * @author Zach van Schouwen
470888a09821a98ac0680fad765217302858e70fa4Paul Duffin */
480888a09821a98ac0680fad765217302858e70fa4Paul Duffinclass SameThreadScheduledExecutorService extends AbstractExecutorService
490888a09821a98ac0680fad765217302858e70fa4Paul Duffin    implements ListeningScheduledExecutorService {
500888a09821a98ac0680fad765217302858e70fa4Paul Duffin
513ecfa412eddc4b084663f38d562537b86b9734d5Paul Duffin  private final ListeningExecutorService delegate = newDirectExecutorService();
520888a09821a98ac0680fad765217302858e70fa4Paul Duffin
530888a09821a98ac0680fad765217302858e70fa4Paul Duffin  @Override
540888a09821a98ac0680fad765217302858e70fa4Paul Duffin  public void shutdown() {
550888a09821a98ac0680fad765217302858e70fa4Paul Duffin    delegate.shutdown();
560888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
570888a09821a98ac0680fad765217302858e70fa4Paul Duffin
580888a09821a98ac0680fad765217302858e70fa4Paul Duffin  @Override
590888a09821a98ac0680fad765217302858e70fa4Paul Duffin  public List<Runnable> shutdownNow() {
600888a09821a98ac0680fad765217302858e70fa4Paul Duffin    return delegate.shutdownNow();
610888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
620888a09821a98ac0680fad765217302858e70fa4Paul Duffin
630888a09821a98ac0680fad765217302858e70fa4Paul Duffin  @Override
640888a09821a98ac0680fad765217302858e70fa4Paul Duffin  public boolean isShutdown() {
650888a09821a98ac0680fad765217302858e70fa4Paul Duffin    return delegate.isShutdown();
660888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
670888a09821a98ac0680fad765217302858e70fa4Paul Duffin
680888a09821a98ac0680fad765217302858e70fa4Paul Duffin  @Override
690888a09821a98ac0680fad765217302858e70fa4Paul Duffin  public boolean isTerminated() {
700888a09821a98ac0680fad765217302858e70fa4Paul Duffin    return delegate.isTerminated();
710888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
720888a09821a98ac0680fad765217302858e70fa4Paul Duffin
730888a09821a98ac0680fad765217302858e70fa4Paul Duffin  @Override
740888a09821a98ac0680fad765217302858e70fa4Paul Duffin  public boolean awaitTermination(long timeout, TimeUnit unit)
750888a09821a98ac0680fad765217302858e70fa4Paul Duffin      throws InterruptedException {
760888a09821a98ac0680fad765217302858e70fa4Paul Duffin    Preconditions.checkNotNull(unit, "unit must not be null!");
770888a09821a98ac0680fad765217302858e70fa4Paul Duffin    return delegate.awaitTermination(timeout, unit);
780888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
790888a09821a98ac0680fad765217302858e70fa4Paul Duffin
800888a09821a98ac0680fad765217302858e70fa4Paul Duffin  @Override
810888a09821a98ac0680fad765217302858e70fa4Paul Duffin  public <T> ListenableFuture<T> submit(Callable<T> task) {
820888a09821a98ac0680fad765217302858e70fa4Paul Duffin    Preconditions.checkNotNull(task, "task must not be null!");
830888a09821a98ac0680fad765217302858e70fa4Paul Duffin    return delegate.submit(task);
840888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
850888a09821a98ac0680fad765217302858e70fa4Paul Duffin
860888a09821a98ac0680fad765217302858e70fa4Paul Duffin  @Override
870888a09821a98ac0680fad765217302858e70fa4Paul Duffin  public <T> ListenableFuture<T> submit(Runnable task, T result) {
880888a09821a98ac0680fad765217302858e70fa4Paul Duffin    Preconditions.checkNotNull(task, "task must not be null!");
890888a09821a98ac0680fad765217302858e70fa4Paul Duffin    Preconditions.checkNotNull(result, "result must not be null!");
900888a09821a98ac0680fad765217302858e70fa4Paul Duffin    return delegate.submit(task, result);
910888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
920888a09821a98ac0680fad765217302858e70fa4Paul Duffin
930888a09821a98ac0680fad765217302858e70fa4Paul Duffin  @Override
940888a09821a98ac0680fad765217302858e70fa4Paul Duffin  public ListenableFuture<?> submit(Runnable task) {
950888a09821a98ac0680fad765217302858e70fa4Paul Duffin    Preconditions.checkNotNull(task, "task must not be null!");
960888a09821a98ac0680fad765217302858e70fa4Paul Duffin    return delegate.submit(task);
970888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
980888a09821a98ac0680fad765217302858e70fa4Paul Duffin
990888a09821a98ac0680fad765217302858e70fa4Paul Duffin  @Override
1000888a09821a98ac0680fad765217302858e70fa4Paul Duffin  public <T> List<Future<T>> invokeAll(
1010888a09821a98ac0680fad765217302858e70fa4Paul Duffin      Collection<? extends Callable<T>> tasks) throws InterruptedException {
1020888a09821a98ac0680fad765217302858e70fa4Paul Duffin    Preconditions.checkNotNull(tasks, "tasks must not be null!");
1030888a09821a98ac0680fad765217302858e70fa4Paul Duffin    return delegate.invokeAll(tasks);
1040888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
1050888a09821a98ac0680fad765217302858e70fa4Paul Duffin
1060888a09821a98ac0680fad765217302858e70fa4Paul Duffin  @Override
1070888a09821a98ac0680fad765217302858e70fa4Paul Duffin  public <T> List<Future<T>> invokeAll(
1080888a09821a98ac0680fad765217302858e70fa4Paul Duffin      Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit)
1090888a09821a98ac0680fad765217302858e70fa4Paul Duffin      throws InterruptedException {
1100888a09821a98ac0680fad765217302858e70fa4Paul Duffin    Preconditions.checkNotNull(tasks, "tasks must not be null!");
1110888a09821a98ac0680fad765217302858e70fa4Paul Duffin    Preconditions.checkNotNull(unit, "unit must not be null!");
1120888a09821a98ac0680fad765217302858e70fa4Paul Duffin    return delegate.invokeAll(tasks, timeout, unit);
1130888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
1140888a09821a98ac0680fad765217302858e70fa4Paul Duffin
1150888a09821a98ac0680fad765217302858e70fa4Paul Duffin  @Override
1160888a09821a98ac0680fad765217302858e70fa4Paul Duffin  public <T> T invokeAny(Collection<? extends Callable<T>> tasks)
1170888a09821a98ac0680fad765217302858e70fa4Paul Duffin      throws InterruptedException, ExecutionException {
1180888a09821a98ac0680fad765217302858e70fa4Paul Duffin    Preconditions.checkNotNull(tasks, "tasks must not be null!");
1190888a09821a98ac0680fad765217302858e70fa4Paul Duffin    return delegate.invokeAny(tasks);
1200888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
1210888a09821a98ac0680fad765217302858e70fa4Paul Duffin
1220888a09821a98ac0680fad765217302858e70fa4Paul Duffin  @Override
1230888a09821a98ac0680fad765217302858e70fa4Paul Duffin  public <T> T invokeAny(Collection<? extends Callable<T>> tasks,
1240888a09821a98ac0680fad765217302858e70fa4Paul Duffin      long timeout, TimeUnit unit)
1250888a09821a98ac0680fad765217302858e70fa4Paul Duffin      throws InterruptedException, ExecutionException, TimeoutException {
1260888a09821a98ac0680fad765217302858e70fa4Paul Duffin    Preconditions.checkNotNull(tasks, "tasks must not be null!");
1270888a09821a98ac0680fad765217302858e70fa4Paul Duffin    Preconditions.checkNotNull(unit, "unit must not be null!");
1280888a09821a98ac0680fad765217302858e70fa4Paul Duffin    return delegate.invokeAny(tasks, timeout, unit);
1290888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
1300888a09821a98ac0680fad765217302858e70fa4Paul Duffin
1310888a09821a98ac0680fad765217302858e70fa4Paul Duffin  @Override
1320888a09821a98ac0680fad765217302858e70fa4Paul Duffin  public void execute(Runnable command) {
1330888a09821a98ac0680fad765217302858e70fa4Paul Duffin    Preconditions.checkNotNull(command, "command must not be null!");
1340888a09821a98ac0680fad765217302858e70fa4Paul Duffin    delegate.execute(command);
1350888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
1360888a09821a98ac0680fad765217302858e70fa4Paul Duffin
1370888a09821a98ac0680fad765217302858e70fa4Paul Duffin  @Override
1380888a09821a98ac0680fad765217302858e70fa4Paul Duffin  public ListenableScheduledFuture<?> schedule(Runnable command, long delay,
1390888a09821a98ac0680fad765217302858e70fa4Paul Duffin      TimeUnit unit) {
1400888a09821a98ac0680fad765217302858e70fa4Paul Duffin    Preconditions.checkNotNull(command, "command must not be null");
1410888a09821a98ac0680fad765217302858e70fa4Paul Duffin    Preconditions.checkNotNull(unit, "unit must not be null!");
1420888a09821a98ac0680fad765217302858e70fa4Paul Duffin    return schedule(java.util.concurrent.Executors.callable(command),
1430888a09821a98ac0680fad765217302858e70fa4Paul Duffin        delay, unit);
1440888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
1450888a09821a98ac0680fad765217302858e70fa4Paul Duffin
1460888a09821a98ac0680fad765217302858e70fa4Paul Duffin  private static class ImmediateScheduledFuture<V>
1470888a09821a98ac0680fad765217302858e70fa4Paul Duffin      extends SimpleForwardingListenableFuture<V>
1480888a09821a98ac0680fad765217302858e70fa4Paul Duffin      implements ListenableScheduledFuture<V> {
1490888a09821a98ac0680fad765217302858e70fa4Paul Duffin    private ExecutionException exception;
1500888a09821a98ac0680fad765217302858e70fa4Paul Duffin
1510888a09821a98ac0680fad765217302858e70fa4Paul Duffin    protected ImmediateScheduledFuture(ListenableFuture<V> future) {
1520888a09821a98ac0680fad765217302858e70fa4Paul Duffin      super(future);
1530888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
1540888a09821a98ac0680fad765217302858e70fa4Paul Duffin
1550888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Override
1560888a09821a98ac0680fad765217302858e70fa4Paul Duffin    public V get(long timeout, TimeUnit unit)
1570888a09821a98ac0680fad765217302858e70fa4Paul Duffin        throws InterruptedException, ExecutionException, TimeoutException {
1580888a09821a98ac0680fad765217302858e70fa4Paul Duffin      Preconditions.checkNotNull(unit, "unit must not be null!");
1590888a09821a98ac0680fad765217302858e70fa4Paul Duffin      return get();
1600888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
1610888a09821a98ac0680fad765217302858e70fa4Paul Duffin
1620888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Override
1630888a09821a98ac0680fad765217302858e70fa4Paul Duffin    public long getDelay(TimeUnit unit) {
1640888a09821a98ac0680fad765217302858e70fa4Paul Duffin      Preconditions.checkNotNull(unit, "unit must not be null!");
1650888a09821a98ac0680fad765217302858e70fa4Paul Duffin      return 0;
1660888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
1670888a09821a98ac0680fad765217302858e70fa4Paul Duffin
1680888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Override
1690888a09821a98ac0680fad765217302858e70fa4Paul Duffin    public int compareTo(Delayed other) {
1700888a09821a98ac0680fad765217302858e70fa4Paul Duffin      Preconditions.checkNotNull(other, "other must not be null!");
1710888a09821a98ac0680fad765217302858e70fa4Paul Duffin      return 0;
1720888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
1730888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
1740888a09821a98ac0680fad765217302858e70fa4Paul Duffin
1750888a09821a98ac0680fad765217302858e70fa4Paul Duffin  @Override
1760888a09821a98ac0680fad765217302858e70fa4Paul Duffin  public <V> ListenableScheduledFuture<V> schedule(final Callable<V> callable,
1770888a09821a98ac0680fad765217302858e70fa4Paul Duffin      long delay, TimeUnit unit) {
1780888a09821a98ac0680fad765217302858e70fa4Paul Duffin    Preconditions.checkNotNull(callable, "callable must not be null!");
1790888a09821a98ac0680fad765217302858e70fa4Paul Duffin    Preconditions.checkNotNull(unit, "unit must not be null!");
1800888a09821a98ac0680fad765217302858e70fa4Paul Duffin    ListenableFuture<V> delegateFuture = submit(callable);
1810888a09821a98ac0680fad765217302858e70fa4Paul Duffin    return new ImmediateScheduledFuture<V>(delegateFuture);
1820888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
1830888a09821a98ac0680fad765217302858e70fa4Paul Duffin
1840888a09821a98ac0680fad765217302858e70fa4Paul Duffin  @Override
1850888a09821a98ac0680fad765217302858e70fa4Paul Duffin  public ListenableScheduledFuture<?> scheduleAtFixedRate(Runnable command,
1860888a09821a98ac0680fad765217302858e70fa4Paul Duffin      long initialDelay, long period, TimeUnit unit) {
1870888a09821a98ac0680fad765217302858e70fa4Paul Duffin    throw new UnsupportedOperationException(
1880888a09821a98ac0680fad765217302858e70fa4Paul Duffin        "scheduleAtFixedRate is not supported.");
1890888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
1900888a09821a98ac0680fad765217302858e70fa4Paul Duffin
1910888a09821a98ac0680fad765217302858e70fa4Paul Duffin  @Override
1920888a09821a98ac0680fad765217302858e70fa4Paul Duffin  public ListenableScheduledFuture<?> scheduleWithFixedDelay(Runnable command,
1930888a09821a98ac0680fad765217302858e70fa4Paul Duffin      long initialDelay, long delay, TimeUnit unit) {
1940888a09821a98ac0680fad765217302858e70fa4Paul Duffin    throw new UnsupportedOperationException(
1950888a09821a98ac0680fad765217302858e70fa4Paul Duffin        "scheduleWithFixedDelay is not supported.");
1960888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
1970888a09821a98ac0680fad765217302858e70fa4Paul Duffin}
198