Although the async feature makes use of an event-pump it does not have any specific effect on the interaction with native code. The only requirement to be able to use ‘async’ is that you have an event-pump. A system generated with a thread-safe-shell will get an event pump implicitly but you could also build one in native code. In this description we simply refer to the Dezyne runtime in combination with code generated with the option to generate a thread-safe-shell. For more information read an article about the event pump and one about the thread-safe shell.
In the execution semantics of Dezyne events are handled in a fixed order. For an in-event all action statements are executed depth-first. All out-events are stored in event queues at the receiving components. After the completion of all action statements, just before control is passed back to the caller, a component will flush its own queue of pending out-events.
Recursively all out-events are handled this way. This process is repeated for all components involved in handling the external event. As last action in the row, just before the Dezyne private thread would switch to a ‘waiting for next event’ mode, the queue of async events would be handled.
In the diagram above an external event could lead to actions in Component1 and Component2. First all processing as a result of the external event is handled; this might include raising async events which are stored in the Async Event Queue. Then, before the next external event is picked up from the External Event Queue the contents of Async Event Queue is handled.
There could be several components between the component where the async is handled and the component where the external event fires after being picked up by the event pump. At the level of the ‘async’ component there could be more input events resulting from the original external event that would be processed before the async queued event gets activated. The component simulator cannot see whether multiple events entering a component belong to a tree of actions resulting from one external event or from multiple external events. So the simulator cannot see whether an external event has been completely handled and async events can already be activated. As a consequence the simulator will offer more choices in the next eligible events than could happen in practice at system level.
In the example above events ‘a’ and ‘b’ could be resulting from the same external event e.g. ‘e1’ or they could be resulting from 2 different external events ‘e1’ and ‘e2’.
The blocking keyword creates a dependency on an event external to the component to eventually lift the blocking situation. Obviously this introduces a risk if the external event never comes. See the description at the blocking keyword.
The async feature in fact removes the dependency of an event external to the component. So in its use no risks are introduced, in fact there is one dependency less.