E.4 Remote Subprogram Calls
A 
remote subprogram call is a subprogram call that invokes the execution 
of a subprogram in another partition. The partition that originates the 
remote subprogram call is the 
calling partition, and the partition 
that executes the corresponding subprogram body is the 
called partition. 
Some remote procedure calls are allowed to return prior to the completion 
of subprogram execution. These are called 
asynchronous remote procedure 
calls.
 
There are three different 
ways of performing a remote subprogram call: 
As a direct call on a (remote) subprogram explicitly 
declared in a remote call interface;
As an indirect call through a value of a remote 
access-to-subprogram type;
As a dispatching call with a controlling operand 
designated by a value of a remote access-to-class-wide type. 
The first way of calling corresponds to a static 
binding between the calling and the called partition. The latter two 
ways correspond to a dynamic binding between the calling and the 
called partition.
Remote types library units (see 
E.2.2) 
and remote call interface library units (see 
E.2.3) 
define the remote subprograms or remote access types used for remote 
subprogram calls. 
 
Legality Rules
In a dispatching call with two or more controlling 
operands, if one controlling operand is designated by a value of a remote 
access-to-class-wide type, then all shall be. 
Dynamic Semantics
For 
the execution of a remote subprogram call, subprogram parameters (and 
later the results, if any) are passed using a stream-oriented representation 
(see 
13.13.1) which is suitable for transmission 
between partitions. This action is called 
marshalling. 
Unmarshalling 
is the reverse action of reconstructing the parameters or results from 
the stream-oriented representation. Marshalling is performed initially 
as part of the remote subprogram call in the calling partition; unmarshalling 
is done in the called partition. After the remote subprogram completes, 
marshalling is performed in the called partition, and finally unmarshalling 
is done in the calling partition.
 
A 
calling 
stub is the sequence of code that replaces the subprogram body of 
a remotely called subprogram in the calling partition. A 
receiving 
stub is the sequence of code (the “wrapper”) that receives 
a remote subprogram call on the called partition and invokes the appropriate 
subprogram body. 
 
Remote subprogram calls are executed 
at most once, that is, if the subprogram call returns normally, then 
the called subprogram's body was executed exactly once.
 
The task executing a remote subprogram call blocks 
until the subprogram in the called partition returns, unless the call 
is asynchronous. For an asynchronous remote procedure call, the calling 
task can become ready before the procedure in the called partition returns.
If a construct containing a remote 
call is aborted, the remote subprogram call is 
cancelled. Whether 
the execution of the remote subprogram is immediately aborted as a result 
of the cancellation is implementation defined. 
 
If a remote subprogram call is received by a called 
partition before the partition has completed its elaboration, the call 
is kept pending until the called partition completes its elaboration 
(unless the call is cancelled by the calling partition prior to that).
If an exception is propagated by a remotely called 
subprogram, and the call is not an asynchronous call, the corresponding 
exception is reraised at the point of the remote subprogram call. For 
an asynchronous call, if the remote procedure call returns prior to the 
completion of the remotely called subprogram, any exception is lost.
The exception Communication_Error (see 
E.5) 
is raised if a remote call cannot be completed due to difficulties in 
communicating with the called partition.
 
All forms 
of remote subprogram calls are potentially blocking operations (see 
9.5.1). 
 
 In a remote 
subprogram call with a formal parameter of a class-wide type, a check 
is made that the tag of the actual parameter identifies a tagged type 
declared in a declared-pure or shared passive library unit, or in the 
visible part of a remote types or remote call interface library unit. 
Program_Error is raised if this check fails. In a 
remote function call which returns a class-wide type, the same check 
is made on the function result. 
 
In a dispatching 
call with two or more controlling operands that are designated by values 
of a remote access-to-class-wide type, a check is made (in addition to 
the normal Tag_Check — see 
11.5) that 
all the remote access-to-class-wide values originated from Access 
attribute_references 
that were evaluated by tasks of the same active partition. 
Constraint_Error 
is raised if this check fails. 
 
Implementation Requirements
The implementation of remote subprogram calls shall 
conform to the PCS interface as defined by the specification of the language-defined 
package System.RPC (see 
E.5). The calling stub 
shall use the Do_RPC procedure unless the remote procedure call is asynchronous 
in which case Do_APC shall be used. On the receiving side, the corresponding 
receiving stub shall be invoked by the RPC-receiver. 
 
   With respect to shared variables in shared passive 
library units, the execution of the corresponding subprogram body of 
a synchronous remote procedure call is considered to be part of the execution 
of the calling task. The execution of the corresponding subprogram body 
of an asynchronous remote procedure call proceeds in parallel with the 
calling task and does not signal the next action of the calling task 
(see 
9.10). 
 
8  A given active partition can both make 
and receive remote subprogram calls. Thus, an active partition can act 
as both a client and a server.
9  If a given exception is propagated by 
a remote subprogram call, but the exception does not exist in the calling 
partition, the exception can be handled by an others choice or 
be propagated to and handled by a third partition. 
Ada 2005 and 2012 Editions sponsored in part by Ada-Europe