Contents Index Search Previous Next
9.5.4 Requeue Statements
1
[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
2
requeue_statement
::= requeue entry_name [
with abort];
Name Resolution Rules
3
{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
4
A requeue_statement
shall be within a callable construct that is either an entry_body
or an accept_statement, and this
construct shall be the innermost enclosing body or callable construct.
5
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)}
6
{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.
6.a
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.
6.b
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.
6.c
Note that in the strange case
where a task_body is nested inside
an accept_statement, it is permissible
to requeue from an accept_statement
of the inner task_body on parameters
of the outer accept_statement. This
is not a problem because all calls on the inner task have to complete
before returning from the outer accept_statement,
meaning no "dangling calls" will be created.
6.d
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
7
{execution (requeue_statement)
[partial]} The execution of a
requeue_statement
proceeds by first evaluating the
entry_name[,
including the
prefix identifying
the target task or protected object and the
expression
identifying the entry within an entry family, if any]. The
entry_body
or
accept_statement enclosing the
requeue_statement is then completed[,
finalized, and left (see
7.6.1)].
8
{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).
9
{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:
10
- 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);
10.a
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.
11
- 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).
12
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.]
13
{requeue-with-abort}
If the
requeue_statement
includes the reserved words
with abort (it is a
requeue-with-abort),
then:
14
- 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;
15
- if the original entry call was timed
(or conditional), then the original expiration time is the expiration
time for the requeued call.
16
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.
16.a
Ramification: This protection
against cancellation lasts only until the call completes or a subsequent
requeue-with-abort is performed on the call.
16.b
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.
17
30 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
18
Examples of
requeue statements:
19
requeue Request(Medium) with abort;
-- requeue on a member of an entry family of the current task, see 9.1
20
requeue Flags(I).Seize;
-- requeue on an entry of an array component, see 9.4
Extensions to Ada 83
20.a
{extensions to Ada 83}
The requeue_statement
is new.
Contents Index Search Previous Next Legal