Version 1.2 of ais/ai-00266.txt
!standard D.2.2 (5) 01-10-05 AI95-00266/02
!standard D.7 (00)
!class amendment 01-05-10
!status work item 01-05-10
!status received 01-05-10
!subject Task Termination procedure
A pragma is proposed that used as part of a task definition specifies
a "task group" object to be notified when a task terminates.
In Ada 95, a task propagating an exception will silently be terminated.
This is a significant hazard in high integrity systems.
An abstract type Root_Task_Group is declared as follows:
package Ada.Task_Groups is
type Root_Task_Group is abstract tagged limited private;
procedure Aborted(TG : in out Root_Task_Group;
ID : Task_Identification.Task_ID) is abstract;
procedure Unhandled_Exception(TG : in out Root_Task_Group;
ID : Task_Identification.Task_ID;
Excep : Exceptions.Exception_Occurrence) is abstract;
procedure Normal_Termination(TG : in out Root_Task_Group;
ID : Task_Identification.Task_ID) is abstract;
A new pragma is defined:
pragma Task_Group(task-group_name [, On => object-or-type_local_name]);
The task-group_name argument must denote a variable object whose type is
covered by Root_Task_Group'Class. The On argument, if present, must statically
denote an object or first subtype declared immediately in the current region.
When the On argument is present, the Task_Group pragma directly specifies the
task-group aspect for the object or type denoted by the argument. A derived
type inherits the task-group aspect of its parent type. An object inherits the
task-group aspect of its type. An object created by an allocator inherits the
task-group aspect of the type of the allocator. If both the object's type and
the allocator type have a specified task-group, the object inherits the
task-group from the type of the allocator. A component object inherits the
task-group aspect from its enclosing object. If both the enclosing object and
its type specify the task-group, the component inherits the task-group aspect
from its enclosing object.
When the On argument is not present, the Task_Group pragma establishes a
"default" task-group aspect for all declarations within the immediate scope of
the pragma. A Task_Group pragma without an On argument in an inner scope
overrides the default established in an outer scope. If the task-group aspect
is specified for a task, this becomes the default for the outermost region of
its task body.
If a task object has a task-group aspect specified directly or indirectly, then
immediately prior to task termination, after the task body has completed and
been left, a call is made to one of the three operations of the associated
task-group object. If the task completes due to an abort statement, the Aborted
operation is called. If the task completes due to an unhandled exception, the
Unhandled_Exception operation is called. If the task completes due to
completing the last statement of the task body, or as part of waiting on a
terminate alternative, the Normal_Termination operation is called. In each
case, the ID parameter identifies the task that is terminating. For the
Unhandled_Exception operation, the Excep parameter holds the
Exception_Occurrence which was not handled.
The result of calling Current_Task while executing one of the task-group
operations identifies the task about to terminate. Both the Terminated
attribute and the Callable attribute of the task return False.
Because the task has not yet terminated at the time of the call, task
attributes created by an (active) instantiation of the Ada.Task_Attributes
package have not yet been finalized, allowing the operations to read
information from these attributes.
Note that concurrent calls on task-group operations are possible due to
concurrent termination of tasks. Hence, these operations should be implemented
in a reentrant manner.
Many safety critical and high integrity systems prohibit exception handling,
and so the use of a "when others" handler at the task body level is then not
We have proposed a technique that is reminiscent of what Java does, in that it
establishes a separate abstraction, called a task group ("thread group" in
Java) which receives notification of task termination.
This proposal allows each library package to specify a default task-group, as
well as allowing more local specifications. The proposal does not provide any
direct way to specify the task-group for all tasks in the entire program. This
is difficult due to elaboration order issues. Multiple packages are allowed to
specify the same task-group object, since the task-group_name argument of the
pragma is a "name" rather than a "local_name".
Because task terminations can occur immediately after task activation, it is
important that the operations of the task-group object be elaborated prior to
activations being performed. Use of pragma Elaborate_All on the package
containing the type of the task-group object is therefore recommended.
[Editor's note: This originally was part of the Ravenscar proposal,
From: Randy Brukardt
Date: Wednesday, April 11, 2001, 5:41 PM.
This proposal seems to be exactly equivalent to the following code. (We use
code like this in Claw to handle locking, that the user can't lock
something and leave it locked by omission or by abnormal termination.)
Since this code is pure Ada 95, it would be useful to understand why this
is not an effective solution to the problem posed.
type Handler_Object is new Ada.Finalization.Limited_Controlled
with null record;
procedure Finalize (Object : in out Handler_Object) is
<handler_name>; -- Call to <handler_name>; as a practical matter,
-- you'd probably put the code here.
task My_Task ...
task body My_Task is
Termination_Handler : Handler_Object; -- Declare this first,
-- so it gets finalized last.
The basic idea is to insure that the last thing Finalized is your
termination handler. Clearly, it's easier to mess this up than with the
pragma (if someone sticks something in front of the termination object, you
could have trouble), but the semantics seem to be exactly the same. So I
would consider this proposal unnecessary without further justification. I'd
also suggest that the semantics be defined in terms of this sort of code if
possible (it would make the proposal look "simpler", which is always good).
Questions? Ask the ACAA Technical Agent