comp.lang.ada
 help / color / mirror / Atom feed
From: "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de>
Subject: Re: Task origin track from a class
Date: Tue, 12 Jul 2011 09:41:24 +0200
Date: 2011-07-12T09:41:24+02:00	[thread overview]
Message-ID: <4o0rnqqqec1s$.19h46xsbjbku2.dlg@40tude.net> (raw)
In-Reply-To: e05f6958-33e1-4660-bdfa-c370ca466c02@glegroupsg2000goo.googlegroups.com

On Mon, 11 Jul 2011 20:24:04 -0700 (PDT), Rego, P. wrote:

> I have a class Def_Class which defines a record which is a task.

You shouldn't do that, because most likely you will later have serious
(unsolvable) problems with the object's finalization.

Unless the task has somewhere a select with an open terminate alternative,
the object's finalization will hang.

Note that deriving it from Ada.Finalization.Limited_Controlled won't help.
Consider this:

      type Parent;
      task type Worker (Data : not null access Parent'Class) is
         entry Do_Stuff;
         entry Stop;
      end Worker;
      type Parent is
         new Ada.Finalization.Limited_Controlled with
      record
         My_Task : Worker (Parent'Access);
      end record;
      overriding procedure Finalize (Object : in out Parent);

and the implementation:

      procedure Finalize (Object : in out Parent) is
      begin
         Object.My_Task.Stop; -- Kill the task
      end Finalize;
      
      task body Worker is
      begin
         loop
            select
               accept Do_Stuff;
                -- Some useful stuff to do
            or accept Stop;
               exit;
            end select;
         end loop;
      end Worker;

This does *not* work! The problem is that the task must complete *before*
Finalize of the containing object is called. It would work if the select of
the task would have:

   or terminate;  -- Complete if asked

(and then the Stop entry call removed from Finalize, of course).

The problem with this is that too frequently there is no way to add the
terminate alternative (for various reasons, which are irrelevant here).

So the unfortunate rule of the thumb is: never use task components, but
access to task instead. From Finalize you would call Stop entry or an
equivalent and then free the task object using Unchecked_Deallocation.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



  parent reply	other threads:[~2011-07-12  7:41 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-07-12  3:24 Task origin track from a class Rego, P.
2011-07-12  5:57 ` Simon Wright
2011-07-12  7:41 ` Dmitry A. Kazakov [this message]
2011-07-12 10:29   ` Simon Wright
2011-07-12 10:31     ` Simon Wright
2011-07-13  0:36       ` Shark8
2011-07-13  2:57         ` Rego, P.
2011-07-13  7:41         ` Dmitry A. Kazakov
2011-07-13  8:43           ` Georg Bauhaus
2011-07-13 11:59             ` Dmitry A. Kazakov
2011-07-13 16:31           ` Shark8
2011-07-13 17:22             ` Dmitry A. Kazakov
replies disabled

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