Ada Resource Association
News and resources for the Ada programming language
Annotated Ada Reference ManualLegal Information
Contents   Index   References   Search   Previous   Next 

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} ]


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

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.
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.
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. 
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_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)].
{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: 
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 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 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 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

{extensions to Ada 83} The requeue_statement is new. 

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