Lady Ada

Ada '83 Language Reference Manual

Copyright 1980, 1982, 1983 owned by the United States Government. Direct reproduction and usage requests to the Ada Information Clearinghouse.


9.7. Select Statements

[PREVIOUS][UP][NEXT]

There are three forms of select statements. One form provides a selective wait for one or more alternatives. The other two provide conditional and timed entry calls.

    select_statement ::= selective_wait
       | conditional_entry_call | timed_entry_call  

References: selective wait, conditional entry call, timed entry call.

Rationale references: 13.2.5 The Select Statement, 13.2.6 Timing, 13.2.7 Timed and Conditional Communication

Style Guide references: 2.1.2 Indentation, 5.6.1 Nesting, 6.2.1 Efficient Task Communications, 6.2.6 Communication Complexity

Sub-topics:

9.7.1. Selective Waits

[UP][NEXT]

This form of the select statement allows a combination of waiting for, and selecting from, one or more alternatives. The selection can depend on conditions associated with each alternative of the selective wait.

    selective_wait ::=
        select
          select_alternative
       {or
          select_alternative}
       [else
          sequence_of_statements]
        end select; 

    select_alternative ::=
       [when condition =>]
          selective_wait_alternative 

    selective_wait_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 wait must contain at least one accept alternative. In addition a selective wait can contain either a terminate alternative (only one), or one or more delay alternatives, or an else part; these three possibilities are mutually exclusive.

A select alternative is said to be open if it does not start with when and a condition, or if the condition is TRUE. It is said to be closed otherwise.

For the execution of a selective wait, any conditions specified after when are evaluated in some order that is not defined by the language; 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. Selection and execution of one open alternative, or of the else part, then completes the execution of the selective wait; the rules for this selection are described below.

Open accept alternatives are first considered. Selection of one such alternative takes place immediately if a corresponding rendezvous is possible, that is, if there is a corresponding entry call issued by another task and waiting to be accepted. If several alternatives can thus be selected, one of them is selected arbitrarily (that is, the language does not define which one). When such an alternative is selected, the corresponding accept statement and possible subsequent statements are executed. If no rendezvous is immediately possible and there is no else part, the task waits until an open selective wait alternative can be selected.

Selection of the other forms of alternative or of an else part is performed as follows:

The exception PROGRAM_ERROR is raised if all alternatives are closed and there is no else part.

Examples of a select statement:

    select
       accept DRIVER_AWAKE_SIGNAL;
    or
       delay 30.0*SECONDS;
       STOP_THE_TRAIN;
    end select; 

Example of a task body with a select statement:

    task body RESOURCE is
       BUSY : BOOLEAN := FALSE;
    begin
       loop
          select
             when not BUSY =>
                accept SEIZE do
                   BUSY := TRUE;
                end;
          or
             accept RELEASE do
                BUSY := FALSE;
             end;
          or
             terminate;
          end select;
       end loop;
    end RESOURCE; 

Notes:

A selective wait is allowed to have several open delay alternatives. A selective wait is allowed to have several open accept alternatives for the same entry.

References: accept statement, condition, declaration, delay expression, delay statement, duration, entry, entry call, entry index, program_error exception, queued entry call, rendezvous, select statement, sequence of statements, task.

Style Guide references: 6.2.1 Efficient Task Communications, 6.2.2 Defensive Task Communication, 6.2.4 Shared Variables, 6.2.5 Tentative Rendezvous Constructs, 6.3.2 Normal Termination, 7.4.4 Select Statement Evaluation Order

9.7.2. Conditional Entry Calls

[PREVIOUS][UP][NEXT]

A conditional entry call issues an entry call that is then canceled if a rendezvous is not immediately possible.

    conditional_entry_call ::=
       select  
           entry_call_statement
          [sequence_of_statements]
       else
           sequence_of_statements
       end select;                                                                      

For the execution of a conditional entry call, the entry name is first evaluated. This is followed by any evaluations required for actual parameters as in the case of a subprogram call (see 6.4).

The entry call is canceled if the execution of the called task has not reached a point where it is ready to accept the call (that is, either an accept statement for the corresponding entry, or a select statement with an open accept alternative for the entry), or if there are prior queued entry calls for this entry. If the called task has reached a select statement, the entry call is canceled if an accept alternative for this entry is not selected.

If the entry call is canceled, the statements of the else part are executed. Otherwise, the rendezvous takes place; and the optional sequence of statements after the entry call is then executed.

The execution of a conditional entry call raises the exception TASKING_ERROR if the called task has already completed its execution (see also 9.10 for the case when the called task becomes abnormal).

Example:

    procedure SPIN(R : RESOURCE) is
    begin
       loop
          select
             R.SEIZE;
             return;
          else
             null;  --  busy waiting
          end select;
       end loop;
    end; 

References: abnormal task, accept statement, actual parameter part, completed task, entry call statement, entry family, entry index, evaluation, expression, open alternative, queued entry call, rendezvous, select statement, sequence of statements, task, tasking_error exception.

Style Guide references: 4.2.4 Hiding Tasks, 6.2.5 Tentative Rendezvous Constructs

9.7.3. Timed Entry Calls

[PREVIOUS][UP]

A timed entry call issues an entry call that is canceled if a rendezvous is not started within a given delay.

    timed_entry_call ::=
       select
           entry_call_statement
          [sequence_of_statements]
       or
           delay_alternative  
       end select;                                                                 

For the execution of a timed entry call, the entry name is first evaluated. This is followed by any evaluations required for actual parameters as in the case of a subprogram call (see 6.4). The expression stating the delay is then evaluated, and the entry call is finally issued.

If a rendezvous can be started within the specified duration (or immediately, as for a conditional entry call, for a negative or zero delay), it is performed and the optional sequence of statements after the entry call is then executed. Otherwise, the entry call is canceled when the specified duration has expired, and the optional sequence of statements of the delay alternative is executed.

The execution of a timed entry call raises the exception TASKING_ERROR if the called task completes its execution before accepting the call (see also 9.10 for the case when the called task becomes abnormal).

Example:

    select
       CONTROLLER.REQUEST(MEDIUM)(SOME_ITEM);
    or
       delay 45.0;
       --  controller too busy, try something else
    end select; 

References: abnormal task, accept statement, actual parameter part, completed task, conditional entry call, delay expression, delay statement, duration, entry call statement, entry family, entry index, evaluation, expression, rendezvous, sequence of statements, task, tasking_error exception.

Style Guide references: 4.2.4 Hiding Tasks, 6.1.5 Delay Statements, 6.2.5 Tentative Rendezvous Constructs

[INDEX][CONTENTS]


[Ada Information Clearinghouse]

Address any questions or comments to adainfo@sw-eng.falls-church.va.us.