package com.netifera.platform.net.sockets.internal;
import java.net.SocketTimeoutException;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
import com.netifera.platform.api.log.ILogger;
import com.netifera.platform.net.sockets.CompletionHandler;
public class SelectionFuture<V,A> extends FutureTask<V> {
final CompletionHandler<V,? super A> handler;
final A attachment;
final long deadline;
private final ILogger logger;
public SelectionFuture(CompletionHandler<V,? super A> handler, A attachment, long deadline, ILogger logger, Callable<V> callable) {
super(callable);
this.deadline = deadline;
this.handler = handler;
this.attachment = attachment;
this.logger = logger;
}
@Override
protected void done() {
if (handler == null) return;
try {
if (this.isCancelled())
handler.cancelled(attachment);
else {
final V value;
try {
value = get();
} catch (InterruptedException e) {
handler.failed(e, attachment);
Thread.interrupted();
return;
} catch (ExecutionException e) {
handler.failed(e.getCause(), attachment);
return;
}
handler.completed(value, attachment);
}
} catch (Throwable e) {
//NOTE if we dont do this, it will eat the exceptions
logger.error("Unhandled exception in SelectionFuture", e);
// FIXME re-throw e?
}
}
public long getDeadline() {
return deadline;
}
public boolean testTimeOut(long now) {
if (deadline > now) return false;
setException(new SocketTimeoutException());
return true;
}
}