From: William FRANCK <william.franck@free.fr>
Subject: Re: How to transfer Class-Wide object to a Task ?
Date: Wed, 16 Oct 2019 22:04:41 +0200
Date: 2019-10-16T22:04:37+02:00 [thread overview]
Message-ID: <5da777d4$0$21611$426a34cc@news.free.fr> (raw)
In-Reply-To: 55cpF.815759$bv6.689110@fx04.am4
Hello Per,
Thaks for the tip !
It saved my life :-).
By using 'Ada.Containers.Indefinite_Holders'
it was possible to transfer the class-wide object from one task-entry
to another.
If some of you are interested by the 129 SLOC for the sake of sharing designs,
I will post it on this tread.
William.
PS : I didn't found any practical advantage to implement a design with
a regular FIFO as the queue will always be at it's max allocation,
waiting for writing on the file...
Thanks Dmitry for the tip!
On 2019-10-15 04:40:33 +0000, Per Sandberg said:
> 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;
next prev parent reply other threads:[~2019-10-16 20:04 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
2019-10-15 5:40 ` William FRANCK
2019-10-16 20:04 ` William FRANCK [this message]
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