Re: Concurrency and interfaces



Philippe Tarroux <philippe.tarroux@xxxxxxxx> writes:

package Test_Interfaces is

type Int1 is synchronized interface;
<snip>

package body Test_Interfaces is

<snip>
task body T2 is
Int_Task : Int1_Ptr;
begin
accept Connect (T : Int1'Class) do
Put("External task connection"); New_Line;
Int_Task := new Int1'Class'(T);

This is illegal; you are allocating an object of type Int1, and
initializing it. But synchronized types are limited (ARM 3.9.4 (5)),
so you can't do that.

The compiler doesn't recognize that the code is illegal; that's a
compiler bug.

With GNAT 6.1.0w, I get:

test_interfaces.adb:39:22: initialization not allowed for limited types

When Task11 is used instead Task12, I get a PROGRAM ERROR : unhanded
signal. I dont understand why these two situations are not symmetrical
and give rise to different behaviors.

Since the compiler has a bug, it's not surprising it generates buggy
code :).

When I replace Int1'class by Int1_Ptr :

...
task type T2 is
entry Connect (T : Int1_Ptr);
end T2;
...

task body T2 is
Int_Task : Int1_Ptr;
begin
accept Connect (T : Int1_Ptr) do
Put("External task connection"); New_Line;
Int_Task := T;

Now this is legal; you are copying a pointer.

end Connect;
Int_Task.Init;
end T2;

all runs correctly.

I suspect the conjunction of a faulty construct at the level of the
affectation Int_Task := new Int1'Class'(T); incorrectly handled by the
compiler but i don't really understand why this construct is
illegal.

The short answer is "Int1 is limited". The reason it's limited is that
it might be a task, and tasks are limited, because what would it mean
to copy a task?

In the statement

Int_Task := new Int1'Class'(T);

are you trying to create a new task, or just get a reference to an
existing one?

If you want a reference, then passing in the pointer is necessary.

If you are trying to create a new one, then you need some sort of
factory, and you _don't_ want to create a task in the test_tasking
main program.

Your initial problem statement sounded more like you wanted a
reference, not to create a new task.

I conclude that there is no way to hide the use of the pointer
Int1_Ptr and probably no way to do that statically.

Right. But that's good; the semantics of your program requires a
reference, so you should declare a reference.

--
-- Stephe
.