comp.lang.ada
 help / color / mirror / Atom feed
From: Per Sandberg <per.s.sandberg@bahnhof.se>
Subject: Re: How to transfer Class-Wide object to a Task ?
Date: Tue, 15 Oct 2019 06:40:33 +0200
Date: 2019-10-15T06:40:33+02:00	[thread overview]
Message-ID: <55cpF.815759$bv6.689110@fx04.am4> (raw)
In-Reply-To: <5da4e182$0$20321$426a74cc@news.free.fr>

Why not use Ada.Containers.Indefinite_holders to encapsulate the 
Classwide type during store?
----------------
with ADA.Containers.Indefinite_Holders;
package Demo is
    type T1 is interface;
    package T1_Holders is new ADA.Containers.Indefinite_Holders (T1'Class);

    task type Storage_Task is
       entry Internal_Store (D : in T1_Holders.Holder);
       entry Internal_Fetch (D : out T1_Holders.Holder);
    end Storage_Task;

    procedure Store (S : Storage_Task; Var : in Demo.T1'Class );
    Function Fetch(S : Storage_Task) return Demo.T1'Class;
end Demo;
---------------------
package body Demo is
    procedure Store (S : Storage_Task; Var : in Demo.T1'Class ) is
       H : Demo.T1_Holders.Holder;
    begin
       H.Replace_Element (Var);
       S.Internal_Store(H);
    end Store;
    Function Fetch(S : Storage_Task) return Demo.T1'Class is
       H : Demo.T1_Holders.Holder;
    begin
       S.Internal_Fetch (H);
       return H.Element;
    end Fetch;

    task body Storage_Task is
       S : T1_Holders.Holder;
    begin
       loop
          select
             accept Internal_Fetch (D : out T1_Holders.Holder)  do
                D := S;
             end Internal_Fetch;
          or accept Internal_Store (D : in T1_Holders.Holder) do
                S := D;
             end Internal_Store;
          or
             terminate;
          end select;
       end loop;
    end Storage_Task;
end Demo;
---------------------
/P

On 2019-10-14 22:58, William FRANCK wrote:
> On 2019-10-14 19:58:34 +0000, Dmitry A. Kazakov said:
> 
>> On 2019-10-14 21:41, William FRANCK wrote:
>>
>>> Here is a nice issue I have with Ada (GNAT 2012) when trying to do OO 
>>> dispatching with streams in different tasks ...
>>>
>>> Here it is :
>>> I'd like to get from a task RdV (Entry-Access) an object which could 
>>> be any subclass of a root'Class, and pass it to another task
>>>
>>> Context : read (Root'Class'Input() ) tagged records from an input 
>>> stream, and send them to anther task which will write 
>>> (Root'Class'Output() ) the given records to another output stream.
>>
>> Strange design, why not to pipe streams using a FIFO?
>>
>>> I'm stuck with task memory isolation with does NOT allow to pass any 
>>> access object to a Root'Class.
>>>
>>> Should I try to use a protected object ?
>>> (not shore this solves the passing of a Class-wide object ...)
>>
>> Yes, if using FIFO, a protected object can be used to signal 
>> non-empty/not-full events at the FIFO ends.
>>
>> Otherwise, use a reference-counted handle or a plain access type to 
>> the target object. The reader task allocates the object in the pool 
>> and passes a handle or access to it to the writer. The writer task 
>> writes the object and then disposes it.
> 
> Thanks you Dimitry for your follow-up.
> 
> Here is the multitasking part (simplified) (working, no issue)
> for reading the datafile, and writing it back (after some data-process)
> 
> My first intention was : while Writing.Bloc is busy writing on the 
> output file, Reading.Bloc can take 1 record in advance
> 
> Now I have to insert the class-wide object passing in the Bloc.
> 
> As You mentionned, should I use a protected type (FIFO)  instead of 2 // 
> tasks ?
> 
> --================
> with Ada.Text_io;
> 
> procedure main_tasks is
> 
>    task reading is
>       entry Open;
>       entry Bloc;
>       entry Stop;
>    end reading;
> 
>    task  writing is
>       entry Create;
>       entry Bloc;
>       entry Stop;
>    end writing;
> 
>    task body reading is
>    begin
>       loop
>          select
>             accept Open;
>                Ada.Text_IO.put_line("Opening file ...");
>          or
>             accept Bloc do
>                Ada.Text_IO.put_line("Reading ...");
>             end Bloc;
>          or
>             accept Stop;
>             Ada.Text_IO.put_line("Reading Stopped !");
>             exit;
>          end select;
>       end loop;
>    end reading;
> 
>    task body writing is
>    begin
>       loop
>       select
>          accept Create;
>          Ada.Text_IO.put_line("Creating file ...");
>          or
>             accept Bloc do
>                Ada.Text_IO.put_line("Got bloc !");
>             end Bloc;
>             Ada.Text_IO.put_line("Writing bloc ...");
>          or
>             accept Stop;
>             Ada.Text_IO.put_line("Writing Stopped !");
>             exit;
>          end select;
>       end loop;
>    end writing;
> 
> begin
> 
>    Writing.Create;
>    Reading.Open;
>    for i in 1..10 loop -- While not end_of_file()
>       Reading.Bloc;
>       Writing.Bloc;
>    end loop;
> 
>    Reading.Stop;
>    Writing.Stop;
> 
> end main_tasks;
> 


  reply	other threads:[~2019-10-15  4:40 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-10-14 19:41 How to transfer Class-Wide object to a Task ? William FRANCK
2019-10-14 19:55 ` Shark8
2019-10-14 20:48   ` William FRANCK
2019-10-14 22:01     ` Shark8
2019-10-15  5:13       ` William FRANCK
2019-10-14 19:58 ` Dmitry A. Kazakov
2019-10-14 20:58   ` William FRANCK
2019-10-15  4:40     ` Per Sandberg [this message]
2019-10-15  5:40       ` William FRANCK
2019-10-16 20:04       ` William FRANCK
2019-10-16 23:43         ` Anh Vo
2019-10-17  9:28         ` William FRANCK
2019-10-17 10:00           ` Dmitry A. Kazakov
2019-10-17 10:45             ` William FRANCK
2019-10-15  7:21     ` Dmitry A. Kazakov
2019-10-15 14:31       ` Optikos
2019-10-15 19:41         ` William FRANCK
2019-10-15 20:03           ` Shark8
2019-10-14 20:21 ` William FRANCK
2019-10-14 20:32   ` Dmitry A. Kazakov
2019-10-14 21:04     ` William FRANCK
2019-10-14 21:57   ` Shark8
2019-10-15  5:43     ` William FRANCK
replies disabled

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