9.5.4 Requeue Statements
[A
requeue_statement
can be used to complete an
accept_statement
or
entry_body,
while redirecting the corresponding entry call to a new (or the same)
entry queue.
{requeue} Such
a
requeue can be performed with or without allowing an intermediate
cancellation of the call, due to an abort or the expiration of a delay.
{preference control: See requeue}
{broadcast signal:
See requeue} ]
Syntax
requeue_statement ::= requeue entry_name [
with abort];
Name Resolution Rules
{target entry (of
a requeue_statement)} The
entry_name
of a
requeue_statement
shall resolve to denote an entry (the
target entry) that either
has no parameters, or that has a profile that is type conformant (see
6.3.1) with the profile of the innermost
enclosing
entry_body
or
accept_statement.
{type conformance (required)}
Legality Rules
If the target entry has parameters, then its profile
shall be subtype conformant with the profile of the innermost enclosing
callable construct.
{subtype conformance
(required)}
{accessibility rule
(requeue statement) [partial]} In a
requeue_statement
of an
accept_statement
of some task unit, either the target object shall be a part of a formal
parameter of the
accept_statement,
or the accessibility level of the target object shall not be equal to
or statically deeper than any enclosing
accept_statement
of the task unit. In a
requeue_statement
of an
entry_body
of some protected unit, either the target object shall be a part of a
formal parameter of the
entry_body,
or the accessibility level of the target object shall not be statically
deeper than that of the
entry_declaration.
Ramification: In the
entry_body
case, the intent is that the target object can be global, or can be a
component of the protected unit, but cannot be a local variable of the
entry_body.
Reason: These restrictions ensure that
the target object of the requeue outlives the completion and finalization
of the enclosing callable construct. They also prevent requeuing from
a nested
accept_statement
on a parameter of an outer
accept_statement,
which could create some strange "long-distance" connections
between an entry caller and its server.
Implementation Note: By disallowing certain
requeues, we ensure that the normal
terminate_alternative
rules remain sensible, and that explicit clearing of the entry queues
of a protected object during finalization is rarely necessary. In particular,
such clearing of the entry queues is necessary only (ignoring premature
Unchecked_Deallocation) for protected objects declared in a
task_body
(or created by an allocator for an access type declared in such a body)
containing one or more
requeue_statements.
Protected objects declared in subprograms, or at the library level, will
never need to have their entry queues explicitly cleared during finalization.
Dynamic Semantics
{execution (requeue
task entry) [partial]} For the execution
of a requeue on an entry of a target task, after leaving the enclosing
callable construct, the named entry is checked to see if it is open and
the requeued call is either selected immediately or queued, as for a
normal entry call (see
9.5.3).
{execution
(requeue protected entry) [partial]} For
the execution of a requeue on an entry of a target protected object,
after leaving the enclosing callable construct:
if the requeue is an internal requeue (that is,
the requeue is back on an entry of the same protected object —
see
9.5), the call is added to the queue of
the named entry and the ongoing protected action continues (see
9.5.1);
Ramification: Note that for an internal
requeue, the call is queued without checking whether the target entry
is open. This is because the entry queues will be serviced before the
current protected action completes anyway, and considering the requeued
call immediately might allow it to "jump" ahead of existing
callers on the same queue.
if the requeue is an external requeue (that is,
the target protected object is not implicitly the same as the current
object — see
9.5), a protected action
is started on the target object and proceeds as for a normal entry call
(see
9.5.3).
If the new entry named in the
requeue_statement
has formal parameters, then during the execution of the
accept_statement
or
entry_body
corresponding to the new entry, the formal parameters denote the same
objects as did the corresponding formal parameters of the callable construct
completed by the requeue. [In any case, no parameters are specified in
a
requeue_statement;
any parameter passing is implicit.]
{requeue-with-abort}
If the
requeue_statement
includes the reserved words
with abort (it is a
requeue-with-abort),
then:
if the original entry call has been aborted (see
9.8), then the requeue acts as an abort completion
point for the call, and the call is cancelled and no requeue is performed;
if the original entry call was timed (or conditional),
then the original expiration time is the expiration time for the requeued
call.
If the reserved words
with abort do not appear,
then the call remains protected against cancellation while queued as
the result of the
requeue_statement.
Ramification: This protection against
cancellation lasts only until the call completes or a subsequent requeue-with-abort
is performed on the call.
Reason: We chose to protect a requeue,
by default, against abort or cancellation. This seemed safer, since it
is likely that extra steps need to be taken to allow for possible cancellation
once the servicing of an entry call has begun. This also means that in
the absence of with abort the usual Ada 83 behavior is preserved,
namely that once an entry call is accepted, it cannot be cancelled until
it completes.
31 A requeue is permitted from a single
entry to an entry of an entry family, or vice-versa. The entry index,
if any, plays no part in the subtype conformance check between the profiles
of the two entries; an entry index is part of the
entry_name
for an entry of a family.
{subtype conformance
[partial]}
Examples
Examples of requeue
statements:
requeue Request(Medium)
with abort;
--
requeue on a member of an entry family of the current task, see 9.1
requeue Flags(I).Seize;
--
requeue on an entry of an array component, see 9.4
Extensions to Ada 83