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    }