comp.lang.ada
 help / color / mirror / Atom feed
From: Philippe Tarroux <philippe.tarroux@limsi.fr>
Subject: Concurrency and interfaces
Date: Mon, 28 Jan 2008 16:34:14 +0100
Date: 2008-01-28T16:34:14+01:00	[thread overview]
Message-ID: <fnksin$gvs$1@news2.u-psud.fr> (raw)

Hi everybody,

I try to explore the Ada05 interfaces in the context of concurrency. My 
original question was to explore different solutions for the following 
problem:

How to connect a task (T2) to other tasks (T11 or T12) having different 
functionalities depending on a given context.

I abstracted the following code :

package Test_Interfaces is

   type Int1 is synchronized interface;
   procedure Init (I1 : in out Int1) is abstract;
 
   type Int1_Ptr is access Int1'Class;

   type Int2 is synchronized interface;
   procedure Process(I1 : in out Int2) is abstract;

   task type T11 is new Int1 with
      entry Init;
   end T11;

   task type T12 is new Int1 and Int2 with
      entry Init;
      entry Process;  -- Some additional functionalities
   end T12;
 
   task type T2 is
      entry Connect (T : Int1'Class);
   end T2;
     
end Test_Interfaces;

with Text_Io;
use Text_Io;

package body Test_Interfaces is

   task body T11 is
   begin
      accept Init do
     Put ("Init T11"); New_Line;
      end Init;
      loop
     delay 0.5;
     Put ("Process T11"); New_Line;
      end loop;
   end T11;

   task body T12 is
   begin
      accept Init do
     Put ("Init T12"); New_Line;
      end Init;
      loop
         select
         delay 0.1;
            Put ("Process T12"); New_Line;
         or
            accept Process; -- some extra processing
          end select;
        end loop;
   end T12;
 
   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);
      end Connect;
      Int_Task.Init;
   end T2;

end Test_Interfaces;

Then the main program:

with Test_Interfaces;
use Test_Interfaces;

procedure test_tasking is 
   Task11 : T11;
   Task12 : T12;
  
   Task2 : T2;
begin
   Task2.Connect (Task12);
end test_tasking;

In this case, the program is blocked in the Connect call.

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.

When I replace the declaration of Int_Task in task body T2 by Int_Task : 
access Int1'class; the builder raises the following error:

undefined reference to 'test_interface__t2___master'

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;
      end Connect;
      Int_Task.Init;
   end T2;

...
with Test_Interfaces;
use Test_Interfaces;

procedure test_tasking is 
   Task11 : Int1_Ptr := new T11;
   Task12 : Int1_Ptr := new T12;
  
   Task2 : T2;
begin
   Task2.Connect (Task11);  -- or Task2.Connect(Task12);
end test_tasking;

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.

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

Any idea?

Philippe Tarroux
philippe.tarroux@limsi.fr

OS : WXP
Ada compiler : gcc 4.1.3 20070403 for GNAT GPL 2007 (20070402)









             reply	other threads:[~2008-01-28 15:34 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-01-28 15:34 Philippe Tarroux [this message]
2008-01-29 13:37 ` Concurrency and interfaces Stephen Leake
replies disabled

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox