Concurrence et interfaces

Philippe Tarroux <[email protected]>
Newsgroups gmane.comp.lang.ada.france
Message-ID <[email protected]>
Bonjour à tous,

j'ai posté sur comp.lan.ada la question suivantye que je reposte ici à 
la fois parce qu'elle peut intéresser les lecteurs de cette liste qui ne 
fréquentent pas forcément comp.la,g.ada.

J'ai exploré le problème suivant: comment passer à une tâche une autre 
tâche qui diffère selon le contexte par certaines fonctionnalités. Les 
fonctionnalités de ces dernières sont définies par héritage et je 
pensais que passer un type à l'échelle de classe suffirait pour régler 
le problème. J'ai rencontré plusieurs difficultés.

Voila le code minimal que j'ai écrit:

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;

Puis le programme principal:

with Test_Interfaces;
use Test_Interfaces;

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

Avec ce code le programme est bloqué dans l'appel à Connect.

Quand on utilise Task11 à la place de Task12, j'obtiens un POGRAM ERROR 
: unhanded signal.

Je ne comprends pas pourquoi ces deux situations ne sont pas symétriques.

Quand on remplace la déclaration de Int_Task dans le corps de T2 par 
Int_Task : access Int1'class; on obtient une erreur au niveau du builder:

undefined reference to 'test_interface__t2___master'

Quand Int1'class est remplacé par 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;

tout marche correctement.

je suspecte une erreur au niveau de l'usage de Int1'Class mal gérée par 
le compilateur.

J'en conclue qu'on ne peut pas se passer du pointeur Int1_Ptr.

Quelqu'un a t il une idée?

Philippe Tarroux
[email protected]

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








_______________________________________________
Site WWW de l'association Ada-France: http://www.ada-france.org/
[email protected]
http://www.ada-france.org/mailman/listinfo/ada-france
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.