comp.lang.ada
 help / color / mirror / Atom feed
* Finalization of record components which are tasks
@ 2000-03-02  0:00 Florian Weimer
  2000-03-02  0:00 ` Robert A Duff
  2000-03-03  0:00 ` Florian Weimer
  0 siblings, 2 replies; 5+ messages in thread
From: Florian Weimer @ 2000-03-02  0:00 UTC (permalink / raw)


Does the termination of a task which is a component of a controlled
object really happen *before* the user-defined finalization subprogram
is called?  This is really surprising.  IMHO, both common sense and
7.6.1(5) suggest that the task object has to be finalized *after* the
user-defined finalization subprogram has completed.

The program below illustrates the problem.  Running it with GNAT (on
Solaris, Debian GNU/Linux, Red Hat 6.1) results in the following
output:

Before Task_Type.Start (R)
Before Start
After Task_Type.Start (R)
Before Wait
Watcher object finalized
Task has terminated
Before Wait in finalization
Exception in Finalize
Exception name: TASKING_ERROR
Message: s-tasren.adb:516

"Watcher object finalized" means that the task object is about to be
finalized; and in fact, the task has already terminated when Finalize
on the composite type is called.  Very strange.

with Ada.Exceptions, Ada.Finalization;
with Ada.Text_IO;
with Task_Type;
procedure Free_Task is

   procedure Create_Task is
      R : Task_Type.Some_Record;
   begin
      Ada.Text_IO.Put_Line ("Before Task_Type.Start (R)");
      Task_Type.Start (R);
      Ada.Text_IO.Put_Line ("After Task_Type.Start (R)");
    end Create_Task;

begin
   Create_Task;
end Free_Task;

with Ada.Exceptions;
with Ada.Text_IO;
package body Task_Type is

   procedure Finalize (Object : in out Some_Record) is
   begin
      if Object.T'Terminated then
         Ada.Text_IO.Put_Line ("Task has terminated");
      else
         Ada.Text_IO.Put_Line ("Task has NOT terminated");
      end if;
      Ada.Text_IO.Put_Line ("Before Wait in finalization");
      Object.T.Wait;
      Ada.Text_IO.Put_Line ("After Wait in finalization");
   exception
      when E : others =>
         Ada.Text_IO.Put_Line ("Exception in Finalize");
         Ada.Text_IO.Put_Line (Ada.Exceptions.Exception_Information (E));
   end Finalize;

   type Watcher is new Ada.Finalization.Limited_Controlled with null record;

   procedure Finalize (Object : in out Watcher) is
   begin
      Ada.Text_IO.Put_Line ("Watcher object finalized");
   end Finalize;

   task body Some_Task is
      W : Watcher;
   begin
      Ada.Text_IO.Put_Line ("Before Start");
      accept Start;
      Ada.Text_IO.Put_Line ("Before Wait");
      select
         accept Wait;
         Ada.Text_IO.Put_Line ("After Wait");
      or
         terminate;
      end select;
   exception
      when E : others =>
         Ada.Text_IO.Put_Line ("Exception in task");
         Ada.Text_IO.Put_Line (Ada.Exceptions.Exception_Information (E));
   end Some_Task;

   procedure Start (R : in out Some_Record) is
   begin
      R.T.Start;
   end Start;

   procedure Wait (R : in out Some_Record) is
   begin
      R.T.Wait;
   end Wait;

end Task_Type;

with Ada.Finalization;
package Task_Type is

   type Some_Record is limited private;

   procedure Start (R : in out Some_Record);
   procedure Wait (R : in out Some_Record);

