Version 1.2 of ai05s/ai05-0101-1.txt

Unformatted version of ai05s/ai05-0101-1.txt version 1.2
Other versions for file ai05s/ai05-0101-1.txt

!standard E.2.2(14/2)          08-09-24 AI05-0101-1/02
!standard E.2.3(14/2)
!class binding interpretation 08-05-28
!status work item 08-05-28
!status received 06-04-22
!priority Low
!difficulty Medium
!qualifier Omission
!subject Remote functions must support external streaming
!summary
The result type of a remote function must either support external streaming or be a controlling access result type.
A remote function that returns an access result type must have a controlling access result. Such a function returns a value of a remote access-to-class-wide type if the function has any controlling operands. Otherwise, a function without a controlling operand must return an access value that designates an object of a non-remote access type (a local object).
!question
E.2.2(14/2) specifies restrictions applying to the types of non-controlling formals of the primitive operations of the limited private type associated with an RACW. The same restrictions must be applied to a non-controlling result, to ensure that the returned value can be sent back to the calling partition.
E.2.3(14/2) has similar language for RCI subprograms and RAS types. This clause should be augmented to forbid functions returning a type that does not support external streaming.
!wording
Change E.2.2(14/2) as follows (this wording includes the changes of AI05-0060-1):
The primitive subprograms of the corresponding specific type shall only have access parameters if they are controlling formal parameters[;]{. The primitive functions of the corresponding specific type shall only have an access result if it is a controlling access result. E}[e]ach non-controlling formal parameter {and non-controlling result subtype} shall support external streaming (see 13.13.2);
Add a new bullet after E.2.2 (15):
* A controlling access result value for a primitive function with any controlling
operands of the corresponding specific type shall either be explicitly converted to a remote access-to-class-wide type or be part of a dispatching call where the value designates a controlling operand of the call.
Change E.2.3(14/2) as follows:
it shall not be, nor shall its visible part contain, a subprogram (or access-to-subprogram) declaration whose profile has [an access parameter or] a parameter {or result} of a type that does not support external streaming (see 13.13.2).
AARM Ramification: No anonymous access types support external streaming, so those are never allowed in RCI subprograms.
[Editor's note: I intend to delete the access parameter portion above as it is redundant and including it complicates the wording for little value.]
!discussion
Annex E provides adequate rules describing the restrictions for parameters of a remote call, but lacks clarity on describing the restrictions that should be applied to the results of remote function calls. Generally, the same rules should apply, but there are cases that need special consideration.
In the case of a non-controlling function result, the function result has to be streamed from a remote partition, so this should be clearly stated in the rules. However, E.2.2(14/2) and E.2.3 (14/2) only describe rules for parameters of remote subprogram calls; there is no mention of restrictions that apply to a remote function result type.
There is no reason why a non-controlling function result should be treated differently than non-controlling parameters. That is, it only makes sense to allow remote function calls that have a result type that supports external streaming. This rules out non-controlling access result types since anonymous access types do not support external streaming.
Special consideration needs to be given to functions that have a controlling access result however.
E.4 (5) states that a remote subprogram call can be executed as “a dispatching call with a controlling operand designated by a value of a remote access-to-class-wide type.”
3.9.2 (2/2) states that “a controlling operand in a call on a dispatching operation of a tagged type T is one whose corresponding formal parameter is of type T or is of an anonymous access type with designated type T”.
If controlling anonymous access parameters of dispatching subprograms can be designated by a value of a remote access-to-class-wide type, it seems logical that a controlling access result of a dispatching function should be treated the same way; as a result type that can be designated by a value of a remote access-to-class-wide type. Indeed, there does not seem to be any other semantic meaning that could be applied to such an access result returned from a remote function call. It surely must be a value of a remote access-to-class-wide type.
However, 13.13.2 (52/2) states that “an anonymous access type does not support external streaming”, so if we are to allow streaming of a remote access-to-class-wide type as a controlling access result, then special wording will need to be added to the RM to allow this, similar to the wording used to allow streaming of remote access-to-class-wide types for subprogram parameters. The wording should should add restrictions that ensure such a result is either explicitly converted to a remote access-to-class-wide type by the caller, or used as a controlling operand of another dispatching call to a remote subprogram.
There is a further distinction that needs to be observed. E.4 (5) stated above that a dispatching function call with a controlling operand is a remote subprogram call. A dispatching function call that does not have a controlling operand is not a remote subprogram call. The controlling access result returned by such a function should be treated as a value of a local anonymous access type. This is enforced by E.2.2 (15) which states “A value of a remote access-to-class-wide type shall be explicitly converted only to another remote access-to-class-wide type” and by E.2.2(16/1) which states that “A value of a remote access-to-class-wide type shall be dereferenced (or implicitly converted to an anonymous access type) only as part of a dispatching call where the value designates a controlling operand of the call”.
These rules makes it impossible for a local function to obtain a value of a remote access-to-class-wide type and return it to the caller, because it would have to be implictly converted from an access-to-class-wide type to an anonymous access-to-specific type of the controlling result, which is not allowed. For the same reason, these rules makes it impossible for a remote function to obtain a value of a remote access-to-class-wide type from another partition and return that value to the caller.
package P is pragma Remote_Types;
type T is tagged limited private;
function Remote_Call (Controlling_Operand : access T) return access T; function Local_Call return access T;
private type T is tagged limited null record; end P;
with Distributed_P;
package body P is
Foo : aliased T;
function Local_Call return access T is begin -- return Distributed_P.Get_Foo; -- illegal E.2.2 (16/1) return Foo'access; -- OK end Local_Call;
function Remote_Call (Controlling_Operand : access T) return access T is pragma Unreferenced (Controlling_Operand); begin -- return Distributed_P.Get_Foo; -- illegal E.2.2 (16/1) return Foo'access; -- OK
end Remote_Call;
end Foo_Pkg;
with P;
package Distributed_P is
pragma Remote_Call_Interface;
type T_Access is access all P.T'Class;
procedure Set_Foo (Item : T_Access);
function Get_Foo return T_Access; end Distributed_P;
package body Distributed_P is
Remote_Foo : T_Access;
function Get_Foo return T_Access is begin return Remote_Foo; end Get_Foo;
procedure Set_Foo (Item : T_Access) is begin Remote_Foo := Item; end Set_Foo;
end Distributed_P;
with P; with Distributed_P;
procedure Test_Function_Access_Return is My_Foo : aliased P.T;
-- 1) Function returns local RACW value that must be explicity converted -- to a RACW Remote : constant Distributed_P.T_Access -- Legal Conversion? (Yes) := Distributed_P.T_Access (P.Remote_Call (My_Foo'access));
begin
-- Send the local RACW off to some remote location Distributed_P.Set_Foo (Remote);
declare -- 2) Function returns local access value that is optionally converted -- to a RACW Local : constant Distributed_P.T_Access := Distributed_P.T_Access (P.Local_Call);
-- 3) Same call as 2) but not converted to a RACW Local2 : constant access P.T := P.Local_Call;
-- 4) First call returns RACW that dispatches to same remote partition -- returning a controlling access result from that partition that -- must be explicitly converted to a RACW Remote2 : constant Distributed_P.T_Access := Distributed_P.T_Access (P.Remote_Call (P.Remote_Call (Distributed_P.Get_Foo))); begin null; end;
end Test_Function_Access_Return;
--!corrigendum E.2.2(14/2)
!ACATS Test
!appendix

