9.5 Intertask Communication
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
{
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:
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).
{
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;
{
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;
Discussion: For example:
protected type Pt is
procedure Op1;
procedure Op2;
end Pt;
PO : Pt;
Other_Object : Some_Other_Protected_Type;
protected body Pt is
procedure Op1 is begin ... end Op1;
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;
{
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;
{
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.
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
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.
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
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.
To be honest: The current instance is
defined in the same way within the body of a subprogram declared immediately
within a
protected_body.
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.
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
Static Semantics
{
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):
Synchronization
If specified, the aspect definition shall be a
synchronization_kind.
Aspect Description for Synchronization:
Defines whether a given primitive operation of a synchronized interface
must be implemented by an entry or protected procedure.
{
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
{
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).
{
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.
{
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.
Wording Changes from Ada 95
{
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
{
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
{
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.
Ada 2005 and 2012 Editions sponsored in part by Ada-Europe