Contents Index Previous Next
9.7.1 Selective Accept
1
[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.
{time-out: See selective_accept} ]
Syntax
2
selective_accept
::=
select
[
guard]
select_alternative
{
or
[
guard]
select_alternative }
[
else
sequence_of_statements ]
end select;
3
guard
::= when condition =>
4
select_alternative
::=
accept_alternative
|
delay_alternative
|
terminate_alternative
5
accept_alternative
::=
accept_statement [
sequence_of_statements]
6
delay_alternative
::=
delay_statement [
sequence_of_statements]
7
terminate_alternative
::= terminate;
8
A selective_accept
shall contain at least one accept_alternative.
In addition, it can contain:
9
- a terminate_alternative
(only one); or
10
- one or more delay_alternatives;
or
11
- {else part (of a selective_accept)}
an else part (the reserved word else
followed by a sequence_of_statements).
12
These three possibilities are mutually exclusive.
Legality Rules
13
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.
13.a
Reason: This simplifies
the implementation and the description of the semantics.
Dynamic Semantics
14
{open alternative}
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.
15
{execution (selective_accept)
[partial]} 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.
16
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
9.5.3 and
D.4).
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.
{blocked (execution of a selective_accept)
[partial]} 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.
17
Selection of the
other forms of alternative or of an else part is performed as follows:
18
- 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 D.4); the default queuing
policy chooses arbitrarily among the delay_alternatives
whose expiration time has passed.
19
- 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.
20
- An open terminate_alternative
is selected if the conditions stated at the end of clause 9.3
are satisfied.
20.a
Ramification: In the absence
of a requeue_statement, the conditions
stated are such that a terminate_alternative
cannot be selected while there is a queued entry call for any entry of
the task. In the presence of requeues from a task to one of its subtasks,
it is possible that when a terminate_alternative
of the subtask is selected, requeued calls (for closed entries only)
might still be queued on some entry of the subtask. Tasking_Error will
be propagated to such callers, as is usual when a task completes while
queued callers remain.
21
{Program_Error (raised by failure
of run-time check)} The exception Program_Error
is raised if all alternatives are closed and there is no else part.
22
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
23
Example of a
task body with a selective accept:
24
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;
Wording Changes from Ada 83
24.a
The name of selective_wait
was changed to selective_accept
to better describe what is being waited for. We kept select_alternative
as is, because selective_accept_alternative
was too easily confused with accept_alternative.
Contents Index Previous Next Legal