package org.httpkit.timer;
import clojure.lang.IFn;
import org.httpkit.PriorityQueue;
import java.util.concurrent.atomic.AtomicBoolean;
public class CancelableFutureTask implements Comparable<CancelableFutureTask> {
private final int timeout;
private final IFn futureTask;
public final long timeoutTs;
private final AtomicBoolean done = new AtomicBoolean(false);
private final PriorityQueue<CancelableFutureTask> queue;
public CancelableFutureTask(int timeout, IFn task, PriorityQueue<CancelableFutureTask> queue) {
this.timeoutTs = System.currentTimeMillis() + timeout;
this.timeout = timeout;
this.futureTask = task;
this.queue = queue;
}
public String toString() {
long now = System.currentTimeMillis();
if (done.get()) {
return "timeout=" + timeout + "ms, done or canceled";
} else {
return "timeout=" + timeout + "ms, due in " + (timeoutTs - now) + "ms";
}
}
public void runTask() {
if (done.compareAndSet(false, true)) {
futureTask.invoke();
}
}
public boolean cancel() {
boolean b = done.compareAndSet(false, true);
if (b) {// ok, not done
synchronized (queue) {
queue.remove(this);
}
}
return b;
}
public int compareTo(CancelableFutureTask o) {
return (int) (timeoutTs - o.timeoutTs);
}
}