comp.lang.ada
 help / color / mirror / Atom feed
From: Shark8 <onewingedshark@gmail.com>
Subject: Re: Tasks, Entries, and Variables of a Class-wide type
Date: Mon, 1 Nov 2010 08:30:42 -0700 (PDT)
Date: 2010-11-01T08:30:42-07:00	[thread overview]
Message-ID: <3dcee4c7-9753-41a1-8181-6e7e363bfbe8@t13g2000yqm.googlegroups.com> (raw)
In-Reply-To: ckmpf7cxf86x$.123uob2jwdt0z$.dlg@40tude.net

On Nov 1, 3:21 am, "Dmitry A. Kazakov" <mail...@dmitry-kazakov.de>
wrote:
> On Sun, 31 Oct 2010 22:40:37 -0700 (PDT), Shark8 wrote:
> > I¢d originally wanted to have something like this:
>
> > Task Type Parser_Task is
> >  Entry Parse( Input : in out String ) Return PostScript_Object¢Class;
> > End Parser;
>
> This does not make sense, because it would parse during a rendezvous.

Crap; you're right!
While I certainly like the idea of having a task-construct within the
language itself, I'm still quite new to using them in-practice.
Thanks for pointing that out.

> So
> the effect on the caller would be same as if the caller would parse on its
> own context. Why not to make parsing a plain function then?

See above; programmer error due to not [fully] understanding the tool
he's using.

>
> In order to take an advantage of tasking it should be like:
>
> task type Parser_Task is
>    entry Request_Parsing (Input : String);
>    entry Wait_For_Result (Output : out Post_Script_Object);
> end Parser;
>

[SNIP]

>
> What you could do is to use the generic dispatching constructor (ARM 3.9).
> Here is the outline:
>
>    package Parsers is
>       type Parser_Task;
>       type Post_Script_Object is tagged null record;
>       function Constructor (Parser : not null access Parser_Task)
>          return Post_Script_Object;
>       task type Parser_Task is
>          entry Request (Input : String);
>          entry Wait_For_Result (Output : out Tag);
>          entry Get_Result (Output : out Post_Script_Object'Class);
>       end Parser_Task;
>       function Get_Object is
>          new Ada.Tags.Generic_Dispatching_Constructor
>              (Post_Script_Object, Parser_Task, Constructor);
>    end Parsers;
>
> The implementation:
>
>    package body Parsers is
>       function Constructor (Parser : not null access Parser_Task)
>          return Post_Script_Object is
>       begin
>          return Result : Post_Script_Object do
>             Parser.Get_Result (Result);
>          end return;
>       end Constructor;
>
>       task body Parser_Task is
>          Source : Unbounded_String;
>       begin
>          loop
>             select
>                accept Request (Input : String) do
>                   Source := To_Unbounded_String (Input);
>                end Request;
>             or terminate;
>             end select;
>             -- Here we parsing the stuff in Source. It will create all
>             -- sorts of objects derived from Post_Script_Object.
>             -- For example:
>             declare
>                Result : Post_Script_Object'Class :=
>                   Post_Script_Object'(null record);
>             begin
>                accept Wait_For_Result (Output : out Tag) do
>                   Output := Result'Tag;
>                end Wait_For_Result;
>                accept Get_Result (Output : out Post_Script_Object'Class) do
>                   Output := Result;
>                end Get_Result;
>             end;
>          end loop;
>       end Parser_Task;
>    end Parsers;
>
> Note, you will need to override Constructor for each type derived from
> Post_Script_Object.
>
> Here is how to use it on the client side:
>
>    Worker : aliased Parser_Task;
> begin
>    Worker.Request ("...");
>    declare
>       Result_Type : Tag;
>    begin
>       Worker.Wait_For_Result (Result); -- Now we know the type
>       declare
>          Object : Post_Script_Object'Class :=
>             Get_Object Result_Type, Worker'Access);
>       begin
>          -- Doing something with object;
>       end;
>    end;

Ah... I get it. By putting the actual parsing between ACCEPT
statements you're allowing the structure within the task from
encountering the problem of multiple tasks with one calling
Wait_for_Object after another [different task] had called Request
which could/would have happened if you had something like:

Task body ....
  Working_Text     : Unbounded_String;
  Temporary_Object : Access PostScript_Object'Class;  --- Just a
holder for the operations...
....
begin
 loop
  Select
    Accept Request(Input_String : In String) do
            Working_Test:= To_Unbounded_String( Input_String );
    end Request;
   OR
    Accept Wait_For_Object( Output : out Tag ) do
            Output:= Temporary_Object'Tag;
    end Wait_For_Object;
   OR
    Get_Result( Output : out PostScript_Object'Class ) do
            Output:= Temporary_Object;
    end Wait_For_Object;
  End Select;
 end loop;
end;


Which, sad to admit, was how I was thinking it would have to be done.
WAAAAY over-complicated [because it would need some state-variables
and blocking-logic] compared to the solution you presented.
So, thank you again for the insight/learning.



  reply	other threads:[~2010-11-01 15:30 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-11-01  5:40 Tasks, Entries, and Variables of a Class-wide type Shark8
2010-11-01  9:21 ` Dmitry A. Kazakov
2010-11-01 15:30   ` Shark8 [this message]
2010-11-01 18:50     ` Jeffrey Carter
2010-11-01 19:23       ` Dmitry A. Kazakov
2010-11-01 20:08         ` Georg Bauhaus
2010-11-01 20:56           ` Dmitry A. Kazakov
2010-11-01 19:28       ` Shark8
2010-11-01 20:49         ` Jeffrey Carter
2010-11-05 12:43         ` Robert A Duff
replies disabled

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