See:
Description
Packages | |
---|---|
javax.realtime |
This section contains classes that manage asynchrony. They:
AE - Asynchronous Event. An instance of the javax.realtime.AsyncEvent class.
AEH - Asynchronous Event Handler. An instance of the javax.realtime.AsyncEventHandler class.
Bound AEH - Bound Asynchronous Event Handler. An instance of the javax.realtime.BoundAsyncEventHandler class.
ATC - Asynchronous Transfer of Control.
AIE - Asynchronously Interrupted Exception. An instance of javax.realtime.AsynchronouslyInterruptedException class (a subclass of java.lang.InterruptedException).
AI-method - Asynchronously Interruptible method. A method or constructor that includes AsynchronouslyInterruptedException explicitly (that is not a subclass of AsynchronouslyInterruptedException) in its throws clause.
A happening is an event that takes place outside the Java runtime environment. The triggers for happenings depend on the external environment, but happenings might include signals and interrupts.
Lexical Scope [of a method, constructor, or statement]. The textual region within the constructor, method, or statement, excluding the code within any class declarations, and the code within any class instance creation expressions for anonymous classes, contained therein. The lexical scope of a construct does not include the bodies of any methods or constructors that this code invokes.
ATC-deferred section. A synchronized statement, a static initializer or any method or constructor without AsynchronouslyInterruptedException
in its throws clause. As specified in the introduction to Chapter 8 in Java Language Specification, a synchronized method is equivalent to a non-synchronized method with the body of the method contained in a synchronized statement. Thus, a synchronized AI method behaves like an AI method containing only an ATC-deferred statement.
Interruptible blocking methods. The RTSJ and standard Java methods that are explicitly interruptible by an AIE. The interruptible blocking methods comprise HighResolutionTime.waitForObject()
, Object.wait()
, Thread.sleep(), RealtimeThread.sleep()
, Thread.join(),
ScopedMemory.join()
, ScopedMemory.joinAndEnter(),
RealtimeThread.waitForNextPeriodInterruptible(),
WaitFreeWriteQueue.read(),
WaitFreeReadQueue.waitForData()
, WaitFreeReadQueue.write()
,
WaitFreeDequeue.blockingRead(),
WaitFreeDequeue.blockingWrite()
and their overloaded forms.
Asynchronous event handling is captured by the classes AsyncEvent (AE), AsyncEventHandler (AEH) and BoundAsyncEventHandler. An AE is an object used to direct event occurrences to asynchronous event handlers. An event occurrence may be initiated by application logic, by mechanisms internal to the RTSJ implementation (see the handlers in PeriodicParameters
), or by the triggering of a happening external to the JVM (such as a software signal or a hardware interrupt handler). An event occurrence is initiated in program logic by the invocation of the fire() method of an AE. The triggering of an event due to a happening is implementation dependent except as specified in POSIXSignalHandler
,
An AEH is a schedulable object embodying code that is released for execution in response to the occurrence of an associated event. Each AEH behaves as if it is executed by a RealtimeThread
or NoHeapRealtimeThread
except that it is not permitted to use the waitForNextPeriod()
or waitForNextPeriodInterruptible()
methods, and it is treated as having a null thread group in all cases. There is not necessarily a separate real-time thread for each AEH, but the server real-time thread (returned by currentRealtimeThread()
) remains constant during each execution of the run()
method. The class BoundAsyncEventHandler
extends AsyncEventHandler
and ensures that a handler has a dedicated server real-time thread (a server thread is associated with one and only one bound AEH for the lifetime of that AEH). An event count (called fireCount) is maintained so that a handler can cope with event bursts - situations where an event occurs more frequently than its handler can respond.
The interrupt() method in java.lang.Thread provides rudimentary asynchronous communication by setting a pollable/resettable flag in the target thread, and by throwing a synchronous exception when the target thread is blocked at an invocation of wait(), sleep(), or join(). This specification extends the effect of Thread.interrupt() by adding an overridden version in RealtimeThread, offering a more comprehensive and non-polling asynchronous execution control facility. It is based on throwing and propagating exceptions that, though asynchronous, are deferred where necessary in order to avoid data structure corruption. The main elements of ATC are embodied in the class AsynchronouslyInterruptedException, its subclass Timed, the interface Interruptible, and in the semantics of the interrupt method in RealtimeThread.
A method indicates its eligibility to be asynchronously interrupted by including the checked exception AsynchronouslyInterruptedException in its throws clause. If a schedulable object is asynchronously interrupted while executing such a method, then an AIE will be delivered as soon as the schedulable object is outside of a section in which ATC is deferred. Several idioms are available for handling an AIE, giving the programmer the choice of using catch clauses and a low-level mechanism with specific control over propagation, or a higher-level facility that allows specifying the interruptible code, the handler, and the result retrieval as separate methods.
PriorityScheduler
) and at the active priority of the schedulable object that invoked the fire method. The release of handlers resulting from a happening or a timer must begin within a bounded time (ignoring time consumed by unrelated activities in the system). This worst-case response interval must be documented for some reference architecture.
currentRealtimeThread()
while an AEH is running shall behave with respect to memory access and assignment rules as if it were allocated in the same memory area as the AEH.
clear()
, happened()
or doInterruptible()
.
This following list establishes the semantics and requirements that are applicable to ATC. Semantics that apply to particular classes, constructors, methods, and fields will be found in the class description and the constructor, method, and field detail sections.
fire()
method is called on an AIE for which the schedulable object is executing within the doInterruptible()
method, or the RealtimeThread.interrupt()
method is called; the latter is effectively called when an AIE is generated by internal virtual machine mechanisms (such as an interrupt I/O protocol) that are asynchronous to the execution of program logic which is the target of the AIE. A generated AIE becomes pending upon generation and remains pending until explicitly cleared or replaced by another AIE.
RealtimeThread.interrupt()
method throws the generic AIE at the target real-time thread and has the behaviors defined for Thread.interrupt()
. This is the only interaction between the ATC mechanism and the conventional interrupt()
mechanism.
fire()
mechanism behaves as if it set an asynchronously-interrupted status in the schedulable object. If the schedulable object is blocked within an interruptible blocking method, or invokes an interruptible blocking method, when this asynchronously-interrupted status is set, then the invocation immediately completes by throwing the pending AIE and clearing the asynchronously-interrupted status. When a pending AIE is explicitly cleared then the asynchronously-interrupted status is also cleared.catch
or finally
clause of the nearest dynamically-enclosing a try
statement that has a handler for the generated AIE's (that is a handler naming the AIE's class or any of its superclasses, or a finally
clause) and which is in an ATC-deferred section. Intervening handlers and finally
clauses that are not in ATC-deferred sections are not executed, but object locks are released. See section 11.3 of The Java Language Specification second edition for an explanation of the terms, dynamically enclosing and handler. The RTSJ uses those JLS definitions unaltered. Note, if synchronized code is abandoned as a result of this control transfer, the associated locks are released.
Exception
, it is processed as a normal exception, and has no affect on the pending state of any AIE, and no affect on the firing of the AIE concerned.If so is an instance of a schedulable object and the interrupt() method is called on the real-time thread associated with that object (in this context, the associated real-time thread of an AEH is the real-time thread returned by a call of the RealtimeThread.currentRealtimeThread() method by that AEH) then:
catch
or finally
clause of the nearest dynamically-enclosing a try
statement that has a handler for the generated AIE's (that is a handler naming the AIE's class or any of its superclasses, or a finally
clause) and which is in an ATC-deferred section. Intervening handlers and finally
clauses that are not in ATC-deferred sections are not executed, but objects locks are released. See section 11.3 of The Java Language Specification second edition for an explanation of the terms, dynamically enclosing and handles. The RTSJ uses those definitions unaltered.
clear()
method) has no effect.
|
|
|
---|---|---|
propagate == true | clear the pending AIE, return true |
the AIE remains pending, propagate |
propagate == false | clear the pending AIE, return true |
the AIE remains pending, return false |
Events are dataless: the fire method does not pass any data to the handler. This was intentional in the interest of simplicity and efficiency. An application that needs to associate data with an AsyncEvent can do so explicitly by setting up a buffer; it will then need to deal with buffer overflow issues as required by the application.
The ability to trigger an ATC in a schedulable object is necessary in many kinds of real-time applications but must be designed carefully in order to minimize the risks of problems such as data structure corruption and deadlock. There is, invariably, a tension between the desire to cause an ATC to be immediate, and the desire to ensure that certain sections of code are executed to completion.
One basic decision was to allow ATC in a method only if the method explicitly permits this. The default of no ATC is reasonable, since legacy code might be written expecting no ATC, and asynchronously aborting the execution of such a method could lead to unpredictable results. Since the natural way to model ATC is with an exception (AsynchronouslyInterruptedException), the way that a method indicates its susceptibility to ATC is by including AsynchronouslyInterruptedException in its throws clause. Causing this exception to be thrown in a real-time thread t as an effect of calling t.interrupt() was a natural extension of the semantics of interrupt as currently defined by java.lang.Thread.
One ATC-deferred section is synchronized code. This is a context that needs to be executed completely in order to ensure a program operates correctly. If synchronized code were aborted, a shared object could be left in an inconsistent state. Note that by making synchronized code ATC-deferred, this specification avoids the problems that caused Thread.stop() to be deprecated and that have made the use of Thread.destroy(),
(now also deprecated in Java 1.5) prone to deadlock. If synchronized code calls an AI-method and an associated AIE is generated, then if no appropriate handler is present in the synchronized code, the AIE will propagate through the code.
Constructors and finally clauses are subject to interruption if the program indicates so. However, if a constructor is aborted, an object might be only partially initialized. If the execution of a finally clause in an AI-method is aborted, needed cleanup code might not be performed. Indeed, a finally clause in an aborted AI-method will not be executed at all if the abort occurs before its execution begins. It is the programmer's responsibility to ensure that executing these constructs either does not induce unwanted ATC latency (if ATCs are not allowed) or does not produce undesirable results (if ATCs are allowed).
A potential problem with using the exception mechanism to model ATC is that a method with a "catch-all" handler (for example a catch clause identifying Exception or even Throwable as the exception class) can inadvertently intercept an exception intended for a caller. This problem is avoided by having special semantics for catching an AIE. Even though a catch clause may catch an AIE, the exception will be propagated unless the handler invokes the happened method from AIE. Thus, if a schedulable object is asynchronously interrupted while in a try block that has a handler such as
catch (Throwable e){ return; }
the AIE will remain pending and will be thrown next time control enters or returns to an AI method.
This specification does not provide a special mechanism for terminating a real-time thread; ATC can be used to achieve this effect. This means that, by default, a real-time thread cannot be asynchronously terminated; to support asynchronous termination it needs to enter methods that are AI enabled at frequent intervals. Allowing termination as the default would have been questionable, bringing the same insecurities that are found in Thread.stop() and Thread.destroy().