comp.lang.ada
 help / color / mirror / Atom feed
* Concurrency and interfaces
@ 2008-01-28 15:34 Philippe Tarroux
  2008-01-29 13:37 ` Stephen Leake
  0 siblings, 1 reply; 2+ messages in thread
From: Philippe Tarroux @ 2008-01-28 15:34 UTC (permalink / 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)









^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2008-01-29 13:37 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-01-28 15:34 Concurrency and interfaces Philippe Tarroux
2008-01-29 13:37 ` Stephen Leake

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