001 // Copyright 2006-2008 Waterken Inc. under the terms of the MIT X license
002 // found at http://www.opensource.org/licenses/mit-license.html
003 package org.ref_send.promise;
004
005 import java.io.Serializable;
006 import java.lang.reflect.InvocationHandler;
007 import java.lang.reflect.Method;
008 import java.lang.reflect.Proxy;
009 import java.lang.reflect.Type;
010 import java.lang.reflect.TypeVariable;
011
012 import org.joe_e.Equatable;
013 import org.joe_e.Immutable;
014 import org.joe_e.JoeE;
015 import org.joe_e.Selfless;
016 import org.joe_e.Struct;
017 import org.joe_e.Token;
018 import org.joe_e.array.ConstArray;
019 import org.joe_e.reflect.Proxies;
020 import org.joe_e.reflect.Reflection;
021 import org.ref_send.type.Typedef;
022
023 /**
024 * The eventual operator.
025 * <p>This class decorates an event loop with methods implementing the core
026 * eventual control flow statements needed for defensive programming. The
027 * primary aim of these new control flow statements is preventing plan
028 * interference.</p>
029 * <p>The implementation of a public method can be thought of as a plan in
030 * which an object makes a series of state changes based on a list of
031 * invocation arguments and the object's own current state. As part of
032 * executing this plan, the object may need to notify other objects of the
033 * changes in progress. These other objects may have their own plans to
034 * execute, based on this notification. Plan interference occurs when
035 * execution of these other plans interferes with execution of the original
036 * plan.</p>
037 * <h3>Plan interference</h3>
038 * <p>Interleaving plan execution is vulnerable to many kinds of interference.
039 * Each kind of interference is explained below, using the following example
040 * code:</p>
041 * <pre>
042 * public final class
043 * Account {
044 *
045 * private int balance;
046 * private final ArrayList<Receiver<Integer>> observers;
047 *
048 * Account(final int initial) {
049 * balance = initial;
050 * observers = new ArrayList<Receiver<Integer>>();
051 * }
052 *
053 * public void
054 * observe(final Receiver<Integer> observer) {
055 * if (null == observer) {
056 * throw new NullPointerException();
057 * }
058 * observers.add(observer);
059 * }
060 *
061 * public int
062 * getBalance() { return balance; }
063 *
064 * public void
065 * setBalance(final int newBalance) {
066 * balance = newBalance;
067 * for (final Receiver<Integer> observer : observers) {
068 * observer.apply(newBalance);
069 * }
070 * }
071 * }
072 * </pre>
073 * <h4>Unanticipated termination</h4>
074 * <p>A method can terminate execution of its plan by throwing an exception.
075 * The plan may be terminated because it would violate one of the object's
076 * invariants or because the request is malformed. Unfortunately, throwing an
077 * exception may terminate not just the current plan, but also any other
078 * currently executing plans. For example, if one of the observers throws a
079 * {@link RuntimeException} from its {@code apply()} implementation, the
080 * remaining observers are not notified of the new account balance. These other
081 * observers may then continue operating using stale data about the account
082 * balance.</p>
083 * <h4>Nested execution</h4>
084 * <p>When a method implementation invokes a method on another object, it
085 * temporarily suspends progress on its own plan to let the called method
086 * execute its plan. When the called method returns, the calling method
087 * resumes its own plan where it left off. Unfortunately, the called method
088 * may have changed the application state in such a way that resuming the
089 * original plan no longer makes sense. For example, if one of the observers
090 * invokes {@code setBalance()} in its {@code apply()} implementation,
091 * the remaining observers will first be notified of the balance after the
092 * update, and then be notified of the balance before the update. Again, these
093 * other observers may then continue operating using stale data about the
094 * account balance.</p>
095 * <h4>Interrupted transition</h4>
096 * <p>A called method may also initiate an unanticipated state transition in
097 * the calling object, while the current transition is still incomplete. For
098 * example, in the default state, an {@code Account} is always ready to accept a
099 * new observer; however, this constraint is temporarily not met when the
100 * observer list is being iterated over. An observer could catch the
101 * {@code Account} in this transitional state by invoking {@code observe()} in
102 * its {@code apply()} implementation. As a result, a
103 * {@link java.util.ConcurrentModificationException} will be thrown when
104 * iteration over the observer list resumes. Again, this exception prevents
105 * notification of the remaining observers.</p>
106 * <h3>Plan isolation</h3>
107 * <p>The above plan interference problems are only possible because execution
108 * of one plan is interleaved with execution of another. Interleaving plan
109 * execution can be prevented by scheduling other plans for future execution,
110 * instead of allowing them to preempt execution of the current plan. This
111 * class provides control flow statements for scheduling future execution and
112 * receiving its results.</p>
113 * <h3>Naming convention</h3>
114 * <p>Since the control flow statements defined by this class schedule future
115 * execution, instead of immediate execution, they behave differently from the
116 * native control flow constructs in the Java language. To make the difference
117 * between eventual and immediate execution readily recognized by programmers
118 * when scanning code, some naming conventions are proposed. By convention, an
119 * instance of {@link Eventual} is held in a variable named "{@code _}".
120 * Additional ways of marking eventual operations with the '{@code _}' character
121 * are specified in the documentation for the methods defined by this class. All
122 * of these conventions make eventual control flow statements distinguishable by
123 * the character sequence "{@code _.}". Example uses are also shown in the
124 * method documentation for this class. The '{@code _}' character should only be
125 * used to identify eventual operations so that a programmer can readily
126 * identify operations that are expected to be eventual by looking for the
127 * <b>{@code _.}</b> pseudo-operator.</p>
128 * @see <a href="http://www.erights.org/talks/thesis/">Section 13.1
129 * "Sequential Interleaving Hazards" of "Robust Composition: Towards a
130 * Unified Approach to Access Control and Concurrency Control"</a>
131 */
132 public class
133 Eventual implements Selfless, Serializable {
134 static private final long serialVersionUID = 1L;
135
136 /**
137 * trusted promise permission
138 */
139 private final Token local;
140
141 /**
142 * raw event loop
143 */
144 protected final Receiver<Promise<?>> enqueue;
145
146 /**
147 * URI for the event loop
148 */
149 protected final String here;
150
151 /**
152 * debugging output
153 */
154 public final Log log;
155
156 /**
157 * destruct the vat
158 * <p>
159 * call like: {@code destruct.apply(null)}
160 * </p>
161 */
162 public final Receiver<?> destruct;
163
164 /**
165 * mutable statistics about eventual operations
166 */
167 protected final Fulfilled<Stats> stats;
168
169 /**
170 * Constructs an instance.
171 * @param enqueue raw event loop
172 * @param here URI for the event loop
173 * @param log {@link #log}
174 * @param destruct {@link #destruct}
175 */
176 public
177 Eventual(final Receiver<Promise<?>> enqueue, final String here,
178 final Log log, final Receiver<?> destruct) {
179 this.local = new Token();
180 this.enqueue = enqueue;
181 this.here = here;
182 this.log = log;
183 this.destruct = destruct;
184 this.stats = new Fulfilled<Stats>(false, new Stats());
185 }
186
187 /**
188 * Constructs an instance.
189 * @param enqueue raw event loop
190 */
191 public
192 Eventual(final Receiver<Promise<?>> enqueue) {
193 this(enqueue, "", new Log(),
194 cast(Receiver.class, new Rejected<Receiver<?>>(null)));
195 }
196
197 // org.joe_e.Selfless interface
198
199 public int
200 hashCode() { return 0x1A7E4D0D; }
201
202 public boolean
203 equals(final Object x) {
204 return x instanceof Eventual && local == ((Eventual)x).local;
205 }
206
207 // org.ref_send.promise.Eventual interface
208
209 /**
210 * Does an eventual conditional operation on a promise.
211 * <p>
212 * The {@code conditional} code block will be notified of the
213 * {@code promise}'s state at most once, in a future event loop turn. If
214 * there is no referent, the {@code conditional}'s {@link Do#reject reject}
215 * method will be called with the reason; otherwise, the
216 * {@link Do#fulfill fulfill} method will be called with either an immediate
217 * reference for a local referent, or an {@linkplain #_ eventual reference}
218 * for a remote referent. For example:
219 * </p>
220 * <pre>
221 * import static org.ref_send.promise.Eventual.ref;
222 * …
223 * final Promise<Account> mine = …
224 * final Promise<Integer> balance =
225 * _.when(mine, new Do<Account,Promise<Integer>>() {
226 * public Promise<Integer>
227 * fulfill(final Account x) { return ref(x.getBalance()); }
228 * });
229 * </pre>
230 * <p>
231 * A {@code null} {@code promise} argument is treated like a rejected
232 * promise with a reason of {@link NullPointerException}.
233 * </p>
234 * <p>
235 * The {@code conditional} in successive calls to this method with the same
236 * {@code promise} will be notified in the same order as the calls were
237 * made.
238 * </p>
239 * <p>
240 * This method will not throw an {@link Exception}. Neither the
241 * {@code promise}, nor the {@code conditional}, argument will be given the
242 * opportunity to execute in the current event loop turn.
243 * </p>
244 * @param <P> parameter type
245 * @param <R> return type
246 * @param promise observed promise
247 * @param conditional conditional code block, MUST NOT be {@code null}
248 * @return promise, or {@linkplain #_ eventual reference}, for the
249 * {@code conditional}'s return, or {@code null} if the
250 * {@code conditional}'s return type is {@code Void}
251 */
252 public final <P,R> R
253 when(final Promise<P> promise, final Do<P,R> conditional) {
254 try {
255 final Class<?> R= Typedef.raw(returnType(Object.class,conditional));
256 return cast(R, when(null, R, promise, conditional));
257 } catch (final Exception e) { throw new Error(e); }
258 }
259
260 /**
261 * Does an eventual conditional operation on an
262 * {@linkplain #_ eventual reference}.
263 * <p>
264 * The implementation behavior is the same as that documented for the
265 * promise based {@link #when(Promise, Do) when} statement.
266 * </p>
267 * @param <P> parameter type
268 * @param <R> return type
269 * @param reference observed reference
270 * @param conditional conditional code block, MUST NOT be {@code null}
271 * @return promise, or {@linkplain #_ eventual reference}, for the
272 * {@code conditional}'s return, or {@code null} if the
273 * {@code conditional}'s return type is {@code Void}
274 */
275 public final <P,R> R
276 when(final P reference, final Do<P,R> conditional) {
277 try {
278 final Class<?> P = null!=reference?reference.getClass():Void.class;
279 final Class<?> R = Typedef.raw(returnType(P, conditional));
280 return cast(R, when(P, R, ref(reference), conditional));
281 } catch (final Exception e) { throw new Error(e); }
282 }
283
284 protected final <P,R> Promise<R>
285 when(final Class<?> P, final Class<?> R, final Promise<? extends P> promise,
286 final Do<? super P, ? extends R> conditional) {
287 final Promise<R> r;
288 final Do<? super P,?> forwarder;
289 if (void.class == R || Void.class == R) {
290 r = null;
291 forwarder = conditional;
292 } else {
293 final Deferred<R> x = defer();
294 r = x.promise;
295 forwarder = new Compose<P,R>(conditional, x.resolver);
296 }
297 trust(promise).when(P, forwarder);
298 return r;
299 }
300
301 /**
302 * Determines a block's return type.
303 * @param P block's parameter type
304 * @param block block to introspect on
305 * @return {@code block}'s return type
306 */
307 static private Type
308 returnType(final Type P, final Do<?,?> block) {
309 return block instanceof Invoke ?
310 Typedef.bound(((Invoke<?>)block).method.getGenericReturnType(), P) :
311 Typedef.value(DoR, block.getClass());
312 }
313
314 /**
315 * {@link Do} block return type
316 */
317 static private final TypeVariable<?> DoR = Typedef.var(Do.class, "R");
318
319 /**
320 * A reified method invocation.
321 * @param <T> target object type
322 */
323 static protected final class
324 Invoke<T> extends Do<T,Object> implements Serializable {
325 static private final long serialVersionUID = 1L;
326
327 /**
328 * method to invoke
329 */
330 public final Method method;
331
332 /**
333 * invocation arguments, or {@code null} if none
334 */
335 public final ConstArray<?> argv;
336
337 /**
338 * Constructs a pending invocation.
339 * @param method {@link #method}
340 * @param argv {@link #argv}
341 */
342 public
343 Invoke(final Method method, final ConstArray<?> argv) {
344 this.method = method;
345 this.argv = argv;
346 }
347
348 public Object
349 fulfill(final T object) throws Exception {
350 // AUDIT: call to untrusted application code
351 return Reflection.invoke(method, object,
352 null == argv ? null : argv.toArray(new Object[argv.length()]));
353 }
354 }
355
356 /**
357 * A combined {@link Do} block and return value {@link Resolver}.
358 * @param <P> parameter type
359 * @param <R> return type
360 */
361 static protected final class
362 Compose<P,R> extends Do<P,Void> implements Serializable {
363 static private final long serialVersionUID = 1L;
364
365 /**
366 * conditional code block to execute
367 */
368 public final Do<? super P,? extends R> conditional;
369
370 /**
371 * return value resolver
372 */
373 public final Resolver<R> resolver;
374
375 /**
376 * Constructs an instance.
377 * @param conditional {@link #conditional}
378 * @param resolver {@link #resolver}
379 */
380 public
381 Compose(final Do<? super P, ? extends R> conditional,
382 final Resolver<R> resolver) {
383 this.conditional = conditional;
384 this.resolver = resolver;
385 }
386
387 // org.ref_send.promise.Do interface
388
389 public Void
390 fulfill(final P a) {
391 final R r;
392 try {
393 r = conditional.fulfill(a);
394 } catch (final Exception e) {
395 resolver.reject(e);
396 return null;
397 }
398 resolver.apply(r);
399 return null;
400 }
401
402 public Void
403 reject(final Exception reason) {
404 final R r;
405 try {
406 r = conditional.reject(reason);
407 } catch (final Exception e) {
408 resolver.reject(e);
409 return null;
410 }
411 resolver.apply(r);
412 return null;
413 }
414 }
415
416 private final <T> Local<T>
417 trust(final Promise<T> untrusted) {
418 return trusted(untrusted) ?
419 (Local<T>)untrusted : new Enqueue<T>(untrusted);
420 }
421
422 protected final boolean
423 trusted(final Object untrusted) {
424 return untrusted instanceof Local &&
425 local == ((Local<?>)untrusted).getScope().local;
426 }
427
428 /**
429 * An abstract base class for a promise implementation that is scoped to a
430 * particular event queue.
431 * @param <T> referent type
432 */
433 protected abstract class
434 Local<T> implements Promise<T>, InvocationHandler, Selfless, Serializable {
435 static private final long serialVersionUID = 1L;
436
437 protected final Eventual
438 getScope() { return Eventual.this; }
439
440 // org.joe_e.Selfless interface
441
442 public abstract boolean
443 equals(Object x);
444
445 public abstract int
446 hashCode();
447
448 // java.lang.reflect.InvocationHandler interface
449
450 /**
451 * Forwards a Java language invocation.
452 * @param proxy eventual reference
453 * @param method method to invoke
454 * @param args each invocation argument
455 * @return eventual reference for the invocation return
456 */
457 public final Object
458 invoke(final Object proxy, final Method method,
459 final Object[] args) throws Exception {
460 if (Object.class == method.getDeclaringClass()) {
461 if ("equals".equals(method.getName())) {
462 return args[0] instanceof Proxy &&
463 proxy.getClass() == args[0].getClass() &&
464 equals(Proxies.getHandler((Proxy)args[0]));
465 } else {
466 return Reflection.invoke(method, this, args);
467 }
468 }
469 try {
470 final Class<?> T = proxy.getClass();
471 final Class<?> R =
472 Typedef.raw(Typedef.bound(method.getGenericReturnType(),T));
473 final Tail<?> r =
474 (Tail<?>)Eventual.this.when(T, R, this, new Invoke<T>(
475 method, null == args ? null : ConstArray.array(args)));
476 if (null == r) { return null; }
477
478 // implementation might have already resolved a pipeline promise
479 final State<?> cell = near(r.state);
480 return cast(R, cell.resolved ? cell.value : r);
481 } catch (final Exception e) { throw new Error(e); }
482 }
483
484 // org.ref_send.promise.Promise interface
485
486 public abstract T
487 call() throws Exception;
488
489 // org.ref_send.promise.Local interface
490
491 /**
492 * Shortens the promise chain by one link.
493 */
494 public abstract Object
495 shorten() throws Unresolved;
496
497 /**
498 * Notifies an observer in a future event loop turn.
499 * @param T concrete referent type, {@code null} if not known
500 * @param observer promise observer
501 */
502 public abstract void
503 when(Class<?> T, Do<? super T,?> observer);
504 }
505
506 private final class
507 Enqueue<T> extends Local<T> {
508 static private final long serialVersionUID = 1L;
509
510 final Promise<T> untrusted;
511
512 Enqueue(final Promise<T> untrusted) {
513 this.untrusted = untrusted;
514 }
515
516 public int
517 hashCode() { return 0x174057ED; }
518
519 public boolean
520 equals(final Object x) {
521 return x instanceof Enqueue &&
522 Eventual.this.equals(((Enqueue<?>)x).getScope()) &&
523 (null != untrusted ?
524 untrusted.equals(((Enqueue<?>)x).untrusted) :
525 null == ((Enqueue<?>)x).untrusted);
526 }
527
528 public T
529 call() throws Exception { return untrusted.call(); }
530
531 public Object
532 shorten() { return this; }
533
534 public void
535 when(final Class<?> T, final Do<? super T, ?> observer) {
536 final long id = near(stats).newTask();
537 class Sample extends Struct implements Promise<Void>, Serializable {
538 static private final long serialVersionUID = 1L;
539
540 public Void
541 call() throws Exception {
542 // AUDIT: call to untrusted application code
543 try {
544 sample(untrusted, observer, log, here + "#t" + id);
545 } catch (final Exception e) {
546 log.problem(e);
547 throw e;
548 }
549 return null;
550 }
551 }
552 enqueue.apply(new Sample());
553 log.sent(here + "#t" + id);
554 }
555 }
556
557 static private final Method fulfill;
558 static {
559 try {
560 fulfill = Reflection.method(Do.class, "fulfill", Object.class);
561 } catch (final NoSuchMethodException e) {throw new NoSuchMethodError();}
562 }
563
564 static private final Method reject;
565 static {
566 try {
567 reject = Reflection.method(Do.class, "reject", Exception.class);
568 } catch (final NoSuchMethodException e) {throw new NoSuchMethodError();}
569 }
570
571 /**
572 * A recognizable exception to avoid logging an ignored null resolution.
573 */
574 static private final NullPointerException VOID = new NullPointerException();
575
576 static protected <P,R> R
577 sample(final Promise<? extends P> promise,
578 final Do<? super P, ? extends R> observer,
579 final Log log, final String message) throws Exception {
580 final P a;
581 try {
582 if (null == promise) { throw VOID; }
583 a = promise.call();
584
585 // ensure the called value is not one that is
586 // expected to be handled as a rejection
587 if (null == a) { throw VOID; }
588 final Promise<?> p = ref(a);
589 if (p instanceof Rejected) { p.call(); }
590 } catch (final Exception reason) {
591 final @SuppressWarnings({ "rawtypes", "unchecked" }) Class<?> c =
592 (observer instanceof Compose ? ((Compose)observer).conditional :
593 observer).getClass();
594 log.got(message, c, reject);
595 try {
596 return observer.reject(reason);
597 } catch (final NullPointerException shadow) {
598 if (VOID.equals(shadow)) { return null; }
599 throw shadow;
600 }
601 }
602 final Method m;
603 final Class<?> c; {
604 final @SuppressWarnings({ "rawtypes", "unchecked" }) Do inner =
605 observer instanceof Compose ?
606 ((Compose)observer).conditional : observer;
607 if (inner instanceof Invoke) {
608 m = ((Invoke<?>)inner).method;
609 c = a.getClass();
610 } else {
611 m = fulfill;
612 c = inner.getClass();
613 }
614 }
615 log.got(message, c, m);
616 return observer.fulfill(a);
617 }
618
619 /**
620 * A registered promise observer.
621 * @param <T> referent type
622 */
623 static protected final class
624 When<T> implements Equatable, Serializable {
625 static private final long serialVersionUID = 1L;
626
627 long condition; // id for the corresponding promise
628 long message; // id for this when block
629 Do<? super T,?> observer; // client's when block code
630 Promise<When<T>> next; // next when block registered on the promise
631 }
632
633 /**
634 * Executes the next Do block registered on the promise.
635 */
636 private final class
637 Forward<T> extends Struct implements Promise<Void>, Serializable {
638 static private final long serialVersionUID = 1L;
639
640 private final boolean ignored; // value ignored so far?
641 private final long condition; // corresponding promise id
642 private final Promise<When<T>> pending; // when block to run
643 private final Class<?> T; // referent type of promise
644 private final Promise<? extends T> value; // resolved value of promise
645
646 Forward(final boolean ignored,
647 final long condition, final Promise<When<T>> pending,
648 final Class<?> T, final Promise<? extends T> value) {
649 this.ignored = ignored;
650 this.condition = condition;
651 this.pending = pending;
652 this.T = T;
653 this.value = value;
654 }
655
656 public Void
657 call() throws Exception {
658 final long message;
659 final Do<? super T,?> observer;
660 final Promise<When<T>> next; {
661 final When<T> block;
662 try {
663 block = pending.call();
664 } catch (final Exception e) {
665 /*
666 * There was a problem loading the saved when block. Ignore
667 * it and all subsequent when blocks on this promise.
668 */
669 log.problem(e);
670 throw e;
671 }
672 if (condition != block.condition) { return null; } // been done
673
674 // free the block, thus ensuring it is not run again
675 message = block.message;
676 observer = block.observer;
677 next = block.next;
678 near(stats).freeWhen(pending, block);
679 }
680
681 if (null != next) {
682 enqueue.apply(new Forward<T>(false, condition, next, T, value));
683 try {
684 if (trusted(value)) {
685 log.got(here + "#w" + message, null, null);
686 final @SuppressWarnings("unchecked") Local<? extends T>
687 promise = (Local<? extends T>)value;
688 promise.when(T, observer);
689 } else {
690 // AUDIT: call to untrusted application code
691 sample(value, observer, log, here + "#w" + message);
692 }
693 } catch (final Exception e) {
694 log.problem(e);
695 throw e;
696 }
697 } else if (ignored && value instanceof Rejected) {
698 /*
699 * No when block has been queued on this promise, so this
700 * rejection will go unnoticed by the application code. To make
701 * the exception show up in the log, create a dummy when block
702 * to log the problem. This dummy when block has the unusual
703 * nature of being a message that is received before it is sent.
704 */
705 final Exception e = ((Rejected<?>)value).reason;
706 log.got(here + "#w" + message, null, null);
707 log.sentIf(false, here+"#w"+message, here+"#p"+condition);
708 log.problem(e);
709 throw e;
710 }
711 return null;
712 }
713 }
714
715 private final class
716 State<T> implements Serializable {
717 static private final long serialVersionUID = 1L;
718
719 final long condition; // id of this promise
720 Promise<When<T>> back; // observer list sentinel
721
722 boolean resolved; // Is resolved?
723 Class<?> T; // concrete referent type
724 Promise<? extends T> value; // resolved value
725
726 State(final long condition, final Promise<When<T>> back) {
727 this.condition = condition;
728 this.back = back;
729 }
730
731 protected void
732 observe(final Do<? super T,?> observer) {
733 final boolean call = observer instanceof Compose &&
734 ((Compose<?,?>)observer).conditional instanceof Invoke;
735 final When<T> block = near(back);
736 if (condition == block.condition) {
737 log.sentIf(call, here+"#w"+block.message, here+"#p"+condition);
738 block.observer = observer;
739 back = block.next = near(stats).allocWhen(condition);
740 } else {
741 /*
742 * Promise is already resolved and all previously registered
743 * observers run. Register the observer on the resolved value,
744 * but using a separate turn so that we don't lose the causality
745 * chain from this promise to the resolved value.
746 */
747 final long task = near(stats).newTask();
748 class Fwd extends Struct implements Promise<Void>, Serializable{
749 static private final long serialVersionUID = 1L;
750
751 public Void
752 call() {
753 log.got(here + "#t" + task, null, null);
754 when(T, Void.class, value, observer);
755 return null;
756 }
757 }
758 enqueue.apply(new Fwd());
759 log.sentIf(call, here + "#t" + task, here + "#p" + condition);
760 }
761 }
762 }
763
764 private final class
765 Tail<T> extends Local<T> {
766 static private final long serialVersionUID = 1L;
767
768 final Promise<State<T>> state; // promise's mutable state
769
770 Tail(final State<T> state) {
771 this.state = new Fulfilled<State<T>>(false, state);
772 }
773
774 public int
775 hashCode() { return 0x3EFF7A11; }
776
777 public boolean
778 equals(final Object x) {
779 return x instanceof Tail && state.equals(((Tail<?>)x).state);
780 }
781
782 public T
783 call() throws Exception {
784 final State<T> cell = state.call();
785 if (!cell.resolved) { throw new Unresolved(); }
786 return cell.value.call();
787 }
788
789 public Object
790 shorten() throws Unresolved {
791 final State<T> cell = near(state);
792 if (!cell.resolved) { throw new Unresolved(); }
793 if (cell.value instanceof Inline) {
794 return ((Inline<?>)cell.value).call();
795 }
796 return cell.value;
797 }
798
799 public void
800 when(final Class<?> T, final Do<? super T,?> observer) {
801 near(state).observe(observer);
802 }
803 }
804
805 private final class
806 Head<T> extends Struct implements Resolver<T>, Serializable {
807 static private final long serialVersionUID = 1L;
808
809 private final long condition; // id of corresponding promise
810 private final Promise<State<T>> state; // promise's mutable state
811 private final Promise<When<T>> front; // first when block to run
812
813 Head(final long condition, final State<T> state,
814 final Promise<When<T>> front) {
815 this.condition = condition;
816 this.state = new Fulfilled<State<T>>(true, state);
817 this.front = front;
818
819 /*
820 * The resolver only holds a weak reference to the promise's mutable
821 * state, allowing it to be garbage collected even if the resolver
822 * is still held. This implementation takes advantage of a common
823 * pattern in which a when block is registered on a promise as soon
824 * as it is created, but no other reference to the promise is
825 * retained. Combined with the recycling of when blocks, this common
826 * pattern generates no dead objects. Much of the implementation's
827 * complexity is in service to this goal.
828 */
829 }
830
831 public void
832 progress() { log.progressed(here + "#p" + condition); }
833
834 public void
835 reject(final Exception reason) { set(null, new Rejected<T>(reason)); }
836
837 public void
838 resolve(final Promise<? extends T> p) { set(null, p); }
839
840 public void
841 apply(final T r) {
842 set(null==r || r instanceof Promise ? null : r.getClass(), ref(r));
843 }
844
845 private void
846 set(final Class<?> T, Promise<? extends T> p) {
847 if (p instanceof Fulfilled) {
848 final @SuppressWarnings("unchecked") Fulfilled<? extends T>
849 fulfilled = (Fulfilled<? extends T>)p;
850 p = fulfilled.getState();
851 log.fulfilled(here + "#p" + condition);
852 } else if (p instanceof Rejected) {
853 final @SuppressWarnings("unchecked") Rejected<? extends T>
854 rejected = (Rejected<? extends T>)p;
855 log.rejected(here + "#p" + condition, rejected.reason);
856 } else {
857 log.resolved(here + "#p" + condition);
858 }
859 try {
860 final State<T> cell = state.call();
861 if (null != cell) {
862 if (cell.resolved) { return; }
863 cell.resolved = true;
864 cell.T = T;
865 cell.value = p;
866 }
867 } catch (final Exception e) { log.problem(e); }
868 enqueue.apply(new Forward<T>(true, condition, front, T, p));
869 }
870 }
871
872 /**
873 * Creates a promise in the unresolved state.
874 * <p>
875 * The return from this method is a ( {@linkplain Promise promise},
876 * {@linkplain Resolver resolver} ) pair. The promise is initially in the
877 * unresolved state and can only be resolved by the resolver once. If the
878 * promise is {@linkplain Resolver#apply fulfilled}, the promise will
879 * forever refer to the provided referent. If the promise, is
880 * {@linkplain Resolver#reject rejected}, the promise will forever be in the
881 * rejected state, with the provided reason. If the promise is
882 * {@linkplain Resolver#resolve resolved}, the promise will forever be in
883 * the same state as the provided promise. After this initial state
884 * transition, all subsequent invocations of either {@link Resolver#apply
885 * fulfill}, {@link Resolver#reject reject} or {@link Resolver#resolve
886 * resolve} are silently ignored. Any {@linkplain Do observer}
887 * {@linkplain #when registered} on the promise will only be notified after
888 * the promise is either fulfilled or rejected.
889 * </p>
890 * @param <T> referent type
891 * @return ( {@linkplain Promise promise}, {@linkplain Resolver resolver} )
892 */
893 public final <T> Deferred<T>
894 defer() {
895 final long condition = near(stats).newDeferral();
896 final Promise<When<T>> front = near(stats).allocWhen(condition);
897 final State<T> state = new State<T>(condition, front);
898 return new Deferred<T>(new Tail<T>(state),
899 new Head<T>(condition, state, front));
900 }
901
902 /**
903 * Ensures a reference is an eventual reference.
904 * <p>
905 * An eventual reference queues invocations, instead of processing them
906 * immediately. Each queued invocation will be processed, in order, in a
907 * future event loop turn.
908 * </p>
909 * <p>
910 * Use this method to vet received arguments. For example:
911 * </p>
912 * <pre>
913 * import static org.joe_e.ConstArray.array;
914 *
915 * public final class
916 * Account {
917 *
918 * private final Eventual _;
919 * private int balance;
920 * private ConstArray<Receiver<Integer>> observer_s;
921 *
922 * public
923 * Account(final Eventual _, final int initial) {
924 * this._ = _;
925 * balance = initial;
926 * observer_s = array();
927 * }
928 *
929 * public void
930 * observe(final Receiver<Integer> observer) {
931 * // Vet the received arguments.
932 * final Receiver<Integer> observer_ = _.<b>_</b>(observer);
933 *
934 * // Use the <em>vetted</em> arguments.
935 * observer_s = observer_s.with(observer_);
936 * }
937 *
938 * public int
939 * getBalance() { return balance; }
940 *
941 * public void
942 * setBalance(final int newBalance) {
943 * balance = newBalance;
944 * for (final Receiver<Integer> observer_ : observer_s) {
945 * // Schedule future execution of notification.
946 * observer_.apply(newBalance);
947 * }
948 * }
949 * }
950 * </pre>
951 * <p>
952 * By convention, the return from this method is held in a variable whose
953 * name is suffixed with an '{@code _}' character. The main part of the
954 * variable name should use Java's camelCaseConvention. A list of eventual
955 * references is suffixed with "{@code _s}". This naming convention
956 * creates the appearance of a new operator in the Java language, the
957 * eventual operator: "<b>{@code _.}</b>".
958 * </p>
959 * <p>
960 * If this method returns successfully, the returned eventual reference
961 * will not throw an {@link Exception} on invocation of any of the methods
962 * defined by its type, provided the invoked method's return type is either
963 * {@code void}, an {@linkplain Proxies#isImplementable allowed} proxy
964 * type or assignable from {@link Promise}. Invocations on the eventual
965 * reference will not give the {@code referent}, nor any of the invocation
966 * arguments, an opportunity to execute in the current event loop turn.
967 * </p>
968 * <p>
969 * Invocations of methods defined by {@link Object} are <strong>not</strong>
970 * queued, and so can cause plan interference, or throw an exception.
971 * </p>
972 * @param <T> referent type, MUST be an
973 * {@linkplain Proxies#isImplementable allowed} proxy type
974 * @param referent immediate or eventual reference,
975 * MUST be non-{@code null}
976 * @return corresponding eventual reference
977 * @throws NullPointerException {@code null} {@code referent}
978 * @throws ClassCastException {@code T} not an
979 * {@linkplain Proxies#isImplementable allowed} proxy type
980 */
981 public final <T> T
982 _(final T referent) {
983 if (referent instanceof Proxy) {
984 final Object handler = Proxies.getHandler((Proxy)referent);
985 if ((null != handler && Rejected.class == handler.getClass()) ||
986 trusted(handler)) { return referent; }
987 }
988 final @SuppressWarnings("unchecked") T proxy =
989 (T)Proxies.proxy(new Enqueue<T>(ref(referent)),
990 virtualize(referent.getClass(), Selfless.class));
991 return proxy;
992 }
993
994 /**
995 * Lists the part of an interface that a proxy can implement.
996 * @param r types to mimic
997 */
998 static protected Class<?>[]
999 virtualize(Class<?>... r) {
1000 for (int i = r.length; i-- != 0;) {
1001 final Class<?> type = r[i];
1002 if (type == Serializable.class || !Proxies.isImplementable(type) ||
1003 JoeE.isSubtypeOf(type, Immutable.class) ||
1004 JoeE.isSubtypeOf(type, Equatable.class)) {
1005 // remove the type from the proxy type list
1006 {
1007 final Class<?>[] c = r;
1008 r = new Class<?>[c.length - 1];
1009 System.arraycopy(c, 0, r, 0, i);
1010 System.arraycopy(c, i + 1, r, i, r.length - i);
1011 }
1012
1013 // search the inheritance tree for types that can be implemented
1014 for (Class<?> p = type; null != p; p = p.getSuperclass()) {
1015 Class<?>[] x = virtualize(p.getInterfaces());
1016
1017 // remove any duplicate types from the replacement type list
1018 for (int j = x.length; 0 != j--;) {
1019 for (int k = r.length; 0 != k--;) {
1020 if (x[j] == r[k]) {
1021 final Class<?>[] c = x;
1022 x = new Class<?>[c.length - 1];
1023 System.arraycopy(c, 0, x, 0, j);
1024 System.arraycopy(c, j + 1, x, j, x.length - j);
1025 break;
1026 }
1027 }
1028 }
1029
1030 // splice in the replacement type list
1031 final Class<?>[] c = r;
1032 r = new Class<?>[c.length + x.length];
1033 System.arraycopy(c, 0, r, 0, i);
1034 System.arraycopy(x, 0, r, i, x.length);
1035 System.arraycopy(c, i, r, i + x.length, c.length - i);
1036 }
1037 }
1038 }
1039 return r;
1040 }
1041
1042 /**
1043 * Causes a compile error for code that attempts to create an
1044 * {@linkplain #_ eventual reference} of a concrete type.
1045 * <p>
1046 * If you encounter a compile error because your code is linking to this
1047 * method, insert an explicit cast to the
1048 * {@linkplain Proxies#isImplementable allowed} proxy type. For example,
1049 * </p>
1050 * <kbd>_._(this).apply(null);</kbd>
1051 * <p>becomes:</p>
1052 * <kbd>_._((Receiver<?>)this).apply(null);</kbd>
1053 * @param x ignored
1054 * @throws AssertionError always thrown
1055 */
1056 public final <T extends Serializable> void
1057 _(final T x) { throw new AssertionError(); }
1058
1059 /**
1060 * Casts a promise to a specified type.
1061 * <p>
1062 * For example,
1063 * </p>
1064 * <pre>
1065 * final Channel<Receiver<Integer>> x = _.defer();
1066 * final Receiver<Integer> r_ = cast(Receiver.class, x.promise);
1067 * </pre>
1068 * @param <T> referent type to implement
1069 * @param type referent type to implement
1070 * @param promise promise for the referent
1071 * @return reference of corresponding type
1072 * @throws ClassCastException no cast to {@code type}
1073 */
1074 static public @SuppressWarnings("unchecked") <T> T
1075 cast(final Class<?> type,final Promise<T> promise)throws ClassCastException{
1076 return (T)(Void.class == type || void.class == type ?
1077 null :
1078 Promise.class == type ?
1079 promise :
1080 promise instanceof Fulfilled ?
1081 near(promise) :
1082 type.isInstance(promise) ?
1083 promise :
1084 float.class == type ?
1085 Float.NaN :
1086 double.class == type ?
1087 Double.NaN :
1088 null == promise ?
1089 null :
1090 Float.class == type ?
1091 Float.NaN :
1092 Double.class == type ?
1093 Double.NaN :
1094 Selfless.class == type ?
1095 Proxies.proxy((InvocationHandler)promise, Selfless.class) :
1096 Proxies.proxy((InvocationHandler)promise, type, Selfless.class));
1097 }
1098
1099 /**
1100 * Gets a corresponding {@linkplain Promise promise}.
1101 * <p>
1102 * This method is the inverse of {@link #cast cast}; it gets the
1103 * corresponding {@linkplain Promise promise} for a given reference.
1104 * </p>
1105 * <p>
1106 * This method will not throw an {@link Exception}.
1107 * </p>
1108 * @param <T> referent type
1109 * @param referent immediate or eventual reference
1110 */
1111 static public @SuppressWarnings("unchecked") <T> Promise<T>
1112 ref(final T referent) {
1113 if (null == referent) { return null; }
1114 if (referent instanceof Promise) { return (Promise<T>)referent; }
1115 if (referent instanceof Proxy) {
1116 try {
1117 final Object handler = Proxies.getHandler((Proxy)referent);
1118 if (handler instanceof Promise) {
1119 return handler instanceof Enqueue
1120 ? ((Enqueue<T>)handler).untrusted : (Promise<T>)handler;
1121 }
1122 } catch (final Exception e) { /* treat as normal reference */ }
1123 }
1124 try {
1125 if (referent instanceof Double) {
1126 final Double d = (Double)referent;
1127 if (d.isNaN()) { throw new ArithmeticException(); }
1128 if (d.isInfinite()) { throw new ArithmeticException(); }
1129 } else if (referent instanceof Float) {
1130 final Float f = (Float)referent;
1131 if (f.isNaN()) { throw new ArithmeticException(); }
1132 if (f.isInfinite()) { throw new ArithmeticException(); }
1133 }
1134 return new Fulfilled<T>(false, referent);
1135 } catch (final Exception e) {
1136 return reject(e);
1137 }
1138 }
1139
1140 /**
1141 * Gets a corresponding immediate reference.
1142 * <p>
1143 * This method should only be used when the application knows the provided
1144 * reference refers to a local object. Any other condition is treated as a
1145 * fatal error. Use the {@link Promise#call call} method to check the status
1146 * of a promise.
1147 * </p>
1148 * <p>
1149 * This method will not throw an {@link Exception}.
1150 * </p>
1151 * @param <T> referent type
1152 * @param reference possibly eventual reference for a local referent
1153 * @return corresponding immediate reference
1154 */
1155 static public <T> T
1156 near(final T reference) { return near(ref(reference)); }
1157
1158 /**
1159 * Gets a corresponding immediate reference.
1160 * <p>
1161 * This method should only be used when the application knows the provided
1162 * promise refers to a local object. Any other condition is treated as a
1163 * fatal error. Use the {@link Promise#call call} method to check the status
1164 * of a promise.
1165 * </p>
1166 * <p>
1167 * This method will not throw an {@link Exception}.
1168 * </p>
1169 * @param <T> referent type
1170 * @param promise a promise
1171 * @return {@linkplain #cast corresponding} reference
1172 */
1173 static public <T> T
1174 near(final Promise<T> promise) {
1175 try {
1176 return promise.call();
1177 } catch (final Exception e) { throw new Error(e); }
1178 }
1179
1180 /**
1181 * Constructs a rejected {@linkplain Promise promise}.
1182 * @param <T> referent type
1183 * @param reason rejection reason
1184 */
1185 static public <T> Promise<T>
1186 reject(final Exception reason) { return new Rejected<T>(reason); }
1187
1188 /**
1189 * Creates a sub-vat.
1190 * <p>
1191 * All created vats will be destructed when this vat is
1192 * {@linkplain Vat#destruct destructed}.
1193 * </p>
1194 * <p>
1195 * The {@code maker} MUST be a {@code public}
1196 * {@linkplain org.joe_e.IsJoeE Joe-E} class with a method of signature:
1197 * </p>
1198 * <pre>
1199 * static public R
1200 * make({@link Eventual} _, …)
1201 * </pre>
1202 * <p>
1203 * The ellipsis means the method can have any number of additional
1204 * arguments. The {@link Eventual} parameter, if present, MUST be the first
1205 * parameter.
1206 * </p>
1207 * <p>
1208 * This method will not throw an {@link Exception}. None of the arguments
1209 * will be given the opportunity to execute in the current event loop turn.
1210 * </p>
1211 * @param <R> return type, MUST be either an interface, or a {@link Promise}
1212 * @param label optional vat label,
1213 * if {@code null} a label will be generated
1214 * @param maker constructor class
1215 * @param optional more arguments for {@code maker}'s make method
1216 * @return sub-vat permissions, including a promise for the object returned
1217 * by the {@code maker}
1218 */
1219 public <R> Vat<R>
1220 spawn(final String label, final Class<?> maker, final Object... optional) {
1221 /**
1222 * The default implementation just calls the make method in a separate
1223 * event loop turn.
1224 */
1225 try {
1226 final Method make = NotAMaker.dispatch(maker);
1227 final Class<?>[] paramv = make.getParameterTypes();
1228 final ConstArray.Builder<Object> argv =
1229 ConstArray.builder(paramv.length);
1230 if (0 != paramv.length && Eventual.class == paramv[0]) {
1231 argv.append(this);
1232 }
1233 for (final Object x : optional) { argv.append(x); }
1234 final @SuppressWarnings("unchecked") R top =
1235 (R)when(maker, new Invoke<Class<?>>(make, argv.snapshot()));
1236 final Promise<Receiver<?>> ignore = reject(null);
1237 return new Vat<R>(top, cast(Receiver.class, ignore));
1238 } catch (final Exception e) { throw new Error(e); }
1239 }
1240
1241 // The following convenience overloads are supported under JDK1.6 and early
1242 // versions of JDK1.5, but not on later versions of JDK1.5. They support a
1243 // slighter better syntax and are faster than the generic implementations.
1244 //
1245 // /**
1246 // * Registers an observer on a promise.
1247 // * <p>
1248 // * The implementation behavior is the same as that documented for the
1249 // * promise based {@link #when(Promise, Do) when} statement.
1250 // * </p>
1251 // * @param <P> {@code observer}'s parameter type
1252 // * @param <R> {@code observer}'s return type
1253 // * @param promise observed promise
1254 // * @param observer observer, MUST NOT be {@code null}
1255 // * @return promise for the observer's return value
1256 // */
1257 // public final <P,R extends Serializable> Promise<R>
1258 // when(final Promise<P> promise, final Do<P,R> observer) {
1259 // try {
1260 // return when(Object.class, promise, observer);
1261 // } catch (final Exception e) { throw new Error(e); }
1262 // }
1263 //
1264 // /**
1265 // * Registers an observer on a promise.
1266 // * <p>
1267 // * The implementation behavior is the same as that documented for the
1268 // * promise based {@link #when(Promise, Do) when} statement.
1269 // * </p>
1270 // * @param <P> {@code observer}'s parameter type
1271 // * @param promise observed promise
1272 // * @param observer observer, MUST NOT be {@code null}
1273 // */
1274 // public final <P> void
1275 // when(final Promise<P> promise, final Do<P,Void> observer) {
1276 // try {
1277 // when(Void.class, promise, observer);
1278 // } catch (final Exception e) { throw new Error(e); }
1279 // }
1280 //
1281 // /**
1282 // * Registers an observer on an {@linkplain #_ eventual reference}.
1283 // * <p>
1284 // * The implementation behavior is the same as that documented for the
1285 // * promise based {@link #when(Promise, Do) when} statement.
1286 // * </p>
1287 // * @param <P> {@code observer}'s parameter type
1288 // * @param <R> {@code observer}'s return type
1289 // * @param reference observed reference
1290 // * @param observer observer, MUST NOT be {@code null}
1291 // * @return promise for the observer's return value
1292 // */
1293 // public final <P,R extends Serializable> Promise<R>
1294 // when(final P reference, final Do<P,R> observer) {
1295 // try {
1296 // return when(Object.class, ref(reference), observer);
1297 // } catch (final Exception e) { throw new Error(e); }
1298 // }
1299 //
1300 // /**
1301 // * Registers an observer on an {@linkplain #_ eventual reference}.
1302 // * <p>
1303 // * The implementation behavior is the same as that documented for the
1304 // * promise based {@link #when(Promise, Do) when} statement.
1305 // * </p>
1306 // * @param <P> {@code observer}'s parameter type
1307 // * @param reference observed reference
1308 // * @param observer observer, MUST NOT be {@code null}
1309 // */
1310 // public final <P> void
1311 // when(final P reference, final Do<P,Void> observer) {
1312 // try {
1313 // when(Void.class, ref(reference), observer);
1314 // } catch (final Exception e) { throw new Error(e); }
1315 // }
1316 //
1317 // /**
1318 // * Causes a compile error for code that attempts to cast a promise to a
1319 // * concrete type.
1320 // * <p>
1321 // * If you encounter a compile error because your code is linking to this
1322 // * method, replace the specified concrete type with an
1323 // * {@linkplain Proxies#isImplementable allowed} proxy type. For example,
1324 // * </p>
1325 // * <kbd>final Observer o_ = _.cast(Observer.class, op);</kbd>
1326 // * <p>becomes:</p>
1327 // * <kbd>final Receiver<?> o_ = _.cast(Receiver.class, op);</kbd>
1328 // * @param <R> referent type to implement
1329 // * @param type ignored
1330 // * @param promise ignored
1331 // * @throws AssertionError always thrown
1332 // */
1333 // static public <R extends Serializable> void
1334 // cast(final Class<R> type,
1335 // final Promise<?> promise) { throw new AssertionError();}
1336 }