private

   task type Some_Task (Reference : access Some_Record) is
      entry Start;
      entry Wait;
   end Some_Task;

   type Some_Record is new Ada.Finalization.Limited_Controlled with record
      T : Some_Task (Some_Record'Access);
   end record;

   procedure Finalize (Object : in out Some_Record);

end Task_Type;

-- 
Florian Weimer 	                  Florian.Weimer@RUS.Uni-Stuttgart.DE
RUS-CERT, Univ. Stuttgart         http://cert.uni-stuttgart.de/




^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Finalization of record components which are tasks
  2000-03-02  0:00 Finalization of record components which are tasks Florian Weimer
@ 2000-03-02  0:00 ` Robert A Duff
  2000-03-03  0:00 ` Florian Weimer
  1 sibling, 0 replies; 5+ messages in thread
From: Robert A Duff @ 2000-03-02  0:00 UTC (permalink / raw)


> Does the termination of a task which is a component of a controlled
> object really happen *before* the user-defined finalization subprogram
> is called?  This is really surprising.  IMHO, both common sense and
> 7.6.1(5) suggest that the task object has to be finalized *after* the
> user-defined finalization subprogram has completed.

I'm too lazy to read all your code, but maybe this will answer the
question:

A task terminates when it's done.  Also, if it is waiting on a terminate
alternative, it terminates when its master is done, and all of the other
tasks dependent on that master are terminated or waiting on terminate
alternatives.  In particular, the termination of a task is *not*
triggered by finalization of the task object.  So 7.6.1(9) is
irrelevant.

When a master (eg a procedure) is done ("completed" is the RM term) it
*first* awaits termination of dependent tasks (and/or causes their
termination if they're waiting on terminate alts).  It *then* finalizes
all of the local objects (and if some of those are tasks, or contain
tasks, then they are necessarily already terminated at that point).
Note that finalization of a task object doesn't do much of anything.

You wouldn't want it to be the other way around: If you first finalize
locals, and then wait for the tasks to terminate, then those tasks would
have the data they're working on ripped out from under them.

There are obscure ways in which programs can see finalized objects, but
this isn't one of them, and that's a good thing.

- Bob





^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Finalization of record components which are tasks
  2000-03-02  0:00 Finalization of record components which are tasks Florian Weimer
  2000-03-02  0:00 ` Robert A Duff
@ 2000-03-03  0:00 ` Florian Weimer
  2000-03-03  0:00   ` Robert A Duff
  1 sibling, 1 reply; 5+ messages in thread
From: Florian Weimer @ 2000-03-03  0:00 UTC (permalink / raw)


Florian Weimer <Florian.Weimer@RUS.Uni-Stuttgart.DE> writes:

> Does the termination of a task which is a component of a controlled
> object really happen *before* the user-defined finalization subprogram
> is called?  This is really surprising.  IMHO, both common sense and
> 7.6.1(5) suggest that the task object has to be finalized *after* the
> user-defined finalization subprogram has completed.

Kudos to Robert A. Duff, who explained me via email why my
expectations were wrong.  In short, I didn't know the concept of
"masters" (and didn't read RM 9.3).

Maybe it's time to read another book.  Cohen's "Ada as a Second
Language" doesn't help much in this area.  Is "Currency in Ada" (by
Burns and Wellings) a good choice?

-- 
Florian Weimer 	                  Florian.Weimer@RUS.Uni-Stuttgart.DE
RUS-CERT, Univ. Stuttgart         http://cert.uni-stuttgart.de/




^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Finalization of record components which are tasks
  2000-03-03  0:00 ` Florian Weimer
@ 2000-03-03  0:00   ` Robert A Duff
  0 siblings, 0 replies; 5+ messages in thread
From: Robert A Duff @ 2000-03-03  0:00 UTC (permalink / raw)


Florian Weimer <Florian.Weimer@RUS.Uni-Stuttgart.DE> writes:

> 
> Florian Weimer <Florian.Weimer@RUS.Uni-Stuttgart.DE> writes:
> 
> > Does the termination of a task which is a component of a controlled
> > object really happen *before* the user-defined finalization subprogram
> > is called?  This is really surprising.  IMHO, both common sense and
> > 7.6.1(5) suggest that the task object has to be finalized *after* the
> > user-defined finalization subprogram has completed.
> 
> Kudos to Robert A. Duff, who explained me via email why my
> expectations were wrong.

I meant to post it, not email it.  Feel free to post my e-mail, if you
still have a copy, and think anybody might be interested.

>...  In short, I didn't know the concept of
> "masters" (and didn't read RM 9.3).
> 
> Maybe it's time to read another book.  Cohen's "Ada as a Second
> Language" doesn't help much in this area.  Is "Currency in Ada" (by
> Burns and Wellings) a good choice?

Yeah.  There's also John Barnes' book.

- Bob




^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Finalization of record components which are tasks
@ 2000-03-03  0:00 Christoph Grein
  0 siblings, 0 replies; 5+ messages in thread
From: Christoph Grein @ 2000-03-03  0:00 UTC (permalink / raw)
  To: comp.lang.ada

> Does the termination of a task which is a component of a controlled
> object really happen *before* the user-defined finalization subprogram
> is called?  This is really surprising.  IMHO, both common sense and
> 7.6.1(5) suggest that the task object has to be finalized *after* the
> user-defined finalization subprogram has completed.

What do you mean by "common sense"? My common sense says what happens is just
what I expect.

On Rational on Sun, the following happens:

Before Start                   <-- these two statements may
Before Task_Type.Start (R)     <-- occur in any sequence
After Task_Type.Start (R)
Before Wait
Watcher object finalized
Task has terminated
Before Wait in finalization
Exception in Finalize
TASKING_ERROR raised at 16#000E2544#, Exception Message: 

You have to take into account the notion of a master of the task in question.
Your procedure Create_Task is the master in question. It can be left only if
if all tasks it is the master of have terminated.

Now you have a terminate alternative in you task. This tells the task that it
can terminate when there is no more caller around. Your only caller is in fact
Create_Task, which is waitinf for termination so there actually is no more
caller. So the terminate alternative is chosen, the task terminates.
Finalize is called for the terminated task. Now you try to rendezvous with a
terminated task, so you get what you reqested.

If you comment out the terminate alternative, you'll get deadlock. The task
waits on a select statement no-one is around to call.

Hope that helps.









^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2000-03-03  0:00 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2000-03-02  0:00 Finalization of record components which are tasks Florian Weimer
2000-03-02  0:00 ` Robert A Duff
2000-03-03  0:00 ` Florian Weimer
2000-03-03  0:00   ` Robert A Duff
  -- strict thread matches above, loose matches on Subject: below --
2000-03-03  0:00 Christoph Grein

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