9.5.1 Protected Subprograms and Protected Actions
is a subprogram declared immediately within
Protected procedures provide exclusive read-write access to the data
of a protected object; protected functions provide concurrent read-only
access to the data.
Within the body of a protected function (or a function
declared immediately within a protected_body
the current instance of the enclosing protected unit is defined to be
a constant (that is, its subcomponents may be read but not updated).
Within the body of a protected procedure (or a procedure declared immediately
within a protected_body
and within an entry_body
the current instance is defined to be a variable (updating is permitted).
The type of aspect Exclusive_Functions is Boolean. If not specified (including
by inheritance), the aspect is False.
A value of True for this aspect indicates that protected functions behave
in the same way as protected procedures with respect to mutual exclusion
and queue servicing (see below).
A protected procedure or entry is an exclusive
A protected function of a protected
is an exclusive protected operation if the Exclusive_Functions
aspect of P
For the execution of a call on
a protected subprogram, the evaluation of the name
and of the parameter associations, and any assigning back of in out
parameters, proceeds as for a normal subprogram call (see
). If the call is an internal call (see
), the body of the subprogram is executed
as for a normal subprogram call. If the call is an external call, then
the body of the subprogram is executed as part of a new protected
on the target protected object; the protected action completes
after the body of the subprogram is executed. A protected action can
also be started by an entry call (see 9.5.3
new protected action is not started on a protected object while another
protected action on the same protected object is underway, unless both
actions are the result of a call on a nonexclusive protected function.
This rule is expressible in terms of the execution resource associated
with the protected object:
a protected action on a protected object corresponds to acquiring
the execution resource associated with the protected object, either for
exclusive read-write access if the protected action is for a call on
an exclusive protected operation, or for concurrent read-only access
the protected action corresponds to releasing
the associated execution
After performing an exclusive protected operation
on a protected object, but prior to completing the associated protected
action, the entry queues (if any) of the protected object are serviced
If a parallel construct occurs within a protected
action, no new logical threads of control are created. Instead, each
element of the parallel construct that would have become a separate logical
thread of control executes on the logical thread of control that is performing
the protected action. If there are multiple such elements initiated at
the same point, they execute in an arbitrary order.
Bounded (Run-Time) Errors
During a protected action, it
is a bounded error to invoke an operation that is potentially blocking
Paragraphs 9 through
16 were moved to 9.5.
If the bounded error is detected,
Program_Error is raised. If not detected, the bounded error can result
in deadlock or a (nested) protected action on the same target object.
During a protected action, a call on a subprogram
whose body contains a potentially blocking operation is a bounded error.
If the bounded error is detected,
Program_Error is raised; otherwise, the call proceeds normally.
NOTE 1 If two tasks both try to start
a protected action on a protected object, and at most one is calling
a protected nonexclusive function, then only one of the tasks can proceed.
Although the other task cannot proceed, it is not considered blocked,
and it can be consuming processing resources while it awaits its turn.
Unless there is an admission policy (see D.4.1
in effect, there is no language-defined ordering or queuing presumed
for tasks competing to start a protected action — on a multiprocessor
such tasks can use busy-waiting; for further monoprocessor and multiprocessor
considerations, see D.3
NOTE 2 The body of a protected unit
can contain declarations and bodies for local subprograms. These are
not visible outside the protected unit.
NOTE 3 The body of a protected function
can contain internal calls on other protected functions, but not protected
procedures, because the current instance is a constant. On the other
hand, the body of a protected procedure can contain internal calls on
both protected functions and procedures.
NOTE 4 From within a protected action,
an internal call on a protected subprogram, or an external call on a
protected subprogram with a different target object is not considered
a potentially blocking operation.
NOTE 5 The aspect Nonblocking can
be specified True on the definition of a protected unit in order to reject
most attempts to use potentially blocking operations within the protected
unit (see 9.5
). The pragma
Detect_Blocking can be used to ensure that any remaining executions of
potentially blocking operations during a protected action raise Program_Error.
Examples of protected
subprogram calls (see 9.4):
E := Shared_Array.Component(M);
Ada 2005 and 2012 Editions sponsored in part by Ada-Europe