package org.jetbrains.jps.incremental.java;
import java.util.Queue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.atomic.AtomicBoolean;
/**
* @author Eugene Zhuravlev
* Date: 9/24/11
*/
public class SequentialTaskExecutor {
private final ExecutorService myExecutor;
private final Queue<Runnable> myTaskQueue = new LinkedBlockingQueue<Runnable>();
private final AtomicBoolean myInProgress = new AtomicBoolean(false);
private final Runnable USER_TASK_RUNNER = new Runnable() {
public void run() {
final Runnable task = myTaskQueue.poll();
try {
if (task != null) {
task.run();
}
}
finally {
myInProgress.set(false);
if (!myTaskQueue.isEmpty()) {
processQueue();
}
}
}
};
public SequentialTaskExecutor(ExecutorService executor) {
myExecutor = executor;
}
public void submit(Runnable task) {
if (myTaskQueue.offer(task)) {
processQueue();
}
else {
throw new RuntimeException("Failed to queue task: " + task);
}
}
private void processQueue() {
if (!myInProgress.getAndSet(true)) {
myExecutor.submit(USER_TASK_RUNNER);
}
}
}