package com.github.rfqu.simpleactor;
import java.util.LinkedList;
import java.util.Queue;
import java.util.concurrent.Executor;
/**
* Messages are already Runnables.
*/
public class SerialExecutor implements Executor, Runnable {
private final Executor executor;
/** current task */
private Runnable active=null;
/** rest of tasks */
private final Queue<Runnable> tasks = new LinkedList<Runnable>();
public SerialExecutor(Executor executor) {
this.executor = executor;
}
/**
* Frontend method which may be called from other Thread or Actor.
* Saves the message and initiates Actor's execution.
*/
public void execute(Runnable task) {
if (task==null) {
throw new IllegalArgumentException("task may not be null");
}
synchronized(tasks ) {
if (active != null) {
tasks.add(task);
return;
}
active=task;
}
executor.execute(this);
}
@Override
public final void run() {
for (;;) {
active.run();
synchronized(tasks) {
if ((active = tasks.poll())==null) {
return;
}
}
}
}
}