Previous: guard
, Up: Declarative Statements [Contents][Index]
inevitable
and optional
In interfaces, two modeling events may be used as abstract
triggers, i.e. inevitable
and optional
:
on inevitable: imperative-statement; on optional: imperative-statement;
Where inevitable
implies that if no other triggers occur, this
trigger is guaranteed to occur, and optional
implies that the
trigger may or may never occur.
Note that an inevitable event is not allways guaranteed to occur, it is only inevitable in the absence of other events.
An example of an interface using both inevitable and optional.
interface inevitable_optional { in bool hello (); in void bye (); out void world (); out void cruel (); behavior { enum status {IDLE, WORLD, CRUEL}; status state = status.IDLE; [state.IDLE] { on hello: {state = status.WORLD; reply (true);} on hello: {state = status.CRUEL; reply (false);} } [state.WORLD] on inevitable: {state = status.IDLE; world;} [state.CRUEL] { on optional: {state = status.WORLD; cruel;} on bye: state = status.IDLE; } } }
In the interface above a reply value of true
on hello
informs the client sending the hello
that the world
can be
waited on. However in case the reply value of hello
is
false
and the client would sit there waiting for cruel
to
happen, they may sit there forever because cruel
might never
happen. This is what we refer to as a deadlock. To avoid this
deadlock as a client, they must make sure that they can handle a
cruel
in case it does happen and that they have another way of
making progress in case cruel
never happens.
Conversely, the implementation of this interface may choose to perform
the cruel always, never or intermittently after a hello
followed
by a false
, but it must (being contractually required) always do
a world
after a hello
followed by a true
.
Previous: guard
, Up: Declarative Statements [Contents][Index]