From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-0.3 required=5.0 tests=BAYES_00, REPLYTO_WITHOUT_TO_CC autolearn=no autolearn_force=no version=3.4.4 X-Google-Thread: a07f3367d7,385c146dd3112519 X-Google-Attributes: gida07f3367d7,public,usenet X-Google-NewGroupId: yes X-Google-Language: ENGLISH,ASCII Path: g2news1.google.com!news3.google.com!feeder2.cambriumusenet.nl!feed.tweaknews.nl!193.141.40.65.MISMATCH!npeer.de.kpn-eurorings.net!npeer-ng0.de.kpn-eurorings.net!newsfeed.arcor.de!newsspool4.arcor-online.net!news.arcor.de.POSTED!not-for-mail From: "Dmitry A. Kazakov" Subject: Re: Private or public task ? Newsgroups: comp.lang.ada User-Agent: 40tude_Dialog/2.0.15.1 MIME-Version: 1.0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 8bit Reply-To: mailbox@dmitry-kazakov.de Organization: cbb software GmbH References: Date: Fri, 5 Feb 2010 22:40:38 +0100 Message-ID: <1rvjt99u2jqa8.1okqcvf62hlc8$.dlg@40tude.net> NNTP-Posting-Date: 05 Feb 2010 22:40:31 CET NNTP-Posting-Host: 58ff88e1.newsspool1.arcor-online.net X-Trace: DXC=LLWM>MNjTHfPXlQ;h]GTMdic==]BZ:afn4Fo<]lROoRa<`=YMgDjhgbQ30`UN=@g4k[6LHn;2LCVn[ On Fri, 5 Feb 2010 12:54:42 -0800 (PST), Hibou57 (Yannick Duch�ne) wrote: > So I wanted to solve this, and added a protected object providing an > Put procedure which was displaying the same message, all three > statement in an atomic procedure. This is illegal, because protected procedure shall not perform potentially blocking actions (like I/O. > Later, I advised the task may terminates while some potential clients > may still be alive, or even the task may terminates before any client > had time to make any first request. You do not need to worry about that. Unless you are using pointers, the task object's scope encloses any calls to its entries. Therefore it simply cannot terminate due to its finalization before any entry call. If it terminates for any other reason, you get Tasking_Error in the entry calls. > Later, I wanted to make it more secure and though it would be nice to > manage these Acquire/Release invocations transparently, using a > Limited_Controller type. All clients were then required to own an > instance of this type and to pass it to the Put entry, as a proof the > client was indeed owning one. This type was named Ticket_Type. If you want garbage collection because of pointers involved then just do it. Don't break the task interface, make a handle type pointing to the task object. When the last handle vanishes, deallocate the task. That is. > Here is my though (talking about design principle) : are tasks mostly > to be treated as things to be exposed in public part of to be treated > as implementation details ? After this experiment, I'm filling like > task are just like record components, Task component does not work in most real-life cases. > that is, better to make these private. > Any way, a request made to a task is blocking as long as the task is > not ready to fulfill the request (the rendezvous, which is the Ada > primitive for synchronization). So, from the client point of view, a > method implemented on top of a task is not a different thing than a > method implemented on top of a procedure. Yes, an entry call can be syntactically and semantically different than a call to a procedure. Here is how I would do this: with Ada.Text_IO; procedure Test is task Monitor is -- "Monitor" is the customary name of this pattern entry Put (Text : in String; Number : in Natural); end Monitor; task body Monitor is begin loop select accept Put (Text : in String; Number : in Natural) do Ada.Text_IO.Put_Line (Text & " " & Natural'Image (Number)); end Put; or terminate; end select; end loop; exception when others => Text_IO.Put_Line ("Oops, there is something bad here"); end Monitor; task First_Task; task body First_Task is begin for Index in 1..4 loop Monitor.Put ("This is First_Task, passing number ", Index); end loop; end First_Task; task Second_Task; task body Second_Task is begin for Index in 1..7 loop Monitor.Put ("This is Second_Task, passing number", Index); end loop; end Second_Task; task Third_Task; task body Third_Task is begin for Index in 1..5 loop Monitor.Put ("This is Third_Task, passing number ", Index); end loop; end Third_Task; begin null; end Test; You can print from the rendezvous. That is not a problem. Some tight implementations would prefer buffering in the rendezvous in order to release the caller as soon as possible (minimizing the effect of priority inversion). I.e. Text is first copied into the task's buffer during the rendezvous and printed later outside the rendezvous before accepting the new one. Assuming that the callers run at a higher priority and do not print very often leaving the processor free most of the time, this would give better response times in the callers (at the cost of some overall performance hit). -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de