/* * Copyright (c) 2012-2014, Parallel Universe Software Co. All rights reserved. * * This program and the accompanying materials are dual-licensed under * either the terms of the Eclipse Public License v1.0 as published by * the Eclipse Foundation * * or (per the licensee's choosing) * * under the terms of the GNU Lesser General Public License version 3.0 * as published by the Free Software Foundation. */ package co.paralleluniverse.common.concurrent; 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; /** * * @author pron */ public class SimpleFuture<V> implements Future<V> { private final Lock lock = new ReentrantLock(); private final Condition cond = lock.newCondition(); private volatile boolean done; private V result; private Throwable exception; @Override public boolean isDone() { return done; } @Override public V get() throws InterruptedException, ExecutionException { lock.lock(); try { while (!done) cond.await(); return getResult(); } finally { lock.unlock(); } } @Override public V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException { lock.lock(); try { if (!cond.await(timeout, unit)) throw new TimeoutException(); else return getResult(); } finally { lock.unlock(); } } private V getResult() throws ExecutionException { if(exception != null) throw new ExecutionException(exception); else return result; } public void setResult(V result) { this.result = result; } public void setException(Throwable exception) { this.exception = exception; } public void done() { lock.lock(); try { cond.signalAll(); } finally { lock.unlock(); } } public void done(V result) { lock.lock(); try { setResult(result); cond.signalAll(); } finally { lock.unlock(); } } public void failed(Throwable exception) { lock.lock(); try { setException(exception); cond.signalAll(); } finally { lock.unlock(); } } @Override public boolean cancel(boolean mayInterruptIfRunning) { throw new UnsupportedOperationException("Not supported."); } @Override public boolean isCancelled() { return false; } }