001 package javax.realtime; 002 003 /** A special exception that is thrown in response to an attempt to 004 * asynchronously transfer the locus of control of a <code>RealtimeThread</code>. 005 * <p> 006 * When a method is declared with <code>AsynchronouslyInterruptedException</code> 007 * in its <code>throws</code> clause the platform is expected to 008 * asynchronously throw this exception if <code>RealtimeThread.interrupt()</code> 009 * is called while the method is executing, or if such an interrupt 010 * is pending any time control returns to the method. The interrupt 011 * is <i>not</i> thrown while any methods it invokes are executing, 012 * unless they are, in turn, declared to throw the exception. This 013 * is intended to allow long-running compuations to be terminated 014 * without the overhead or latency of polling with 015 * <code>java.lang.Thread.interrupted()</code>. 016 * <p> 017 * The <code>throws AsynchronouslyInterruptedException</code> clause 018 * is a marker on a stack frame which allows a method to be statically 019 * marked as asynchronously interruptible. Only methods that are 020 * marked this way can be interrupted. 021 * <p> 022 * When <code>Thread.interrupt(), interrupt()</code>, or <code>this.fire</code> 023 * is called, the <code>AsynchronouslyInterruptedException</code> is 024 * compared against any currently pending <code>AsynchronouslyInterruptedException</code> 025 * on the thread. If there none, or the depth of the 026 * <code>AsynchronouslyInterruptedException</code> is less than the 027 * currently pending <code>AsynchronouslyInterruptedException</code> 028 * -- i.e., it is targeted at a less deeply nested method call -- 029 * it becomes the currently pending interrupt. Otherwise, it is discarded. 030 * <p> 031 * If the current method is interruptible, the exception is thrown on 032 * the thread. Otherwise, it just remains pending until control 033 * returns to an interruptible method, at which point the 034 * <code>AsynchronouslyInterruptedException</code> is thrown. When 035 * an interrupt is caught, the caller should invoke the 036 * <code>happened</code> method on the <code>AsynchronouslyInterruptedException</code> 037 * in which it is interested to see if it matches the pending 038 * <code>AsynchronouslyInterruptedException</code>. If so, the 039 * pending <code>AsynchronouslyInterruptedException</code> is cleared 040 * from the thread. Otherwise, it will continue to propagate outward. 041 * <p> 042 * <code>Thread.interrupt()</code> and <code>RealtimeThread.interrupt()</code> 043 * generate a system available generic <code>AsynchronouslyInterruptedException</code> 044 * which will always propagate outward through interruptible methods until 045 * the generic <code>AsynchronouslyInterruptedException</code> is 046 * identified and stopped. Other sources (e.g., <code>this.fire()</code> 047 * and <code>Timed</code>) will generate a specific instance of 048 * <code>AsynchronouslyInterruptedException</code> which applications 049 * can identify and thus limit propagation. 050 */ 051 public class AsynchronouslyInterruptedException extends InterruptedException { 052 053 private boolean enabled = true; 054 055 /** Create an instance of <code>AsynchronouslyInterruptedException</code>. */ 056 public AsynchronouslyInterruptedException() {} 057 058 /** Defer the throwing of this exception. If <code>interrupt()</code> is 059 * called when this exception is disabled, the exception is put in 060 * pending state. The exception will be thrown if this exception is 061 * subsequently enabled. This is valid only within a call to 062 * <code>doInterruptible()</code>. Otherwise it returns false and 063 * does nothing. 064 * 065 * @return True if <code>this</code> is disabled and invoked within a call to 066 * <code>doInterruptable()</code>. False if <code>this</code> is enabled 067 * and invoked within a call to <code>doInterruptable()</code> or 068 * invoked outside of a call to <code>doInterruptable()</code>. 069 */ 070 public boolean disable() { 071 enabled = false; 072 // TODO 073 074 return false; 075 } 076 077 /** Execute the <code>run()</code> method of the given <code>Interruptible</code>. 078 * This method may be on the stack in exacly one <code>RealtimeThread</code>. 079 * An attempt to invoke this method in a thread while it is on the stack of 080 * another of the same thread will cause an immediate return with a value of false. 081 * 082 * @param logic An instance of an <code>Interruptable</code> whose <code>run()</code> 083 * method will be called. 084 * @return True if the method call completed normally. False if another call to 085 * <code>doInterruptible()</code> has not completed. 086 */ 087 public boolean doInterruptible(Interruptible logic) { 088 // TODO 089 090 return false; 091 } 092 093 /** Enable the throwing of this exception. This method is valid only within a call 094 * to <code>doInterruptible()</code>. If invoked outside of a call to 095 * <code>doInterruptible()</code> this method returns false and does nothing. 096 * 097 * @return True if <code>this</code> is enabled and invoked within a call to 098 * <code>doInterruptible()</code>. False if <code>this</code> is disabled 099 * and invoked within a call to <code>doInterruptible()</code> or invoked 100 * outside of a call to <code>doInterruptible()</code>. 101 */ 102 public boolean enable() { 103 enabled = true; 104 // TODO 105 106 return false; 107 } 108 109 /** Make this exception the current exception if <code>doInterruptible()</code> 110 * has been invoked and not completed. 111 * 112 * @return True if <code>this</code> was fired. False if there is no current 113 * invocation of <code>doInterruptible()</code> (with no other effect), 114 * if there is already a current <code>doInterruptible()</code>, or if 115 * <code>disable()</code> has been called. 116 */ 117 public boolean fire() { 118 // TODO 119 120 return false; 121 } 122 123 /** Gets the system generic <code>AsynchronouslyInterruptedException</code>, 124 * which is generated when <code>RealtimeThread.interrupt()</code> is invoked. 125 * 126 * @return The generic <code>AsynchronouslyInterruptedException</code>. 127 */ 128 public static AsynchronouslyInterruptedException getGeneric() { 129 // TODO 130 131 return null; 132 } 133 134 /** Used with an instance of this exception to see if the current 135 * exception is this exception. 136 * 137 * @param propagate If true and this exception is not the current one propagate 138 * the exception. If false, then the state of this is set to 139 * nonpending (i.e., it will stop propagating). 140 * @return True if this is the current exception. False if this is not the 141 * current exception. 142 */ 143 public boolean happened(boolean propagate) { 144 // TODO 145 146 return false; 147 } 148 149 /** Query the enabled status of this exception. 150 * 151 * @return True if this is enabled. False otherwise. 152 */ 153 public boolean isEnabled() { 154 return enabled; 155 } 156 157 /** Cause the pending exception to continue up the stack. */ 158 public static void propagate() { 159 // TODO 160 } 161 }