package codechicken.nei;
import com.google.common.base.Objects;
import net.minecraftforge.fml.common.FMLCommonHandler;
public class ThreadOperationTimer extends Thread {
@SuppressWarnings("serial")
public static class TimeoutException extends RuntimeException {
public final Object operation;
public TimeoutException(String msg, Object op) {
super(msg);
operation = op;
}
}
private Thread thread;
private Object operation;
private long opTime;
private long limit;
private ThreadOperationTimer(Thread thread, int limit) {
super(thread.getName() + " Operation Timer");
this.thread = thread;
this.limit = limit;
}
public synchronized void setLimit(int limit) {
this.limit = limit;
}
public void reset() {
reset(null);
}
public synchronized void reset(Object op) {
operation = op;
opTime = System.currentTimeMillis();
}
public synchronized void update(Object op) {
if (!Objects.equal(operation, op)) {
operation = op;
opTime = System.currentTimeMillis();
}
}
@SuppressWarnings("deprecation")
@Override
public void run() {
if (FMLCommonHandler.instance().findContainerFor("NotEnoughItems").getVersion().contains("$")) {
return;//don't run this thread in a source environment
}
while (thread.isAlive()) {
synchronized (this) {
if (operation != null && System.currentTimeMillis() - opTime > limit) {
thread.stop(new TimeoutException("Operation took too long", operation));
}
}
try {
Thread.sleep(50);
} catch (InterruptedException ie) {
}
}
}
public static ThreadOperationTimer start(Thread thread, int limit) {
ThreadOperationTimer t = new ThreadOperationTimer(thread, limit);
t.start();
return t;
}
}