!topic Return type of remote function should support external streaming
!reference Ada 2005 E.2.2(14/2), E.2.3(14/2)
!from Thomas Quinot 08-04-22
!keywords distributed systems, return type, support external streaming
!discussion

E.2.2(14/2) specifies restrictions applying to the types of non-controlling
formals of the primitive operations of the limited private type associated
with an RACW. The same restrictions must be applied to a non-controlling
result, to ensure that the returned value can be sent back to the
calling partition. (The case of controlling access results is an annoying
irregularity since these can't support external streaming (being anonymous
access types). Maybe a special exception should be added for those).

E.2.3(14/2) has similar language for RCI subprograms and RAS types.
This clause should be augmented to forbid functions returning a type that
does not support external streaming.

****************************************************************

From: Tucker Taft
Sent: Tuesday, April 22, 2008  7:15 AM

Good point about the non-controlling result.
But I don't follow your point about the
controlling access result.  I would have said that a controlling
(non-access) result needs to support external streaming, whereas with
a controlling *access* result, the restriction would be that it *must*
be converted to a RACW upon return, since it can't be a "normal"
access value.

****************************************************************

From: Thomas Quinot
Sent: Tuesday, April 22, 2008  7:41 AM

> But I don't follow your point about the controlling access result.  I 
> would have said that a controlling (non-access) result needs to 
> support external streaming,

Sounds reasonable, but this is not currently explicit in the RM.

> whereas with
> a controlling *access* result, the restriction would be that it *must* 
> be converted to a RACW upon return, since it can't be a "normal"
> access value.

... and can't support external streaming. Which is why I mentioned we
might need a separate rule explicitly making it compulsory to convert
such a controlling access result to an RACW.

****************************************************************



Questions? Ask the ACAA Technical Agent