Annotated Ada Reference ManualLegal Information
Contents   Index   References   Search   Previous   Next 

9.5 Intertask Communication

1
The primary means for intertask communication is provided by calls on entries and protected subprograms. Calls on protected subprograms allow coordinated access to shared data objects. Entry calls allow for blocking the caller until a given condition is satisfied (namely, that the corresponding entry is open — see 9.5.3), and then communicating data or control information directly with another task or indirectly via a shared protected object.

Static Semantics

2/3
{AI05-0225-1} {AI05-0291-1} When a name or prefix denotes an entry, protected subprogram, or a prefixed view of a primitive subprogram of a limited interface whose first parameter is a controlling parameter, the name or prefix determines a target object, as follows: 
2.a/3
To be honest: {AI05-0291-1} This wording uses "denotes" to mean "denotes a view of an entity" (when the term is used in Legality Rules), and "denotes an entity" (when the term is used in Dynamic Semantics rules). It does not mean "view of a declaration", as that would not include renames (a renames is not an entry or protected subprogram). 
3/3
{AI05-0291-1} If it is a direct_name or expanded name that denotes the declaration (or body) of the operation, then the target object is implicitly specified to be the current instance of the task or protected unit immediately enclosing the operation; a call using such a name is defined to be an internal call;
4/3
{AI05-0291-1} If it is a selected_component that is not an expanded name, then the target object is explicitly specified to be the object denoted by the prefix of the name; a call using such a name is defined to be an external call
4.a
Discussion: For example: 
4.b
protected type Pt is
  procedure Op1;
  procedure Op2;
end Pt;
4.c
PO : Pt;
Other_Object : Some_Other_Protected_Type;
4.d
protected body Pt is
  procedure Op1 is begin ... end Op1;
4.e
  procedure Op2 is
  begin
    Op1; -- An internal call.
    Pt.Op1; -- Another internal call.
    PO.Op1; -- An external call. It the current instance is PO, then
            -- this is a bounded error (see 9.5.1).
    Other_Object.Some_Op; -- An external call.
  end Op2;
end Pt;
5/3
{AI05-0291-1} If the name or prefix is a dereference (implicit or explicit) of an access-to-protected-subprogram value, then the target object is determined by the prefix of the Access attribute_reference that produced the access value originally; a call using such a name is defined to be an external call;
6
If the name or prefix denotes a subprogram_renaming_declaration, then the target object is as determined by the name of the renamed entity.
6.1/3
 {AI05-0291-1} A call on an entry or a protected subprogram either uses a name or prefix that determines a target object implicitly, as above, or is a call on (a non-prefixed view of) a primitive subprogram of a limited interface whose first parameter is a controlling parameter, in which case the target object is identified explicitly by the first parameter. This latter case is an external call.
7
A corresponding definition of target object applies to a requeue_statement (see 9.5.4), with a corresponding distinction between an internal requeue and an external requeue.

Legality Rules

7.1/3
 {AI95-00345-01} {AI05-0225-1} {AI05-0291-1} If a name or prefix determines a target object, and the name denotes a protected entry or procedure, then the target object shall be a variable, unless the prefix is for an attribute_reference to the Count attribute (see 9.9). 
7.a/3
Reason: {AI05-0225-1} The point is to prevent any calls to such a name whose target object is a constant view of a protected object, directly, or via an access value, renames, or generic formal subprogram. It is, however, legal to say P'Count in a protected function body, even though the protected object is a constant view there. 
7.b/3
Ramification: {AI05-0291-1} This rule does not apply to calls that are not to a prefixed view. Specifically a "normal" call to a primitive operation of a limited interface is not covered by this rule. In that case, the normal parameter passing mode checks will prevent passing a constant protected object to an operation implemented by a protected entry or procedure as the mode is required to be in out or out

Dynamic Semantics

8
Within the body of a protected operation, the current instance (see 8.6) of the immediately enclosing protected unit is determined by the target object specified (implicitly or explicitly) in the call (or requeue) on the protected operation. 
8.a
To be honest: The current instance is defined in the same way within the body of a subprogram declared immediately within a protected_body.
9
Any call on a protected procedure or entry of a target protected object is defined to be an update to the object, as is a requeue on such an entry. 
9.a
Reason: Read/write access to the components of a protected object is granted while inside the body of a protected procedure or entry. Also, any protected entry call can change the value of the Count attribute, which represents an update. Any protected procedure call can result in servicing the entries, which again might change the value of a Count attribute. 

Syntax

10/3
{AI05-0030-2} {AI05-0215-1} synchronization_kind ::= By_Entry | By_Protected_Procedure | Optional

Static Semantics

11/3
{AI05-0215-1} For the declaration of a primitive procedure of a synchronized tagged type the following language-defined representation aspect may be specified with an aspect_specification (see 13.1.1):
12/3
Synchronization

If specified, the aspect definition shall be a synchronization_kind.
12.a/3
Aspect Description for Synchronization: Defines whether a given primitive operation of a synchronized interface must be implemented by an entry or protected procedure.
13/3
{AI05-0030-2} {AI05-0215-1} Inherited subprograms inherit the Synchronization aspect, if any, from the corresponding subprogram of the parent or progenitor type. If an overriding operation does not have a directly specified Synchronization aspect then the Synchronization aspect of the inherited operation is inherited by the overriding operation. 

Legality Rules

14/3
{AI05-0030-2} {AI05-0215-1} The synchronization_kind By_Protected_Procedure shall not be applied to a primitive procedure of a task interface.
15/3
{AI05-0030-2} {AI05-0215-1} A procedure for which the specified synchronization_kind is By_Entry shall be implemented by an entry. A procedure for which the specified synchronization_kind is By_Protected_Procedure shall be implemented by a protected procedure. A procedure for which the specified synchronization_kind is Optional may be implemented by an entry or by a procedure (including a protected procedure).
16/3
{AI05-0030-2} {AI05-0215-1} If a primitive procedure overrides an inherited operation for which the Synchronization aspect has been specified to be By_Entry or By_Protected_Procedure, then any specification of the aspect Synchronization applied to the overriding operation shall have the same synchronization_kind.
17/3
{AI05-0030-2} In addition to the places where Legality Rules normally apply (see 12.3), these rules also apply in the private part of an instance of a generic unit. 
NOTES
18/3
18  {AI05-0030-2} {AI05-0215-1} The synchronization_kind By_Protected_Procedure implies that the operation will not block. 

Wording Changes from Ada 95

18.a/2
{AI95-00345-01} Added a Legality Rule to make it crystal-clear that the protected object of an entry or procedure call must be a variable. This rule was implied by the Dynamic Semantics here, along with the Static Semantics of 3.3, but it is much better to explicitly say it. While many implementations have gotten this wrong, this is not an incompatibility — allowing updates of protected constants has always been wrong. 

Extensions to Ada 2005

18.b/3
{AI05-0030-2} {AI05-0215-1} Added the Synchronization aspect to allow specifying that an interface procedure is really an entry or a protected procedure.

Wording Changes from Ada 2005

18.c/3
{AI05-0225-1} Correction: Clarified that the target object of any name denoted a protected procedure or entry can never be a constant (other than for the 'Count attribute). This closes holes involving calls to access-to-protected, renaming as a procedure, and generic formal subprograms. 

Contents   Index   References   Search   Previous   Next 
Ada-Europe Ada 2005 and 2012 Editions sponsored in part by Ada-Europe