Go to the first, previous, next, last section, table of contents.
-
This form of the select_statement allows a combination of waiting for,
and selecting from, one or more alternatives. The selection may depend
on conditions associated with each alternative of the selective_accept.
Syntax
-
selective_accept ::=
select
[guard]
select_alternative
{ or
[guard]
select_alternative }
[ else
sequence_of_statements ]
end select;
-
guard ::= when condition =>
-
select_alternative ::=
accept_alternative
| delay_alternative
| terminate_alternative
-
accept_alternative ::=
accept_statement [sequence_of_statements]
-
delay_alternative ::=
delay_statement [sequence_of_statements]
-
terminate_alternative ::= terminate;
-
A selective_accept shall contain at least one accept_alternative. In
addition, it can contain:
-
a terminate_alternative (only one); or
-
one or more delay_alternatives; or
-
an else part (the reserved word else followed by a
sequence_of_statements).
-
These three possibilities are mutually exclusive.
Legality Rules
-
If a selective_accept contains more than one delay_alternative, then all
shall be delay_relative_statements, or all shall be
delay_until_statements for the same time type.
Dynamic Semantics
-
A select_alternative is said to be open if it is not immediately
preceded by a guard, or if the condition of its guard evaluates to True.
It is said to be closed otherwise.
-
For the execution of a selective_accept, any guard conditions are
evaluated; open alternatives are thus determined. For an open
delay_alternative, the delay_expression is also evaluated. Similarly,
for an open accept_alternative for an entry of a family, the entry_index
is also evaluated. These evaluations are performed in an arbitrary
order, except that a delay_expression or entry_index is not evaluated
until after evaluating the corresponding condition, if any. Selection
and execution of one open alternative, or of the else part, then
completes the execution of the selective_accept; the rules for this
selection are described below.
-
Open accept_alternatives are first considered. Selection of one such
alternative takes place immediately if the corresponding entry already
has queued calls. If several alternatives can thus be selected, one of
them is selected according to the entry queuing policy in effect,
See section 9.5.3 Entry Calls, and See section D.4 Entry Queuing Policies. When such an alternative is selected, the
selected call is removed from its entry queue and the
handled_sequence_of_statements (if any) of the corresponding
accept_statement is executed; after the rendezvous completes any
subsequent sequence_of_statements of the alternative is executed. If no
selection is immediately possible (in the above sense) and there is no
else part, the task blocks until an open alternative can be selected.
-
Selection of the other forms of alternative or of an else part is
performed as follows:
-
An open delay_alternative is selected when its expiration time is
reached if no accept_alternative or other delay_alternative can be
selected prior to the expiration time. If several delay_alternatives
have this same expiration time, one of them is selected according to the
queuing policy in effect, See section D.4 Entry Queuing Policies, the default queuing policy chooses
arbitrarily among the delay_alternatives whose expiration time has
passed.
-
The else part is selected and its sequence_of_statements is executed if
no accept_alternative can immediately be selected; in particular, if all
alternatives are closed.
-
An open terminate_alternative is selected if the conditions stated at
the end of clause See section 9.3 Task Dependence - Termination of Tasks, are satisfied.
-
The exception Program_Error is raised if all alternatives are closed and
there is no else part.
NOTES
-
(36) A selective_accept is allowed to have several open
delay_alternatives. A selective_accept is allowed to have several open
accept_alternatives for the same entry.
Examples
-
Example of a task body with a selective accept:
-
task body Server is
Current_Work_Item : Work_Item;
begin
loop
select
accept Next_Work_Item(WI : in Work_Item) do
Current_Work_Item := WI;
end;
Process_Work_Item(Current_Work_Item);
or
accept Shut_Down;
exit; -- Premature shut down requested
or
terminate; -- Normal shutdown at end of scope
end select;
end loop;
end Server;
Go to the first, previous, next, last section, table of contents.