001: package gnu.mapping;
002:
003: public class Future extends Thread {
004: Object result;
005: Future parent;
006:
007: public FluidBinding fluidBindings;
008:
009: Environment environment;
010: InPort in;
011: OutPort out;
012: OutPort err;
013: Throwable exception;
014:
015: Procedure action;
016:
017: public Future(Procedure action, Environment environment) {
018: this .action = action;
019: Thread parent_thread = Thread.currentThread();
020: this .environment = environment;
021: }
022:
023: public Future(Procedure action, Environment environment, InPort in,
024: OutPort out, OutPort err) {
025: this .action = action;
026: Thread parent_thread = Thread.currentThread();
027: this .environment = environment;
028: this .in = in;
029: this .out = out;
030: this .err = err;
031: }
032:
033: public Future(Procedure action) {
034: this .action = action;
035: in = InPort.inDefault();
036: out = OutPort.outDefault();
037: err = OutPort.errDefault();
038: Thread parent_thread = Thread.currentThread();
039: Environment parent_env;
040: if (parent_thread instanceof Future) {
041: parent = (Future) parent_thread;
042: parent_env = parent.environment;
043: } else
044: parent_env = Environment.user();
045:
046: environment = parent_env;
047: }
048:
049: public void run() {
050: try {
051: result = action.apply0();
052: } catch (Throwable ex) {
053: exception = ex;
054: }
055: }
056:
057: public Object waitForResult() {
058: try {
059: join();
060: } catch (InterruptedException ex) {
061: throw new RuntimeException(
062: "thread join [force] was interrupted");
063: }
064: if (exception != null) {
065: if (exception instanceof RuntimeException)
066: throw (RuntimeException) exception;
067: throw new RuntimeException(exception.toString());
068: }
069: return result;
070: }
071:
072: public void setFluids(FluidBinding new_fluids) {
073: FluidBinding old_fluids = fluidBindings;
074: FluidBinding fluid = new_fluids;
075: for (; fluid != old_fluids; fluid = fluid.previous) {
076: Binding binding = fluid.binding;
077: Constraint constraint = binding.constraint;
078: if (constraint instanceof FluidConstraint)
079: ((FluidConstraint) constraint).referenceCount++;
080: else
081: binding.constraint = new FluidConstraint(constraint);
082: }
083: fluidBindings = new_fluids;
084: }
085:
086: public void resetFluids(FluidBinding old_fluids) {
087: FluidBinding new_fluids = fluidBindings;
088: FluidBinding fluid = new_fluids;
089: for (; fluid != old_fluids; fluid = fluid.previous) {
090: Binding binding = fluid.binding;
091: FluidConstraint constraint = (FluidConstraint) binding.constraint;
092: if (constraint.referenceCount-- <= 0)
093: binding.constraint = constraint.savedConstraint;
094: }
095: fluidBindings = old_fluids;
096: }
097:
098: public String toString() {
099: StringBuffer buf = new StringBuffer();
100: buf.append("#<future ");
101: buf.append(getName());
102: buf.append(">");
103: return buf.toString();
104: }
105:
106: static Future defaultContext = null;
107:
108: static synchronized void getDefaultContext() {
109: if (defaultContext == null)
110: defaultContext = new Future(null);
111: }
112:
113: /** Get chain of FluidBindings for the current thread (if a Future).
114: * Should fix to work with other threads. */
115:
116: public static FluidBinding getFluids() {
117: Thread thread = Thread.currentThread();
118: /*
119: for (;;)
120: {
121: if (thread instanceof Future)
122: return ((Future)thread).fluidBindings;
123: FluidBinding fl = ....get(thread);
124: if (fl != null)
125: return fl;
126: thread = thread.getParent();
127: }
128: */
129: if (thread instanceof Future)
130: return ((Future) thread).fluidBindings;
131: if (defaultContext == null)
132: getDefaultContext();
133: return defaultContext.fluidBindings;
134: }
135:
136: public static Future getContext() {
137: Thread thread = Thread.currentThread();
138: if (thread instanceof Future)
139: return (Future) thread;
140: if (defaultContext == null)
141: getDefaultContext();
142: return defaultContext;
143: }
144: }
|