9.5.1 Protected Subprograms and Protected Actions
A 
protected subprogram is a subprogram declared immediately within 
a 
protected_definition. 
Protected procedures provide exclusive read-write access to the data 
of a protected object; protected functions provide concurrent read-only 
access to the data. 
 
Static Semantics
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). 
 
  Exclusive_Functions
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 
protected operation.
 A protected function of a protected 
type 
P is an exclusive protected operation if the Exclusive_Functions 
aspect of 
P is True.
 
Dynamic Semantics
For the execution of a call on 
a protected subprogram, the evaluation of the 
name 
or 
prefix 
and of the parameter associations, and any assigning back of 
in out 
or 
out parameters, proceeds as for a normal subprogram call (see 
6.4). If the call is an internal call (see 
9.5), 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 
action 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).
 
A 
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: 
 
Starting 
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 
otherwise;
 
Completing 
the protected action corresponds to 
releasing the associated execution 
resource. 
 
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 
(see 
9.5.3). 
 
Bounded (Run-Time) Errors
During 
a protected action, it is a bounded error to invoke an operation that 
is 
potentially blocking. 
The 
following are defined to be potentially blocking operations: 
 
task creation or activation;
an external call on a protected subprogram (or 
an external requeue) with the same target object as that of the protected 
action; 
a call on a subprogram whose body contains a potentially 
blocking operation. 
If the bounded error is detected, 
Program_Error is raised. If not detected, the bounded error might result 
in deadlock or a (nested) protected action on the same target object.
 
Certain language-defined subprograms are potentially 
blocking. In particular, the subprograms of the language-defined input-output 
packages that manipulate files (implicitly or explicitly) are potentially 
blocking. Other potentially blocking subprograms are identified where 
they are defined. When not specified as potentially blocking, a language-defined 
subprogram is nonblocking. 
19  If two tasks both try to start a protected 
action on a protected object, and at most one is calling a protected 
function, then only one of the tasks can proceed. Although the other 
task cannot proceed, it is not considered blocked, and it might be consuming 
processing resources while it awaits its turn. There is no language-defined 
ordering or queuing presumed for tasks competing to start a protected 
action — on a multiprocessor such tasks might use busy-waiting; 
for monoprocessor considerations, see 
D.3, 
“
Priority Ceiling Locking”. 
 
20  The body of a protected unit may contain 
declarations and bodies for local subprograms. These are not visible 
outside the protected unit.
21  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.
22  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. 
23  The 
pragma 
Detect_Blocking may be used to ensure that all executions of potentially 
blocking operations during a protected action raise Program_Error. See 
H.5. 
 
Examples
Examples of protected 
subprogram calls (see 9.4):  
Shared_Array.Set_Component(N, E);
E := Shared_Array.Component(M);
Control.Release;
Ada 2005 and 2012 Editions sponsored in part by Ada-Europe