/*
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
package com.facebook.common.executors;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.AbstractExecutorService;
import java.util.concurrent.TimeUnit;
/**
* An executor service that runs each task in the thread that invokes {@code execute/submit}.
*
* <p> This applies both to individually submitted tasks and to collections of tasks submitted via
* {@code invokeAll} or {@code invokeAny}. In the latter case, tasks will run serially on the
* calling thread. Tasks are run to completion before a {@code Future} is returned to the caller.
*
* <p> The implementation deviates from the {@code ExecutorService} specification with regards to
* the {@code shutdownNow} and {@code awaitTermination} methods.
* 1. A call to {@code shutdown} or {@code shutdownNow} is a no-op. A call to {@code isTerminated}
* always returns false.
* 2. A call to {@code awaitTermination} always returns true immediately. True is returned in order
* to avoid potential infinite loop in the clients.
* 3. "best-effort" with regards to canceling running tasks is implemented as "no-effort".
* No interrupts or other attempts are made to stop threads executing tasks.
* 4. The returned list will always be empty, as any submitted task is considered to have started
* execution. This applies also to tasks given to {@code invokeAll} or {@code invokeAny} which
* are pending serial execution, including the tasks that have not yet started execution.
*/
public class CallerThreadExecutor extends AbstractExecutorService {
private static final CallerThreadExecutor sInstance = new CallerThreadExecutor();
public static CallerThreadExecutor getInstance() {
return sInstance;
}
private CallerThreadExecutor() {
}
@Override
public void execute(Runnable command) {
command.run();
}
@Override
public boolean isShutdown() {
return false;
}
@Override
public void shutdown() {
// no-op
}
@Override
public List<Runnable> shutdownNow() {
shutdown();
return Collections.emptyList();
}
@Override
public boolean isTerminated() {
return false;
}
@Override
public boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException {
return true;
}
}