package com.voxeo.moho.common.util;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class SettableResultFuture<C> implements Future<C>, FutureResult<C> {
final Lock lock = new ReentrantLock();
private Condition hasResult = lock.newCondition();
private C result;
// Needed to support a result value of null
private boolean complete;
private Throwable exception;
@Override
public boolean cancel(boolean mayInterruptIfRunning) {
return false;
}
@Override
public boolean isCancelled() {
return false;
}
@Override
public boolean isDone() {
return complete;
}
@Override
public C get() throws InterruptedException, ExecutionException {
if (!complete) {
lock.lock();
try {
while (!complete) {
hasResult.await();
}
}
finally {
lock.unlock();
}
}
if (exception != null) {
throw new ExecutionException(exception);
}
return result;
}
@Override
public C get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
if (!complete) {
lock.lock();
try {
while (!complete) {
if (!hasResult.await(timeout, unit)) {
throw new TimeoutException();
}
}
}
finally {
lock.unlock();
}
}
if (exception != null) {
throw new ExecutionException(exception);
}
return result;
}
public void setResult(C result) {
this.result = result;
this.complete = true;
lock.lock();
try {
hasResult.signalAll();
}
finally {
lock.unlock();
}
}
public void setException(Throwable t) {
this.exception = t;
this.complete = true;
lock.lock();
try {
hasResult.signalAll();
}
finally {
lock.unlock();
}
}
}