Version 1.1 of ai05s/ai05-0202-1.txt

Unformatted version of ai05s/ai05-0202-1.txt version 1.1
Other versions for file ai05s/ai05-0202-1.txt

!standard C.7.3(8/2)          10-02-12 AI05-0202-1/00
!class binding interpretation 10-02-12
!status work item 10-02-12
!status received 09-09-24
!priority Medium
!difficulty Easy
!qualifier Omission
!subject Task_Termination and Exceptions raised during finalization
!summary
Exceptions raised during finalization have no effect on the Cause of termination of a task.
!question
Suppose a task has a termination handler set up by either Set_Specific_Handler or Set_Dependents_Fallback_Handler. Suppose the task executes the last statement of the task body normally, but an exception occurs during finalization (as part of the "actions specfied in 7.6 for finalization of a master"). For instance, the task may have a local variable with a controlled part, and a user-defined Finalize routine propagates an exception.
What is passed as the Cause parameter to the termination handler? Normal, or Unhandled_Exception? I don't think the wording of C.7.3(8/2) gives a clear answer; it says Cause=>Normal if the task is terminating "due to completing the last statement of its body", and that is the reason the task is terminating, it's just that some other unhandled exception came up afterwards.
In a similar vein, suppose an exception Exc1 is propagated out of the task body, and in the course of finalizing local objects, another exception Exc2 is propagated (by a user-defined Finalize). Now Cause=>Unhandled_Exception is passed to the termination handler, but which exception does the Exception_Occurrence X refer to? Would Exception_Identity(X) be the identity of Exc1, Exc2, or Program_Error?
!recommendation
(See Summary.)
!wording
Modify C.7.3(8/2):
The type Termination_Handler identifies a protected procedure to be executed by the implementation when a task terminates. Such a protected procedure is called a handler. In all cases T identifies the task that is terminating. If the task terminates due to completing the last statement of its body, or as a result of waiting on a terminate alternative, then Cause is set to Normal and X is set to Null_Occurrence. If the task terminates because it is being aborted, then Cause is set to Abnormal and X is set to Null_Occurrence. If the task terminates because of an exception raised by the execution of its task_body, then Cause is set to Unhandled_Exception and X is set to the associated exception occurrence. {In any case, an exception raised by the finalization of the task does not change Cause or X.}
[Editor's note: What the heck kind of name for a parameter is X? How did that get through review?? Oh well, too late to change that now.]
!discussion
The only exception that can be propagated by a failed Finalize routine is Program_Error. Finalization of a protected object itself cannot propagate an exception (it will propagate Program_Error to any queued callers). Waiting for tasks cannot propagate an exception (but we might wait forever). Nothing else happens during a finalization.
So the author believes that this boils down to the Program_Error propagated by a failed finalization.
In any case, the primary purpose of the handlers is to report the otherwise silent termination of a task. The "cause" is a secondary feature, so it isn't critical to be able to tell between the many kinds of failure. But it is important to have a consistent definition.
The definition of Cause is primarily to report why the task itself terminated. The termination of the task definitely was not caused by whatever happens during finalization. When a task fails, it may cause cascading errors during finalization, but that is likely to be much less interesting information. Thus we define that whatever happens in the finalization code is ignored for the purposes of setting Cause.
This does have the weird effect of reporting Normal termination for a task whose finalization raises an exception, but the seems better than obscuring the reason that the task_body completed and terminated.
--!corrigendum 3.9.3(4/2)
!ACATS Test
An ACATS C-Test should be created that checks this semantics.
!appendix

!topic Clarification on parameters passed to Task_Termination handler
!reference C.7.3
!from Adam Beneschan 09-11-20
!discussion

Suppose a task has a termination handler set up by either Set_Specific_Handler
or Set_Dependents_Fallback_Handler.  Suppose the task executes the last
statement of the task body normally, but an exception occurs during finalization
(as part of the "actions specfied in 7.6 for finalization of a master").  For
instance, the task may have a local variable with a controlled part, and a
user-defined Finalize routine propagates an exception.

What is passed as the Cause parameter to the termination handler?
Normal, or Unhandled_Exception?  I don't think the wording of
C.7.3(8/2) is 100% clear; it says Cause=>Normal if the task is terminating "due
to completing the last statement of its body", and that *is* the reason the task
is terminating, it's just that some other unhandled exception came up
afterwards.

In a similar vein, suppose an exception Exc1 is propagated out of the task body,
and in the course of finalizing local objects, another exception Exc2 is
propagated (by a user-defined Finalize).  Now Cause=>Unhandled_Exception is
passed to the termination handler, but which exception does the
Exception_Occurrence X refer to?  Would Exception_Identity(X) be the identity of
Exc1, Exc2, or Program_Error?

****************************************************************

Questions? Ask the ACAA Technical Agent