Next: Blocking multiple provides, Previous: Indirect blocking multiple external out events, Up: Execution Semantics [Contents][Index]
For the remainder of this chapter in our explanations we will be using the following two interfaces:
ihello
interface ihello { in void hello(); behavior { on hello: {} } }
iworld
interface iworld { in void hello(); out void world(); behavior { bool idle = true; [idle] on hello: idle = false; [!idle] on inevitable: {idle = true; world;} } }
So far we have seen examples with more than one requires port. This topology leads to a tree like hierarchy which is a common structure to organize or coordinate in a top down fashion. In the case of sharing a single resource between multiple parties we need the opposite. The example below demonstrates to use of two provides ports.
import ihello.dzn; component multiple_provides { provides ihello left; provides ihello right; requires ihello hello; behavior { on left.hello(): hello.hello(); on right.hello(): hello.hello(); } }
This component simply multiplexes the hello
events from its
provides
ports to its requires
port, resulting in the
following event sequence trace:
If we replace the ihello
interface in our previous example with
the iworld
interface and correct for the behavioral changes, we
get the following component:
import iworld.dzn; component async_multiple_provides { provides iworld left; provides iworld right; requires iworld world; behavior { enum Side {None, Left, Right}; Side side = Side.None; Side pending = Side.None; [side.None] { on left.hello(): {side = Side.Left; world.hello();} on right.hello(): {side = Side.Right; world.hello();} } [side.Left] { [pending.None] { on right.hello(): pending = Side.Right; on world.world(): {side = Side.None; left.world();} } [pending.Right] on world.world(): { side = pending; pending = Side.None; left.world(); world.hello(); } } [side.Right] { [pending.None] { on left.hello(): pending = Side.Left; on world.world(): {side = Side.None; right.world();} } [pending.Left] on world.world(): { side = pending; pending = Side.None; right.world(); world.hello(); } } } }
As we can see from the behavior and the event sequence trace below, asynchonous behavior leads to event interleaving, which requires state to manage the behavior.
Next: Blocking multiple provides, Previous: Indirect blocking multiple external out events, Up: Execution Semantics [Contents][Index]