Annotated Ada Reference ManualLegal Information
Contents   Index   References   Search   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.
NOTES
22
39  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   References   Search   Previous   Next 
Ada-Europe Sponsored by Ada-Europe