Annotated Ada Reference ManualLegal Information
Contents   Index   References   Search   Previous   Next 

9.7.4 Asynchronous Transfer of Control

1
[An asynchronous select_statement provides asynchronous transfer of control upon completion of an entry call or the expiration of a delay.] 

Syntax

2
asynchronous_select ::= 
  select
   triggering_alternative
  then abort
   abortable_part
  end select;
3
triggering_alternative ::= triggering_statement [sequence_of_statements]
4/2
{AI95-00345-01} triggering_statement ::= procedure_or_entry_call | delay_statement
5
abortable_part ::= sequence_of_statements

Dynamic Semantics

6/2
{AI95-00345-01} {execution (asynchronous_select with an entry call trigger) [partial]} {execution (asynchronous_select with a procedure call trigger) [partial]} For the execution of an asynchronous_select whose triggering_statement is a procedure_or_entry_call, the entry_name, procedure_name, or procedure_prefix, and actual parameters are evaluated as for a simple entry call (see 9.5.3) or procedure call (see 6.4). If the call is an entry call or a call on a procedure implemented by an entry, the entry call is issued. If the entry call is queued (or requeued-with-abort), then the abortable_part is executed. [If the entry call is selected immediately, and never requeued-with-abort, then the abortable_part is never started.] If the call is on a procedure that is not implemented by an entry, the call proceeds as described in 6.4, followed by the sequence_of_statements of the triggering_alternative[; the abortable_part is never started].
7
{execution (asynchronous_select with a delay_statement trigger) [partial]} For the execution of an asynchronous_select whose triggering_statement is a delay_statement, the delay_expression is evaluated and the expiration time is determined, as for a normal delay_statement. If the expiration time has not already passed, the abortable_part is executed.
8
If the abortable_part completes and is left prior to completion of the triggering_statement, an attempt to cancel the triggering_statement is made. If the attempt to cancel succeeds (see 9.5.3 and 9.6), the asynchronous_select is complete.
9
If the triggering_statement completes other than due to cancellation, the abortable_part is aborted (if started but not yet completed — see 9.8). If the triggering_statement completes normally, the optional sequence_of_statements of the triggering_alternative is executed after the abortable_part is left. 
9.a
Discussion: We currently don't specify when the by-copy [in] out parameters are assigned back into the actuals. We considered requiring that to happen after the abortable_part is left. However, that doesn't seem useful enough to justify possibly overspecifying the implementation approach, since some of the parameters are passed by reference anyway.
9.b
In an earlier description, we required that the sequence_of_statements of the triggering_alternative execute after aborting the abortable_part, but before waiting for it to complete and finalize, to provide more rapid response to the triggering event in case the finalization was unbounded. However, various reviewers felt that this created unnecessary complexity in the description, and a potential for undesirable concurrency (and nondeterminism) within a single task. We have now reverted to simpler, more deterministic semantics, but anticipate that further discussion of this issue might be appropriate during subsequent reviews. One possibility is to leave this area implementation defined, so as to encourage experimentation. The user would then have to assume the worst about what kinds of actions are appropriate for the sequence_of_statements of the triggering_alternative to achieve portability. 

Examples

10
{signal handling (example)} {interrupt (example using asynchronous_select)} {terminal interrupt (example)} Example of a main command loop for a command interpreter: 
11
loop
    select
        Terminal.Wait_For_Interrupt;
        Put_Line("Interrupted");
    then abort
        -- This will be abandoned upon terminal interrupt
        Put_Line("-> ");
        Get_Line(Command, Last);
        Process_Command(Command(1..Last));
    end select;
end loop;
12
Example of a time-limited calculation: {time-out: See asynchronous_select} {time-out (example)} {time limit (example)} {interrupt (example using asynchronous_select)} {timer interrupt (example)}
13
select
   delay 5.0;
   Put_Line("Calculation does not converge");
then abort
   -- This calculation should finish in 5.0 seconds;
   --  if not, it is assumed to diverge.
   Horribly_Complicated_Recursive_Function(X, Y);
end select;

Extensions to Ada 83

13.a
{extensions to Ada 83} Asynchronous_select is new. 

Extensions to Ada 95

13.b/2
{AI95-00345-01} {extensions to Ada 95} A procedure can be used as the triggering_statement of an asynchronous_select, if the procedure might actually be an entry 

Contents   Index   References   Search   Previous   Next 
Ada-Europe Sponsored by Ada-Europe