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 }