9.7.4 Asynchronous Transfer of Control
[An asynchronous
select_statement
provides asynchronous transfer of control upon completion of an entry
call or the expiration of a delay.]
Syntax
Dynamic Semantics
{
AI95-00345-01}
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].
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.
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
Example
of a main command loop for a command interpreter:
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;
Example of a
time-limited calculation:
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;
{
AI12-0098-1}
Note that these examples presume that there are abort completion points
within the execution of the
abortable_part.
Extensions to Ada 83
Extensions to Ada 95
Ada 2005 and 2012 Editions sponsored in part by Ada-Europe