9.5.4 Requeue Statements
can be used to complete an accept_statement
while redirecting the corresponding entry call to a new (or the same)
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.
requeue_statement ::= requeue procedure_or_entry_name
Name Resolution Rules
of a requeue_statement
shall resolve to denote a procedure or an entry (the requeue target
The profile of the entry, or the profile or prefixed profile of the procedure,
shall either have no parameters, or be type conformant (see 6.3.1
with the profile of the innermost enclosing entry_body
If the requeue target has parameters, then its (prefixed) profile shall
be subtype conformant with the profile of the innermost enclosing callable
Given a requeue_statement where the innermost enclosing
callable construct is for an entry E1, for every [specific or
class-wide ]postcondition expression P1 that applies to E1,
there shall exist a postcondition expression P2 that applies to
the requeue target E2 such that
P1 is fully conformant
with the expression produced by replacing each reference in P2
to a formal parameter of E2 with a reference to the corresponding
formal paramter of E1; and
if P1 is enabled,
then P2 is also enabled.
speaking, the postcondition of the requeue target is required to imply
that of the enclosing callable construct.
If the requeue target is declared immediately within
of a named task type or the protected_definition
of a named protected type, and if the requeue statement occurs within
the body of that type, and if the requeue is an external requeue, then
the requeue target shall not have a specific or class-wide postcondition
which includes a name denoting either the current instance of that type
or any entity declared within the declaration of that type.
above pair of rules always apply; they don't depend on whether or not
any of the postconditions are enabled.
If the target is a procedure, the name shall denote a renaming of an
entry, or shall denote a view or a prefixed view of a primitive subprogram
of a synchronized interface, where the first parameter of the unprefixed
view of the primitive subprogram shall be a controlling parameter, and
the Synchronization aspect shall be specified with synchronization_kind
By_Entry for the primitive subprogram.
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
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.
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_statement
Protected objects declared in subprograms, or at the library level, will
never need to have their entry queues explicitly cleared during finalization.
is evaluated. This includes evaluation of the prefix
(if any) identifying the target task or protected object and of the expression
(if any) identifying the entry within an entry family.
If the target object is not a part of a formal
parameter of the innermost enclosing callable construct, a check is made
that the accessibility level of the target object is not equal to or
deeper than the level of the innermost enclosing callable construct.
If this check fails, Program_Error is raised.
Precondition checks are performed as for a call
to the requeue target.
enclosing the requeue_statement
is then completed[, finalized, and left (see 7.6.1)].
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
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 —
), 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
If the requeue target named in the requeue_statement
has formal parameters, then during the execution of the accept_statement
corresponding to the new entry and during the checking
of any preconditions of 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.]
includes the reserved words with abort
(it is a requeue-with-abort
if the original entry call has been aborted (see
), 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
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
A requeue is permitted from a single entry to an entry of an entry family,
or vice -
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
for an entry of a family.
Examples of requeue
Request(Medium) with abort
-- requeue on a member of an entry family of the current task, see 9.1
-- requeue on an entry of an array component, see 9.4
Extensions to Ada 83
Extensions to Ada 2005
Added the ability to requeue on operations of synchronized
interfaces that are declared to be an entry.
Inconsistencies With Ada 2012
Corrigendum: We now
define that any preconditions of the requeue target are evaluated as
part of a requeue_statement.
Original Ada 2012 did not specify this, so a program that requeues when
the preconditions fail will raise an exception when none would happen
in original Ada 2012. We don't expect this to be a problem, as in that
case, the entry body would be called with some of its preconditions evaluating
as False; the body is likely to assume that they are true and probably
will have failed in some other way anyway.
Correction: We now include an accessibility
check on requeues. This means Program_Error could be raised for a requeue
that worked in Ada 2012. This can only fail for an object for which the
statically deeper relationship does not apply, for instance a stand-alone
object of an anonymous access type. Most programs that are affected are
erroneous anyway (as they will eventually use a nonexistent object),
so we do not elieve this will matter in practice.
Incompatibilities With Ada 2012
Corrigendum: If a requeue
target has a different postcondition than the original entry, the requeue
is now illegal. In such a case, the original postcondition would never
have been evaluated, and assumptions that the caller relied upon might
not be true. A requeue should be invisible to the caller with respect
to any postconditions; thus we only allow it when the original entry
has no postconditions or the requeue target has (at least) the same postconditions.
Wording Changes from Ada 2012
Ada 2005 and 2012 Editions sponsored in part by Ada-Europe