001: /*
002: * @(#)async.java 1.2 04/12/06
003: *
004: * Copyright (c) 2001-2004 Sun Microsystems, Inc. All Rights Reserved.
005: *
006: * See the file "LICENSE.txt" for information on usage and redistribution
007: * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
008: */
009: package org.pnuts.multithread;
010:
011: import pnuts.lang.PnutsFunction;
012: import pnuts.lang.Context;
013: import pnuts.lang.PnutsException;
014:
015: /*
016: * thread_pool = threadPool()
017: * handle = async(function ()..., thread_pool)
018: * ...
019: * handle()
020: */
021: public class async extends PnutsFunction {
022:
023: public async() {
024: super ("async");
025: }
026:
027: public boolean defined(int nargs) {
028: return nargs == 2;
029: }
030:
031: protected Object exec(Object[] args, final Context context) {
032: if (args.length != 2) {
033: undefined(args, context);
034: return null;
035: }
036: final PnutsFunction func = (PnutsFunction) args[0];
037: final ThreadPool pool = (ThreadPool) args[1];
038:
039: class Env {
040: Object result;
041: Throwable throwable;
042: int state = 0; // 1==success, 2==exception thrown
043: Task task;
044: Context ctx;
045:
046: Env() {
047: this .task = new Task();
048: this .ctx = new Context(context);
049: pool.addTask(task);
050: }
051:
052: protected synchronized Object getResult(Context context)
053: throws InterruptedException {
054: while (state == 0) {
055: wait();
056: }
057: if (state == 1) {
058: return result;
059: }
060: throw new PnutsException(throwable, context);
061: }
062:
063: class Task implements Runnable {
064: public void run() {
065: try {
066: result = func.call(new Object[] {}, ctx);
067: state = 1;
068: } catch (Throwable t) {
069: throwable = t;
070: state = 2;
071: }
072: synchronized (Env.this ) {
073: Env.this .notifyAll();
074: }
075: }
076: }
077: }
078:
079: class Handle extends PnutsFunction {
080: Env env = new Env();
081:
082: public boolean defined(int nargs) {
083: return nargs == 0;
084: }
085:
086: protected Object exec(Object[] args, Context context) {
087: if (args.length != 0) {
088: undefined(args, context);
089: return null;
090: }
091: try {
092: return env.getResult(context);
093: } catch (InterruptedException e) {
094: throw new PnutsException(e, context);
095: }
096: }
097:
098: public String toString() {
099: return "<asynchronous task for \"" + func.getName()
100: + "\">";
101: }
102: }
103: return new Handle();
104: }
105:
106: public String toString() {
107: return "function async(function ()..., threadpool)";
108: }
109: }
|