PageRenderTime 19ms CodeModel.GetById 13ms app.highlight 3ms RepoModel.GetById 1ms app.codeStats 0ms

/interpreter/tags/reactive-pattern-matching/src/edu/vub/at/actors/eventloops/BlockingFuture.java

http://ambienttalk.googlecode.com/
Java | 147 lines | 56 code | 14 blank | 77 comment | 7 complexity | 7bbe4417781ca6db574777ec95903a3e MD5 | raw file
  1/**
  2 * AmbientTalk/2 Project
  3 * BlockingFuture.java created on 21-dec-2006 at 10:16:26
  4 * (c) Programming Technology Lab, 2006 - 2007
  5 * Authors: Tom Van Cutsem & Stijn Mostinckx
  6 * 
  7 * Permission is hereby granted, free of charge, to any person
  8 * obtaining a copy of this software and associated documentation
  9 * files (the "Software"), to deal in the Software without
 10 * restriction, including without limitation the rights to use,
 11 * copy, modify, merge, publish, distribute, sublicense, and/or
 12 * sell copies of the Software, and to permit persons to whom the
 13 * Software is furnished to do so, subject to the following
 14 * conditions:
 15 *
 16 * The above copyright notice and this permission notice shall be
 17 * included in all copies or substantial portions of the Software.
 18 *
 19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 20 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 21 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 22 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 23 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 24 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 25 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 26 * OTHER DEALINGS IN THE SOFTWARE.
 27 */
 28package edu.vub.at.actors.eventloops;
 29
 30
 31/**
 32 * A BlockingFuture represents a synchronous, blocking future used by the AT/2 implementation
 33 * to synchronize between native threads.
 34 * 
 35 * Usage:
 36 *  <code>
 37 *    BlockingFuture future = object.doAsynchronousComputation();
 38 *    try {
 39 *      Object result = future.get();
 40 *    } catch(Exception e) {
 41 *      // async computation raised an exception
 42 *    }
 43 *  </code>
 44 *
 45 * Based on source code written by Doug Lea with assistance from members of JCP JSR-166
 46 * Expert Group and released to the public domain.
 47 *
 48 * @author tvcutsem
 49 */
 50public final class BlockingFuture implements Future {
 51	
 52    private Object result;
 53    
 54    private Exception exception;
 55    
 56    private boolean fulfilled = false;
 57    
 58    /** Returns whether the future has been either resolved with a value or ruined by an exception */
 59    public synchronized boolean isDetermined() {
 60        return fulfilled;
 61    }
 62	
 63	public Object get() throws Exception {
 64		Object result;
 65		synchronized(this) {
 66			waitFor();
 67			result = getResult();
 68		}
 69    	// 'blocking future' pipelining...
 70    	if (result instanceof BlockingFuture) {
 71    		return ((BlockingFuture) result).get();
 72    	} else {
 73    		return result;
 74    	}
 75	}
 76	
 77    /**
 78     * Sets the result of this Future to the given value unless
 79     * this future has already been set or has been cancelled.
 80     * @param v the value
 81     */
 82    public void resolve(Object v) {
 83        setCompleted(v);
 84    }
 85
 86    /**
 87     * Causes this future to report an <tt>ExecutionException</tt>
 88     * with the given throwable as its cause, unless this Future has
 89     * already been set or has been cancelled.
 90     * @param e the cause of failure
 91     */
 92    public void ruin(Exception e) {
 93        setFailed(e);
 94    }
 95    
 96    /**
 97     * Marks the task as completed.
 98     * @param result the result of a task.
 99     */
100    private void setCompleted(Object result) {
101        synchronized (this) {
102            if (fulfilled) return;
103            fulfilled = true;
104            this.result = result;
105            notifyAll();
106        }
107    }
108
109    /**
110     * Marks the task as failed.
111     * @param exception the cause of abrupt completion.
112     */
113    private void setFailed(Exception exception) {
114        synchronized (this) {
115            if (fulfilled) return;
116            fulfilled = true;
117            this.exception = exception;
118            notifyAll();
119        }
120    }
121	
122    /**
123     * Waits for the task to complete.
124     * PRE: lock owned
125     */
126    private void waitFor() {
127        while (!isDetermined()) {
128            try {
129				wait();
130			} catch (InterruptedException e) { }
131        }
132    }
133
134    /**
135     * Gets the result of the task.
136     *
137     * PRE: task completed
138     * PRE: lock owned
139     */
140    private Object getResult() throws Exception {
141        if (exception != null) {
142            throw exception;
143        }
144        return result;
145    }
146    
147}