Each task depends on at least one master. A master is a construct that is either a task, a currently executing block statement or subprogram, or a library package (a package declared within another program unit is not a master). The dependence on a master is a direct dependence in the following two cases:
A task is said to have completed its execution when it has finished the execution of the sequence of statements that appears after the reserved word begin in the corresponding body. Similarly a block or a subprogram is said to have completed its execution when it has finished the execution of the corresponding sequence of statements. For a block statement, the execution is also said to be completed when it reaches an exit, return, or goto statement transferring control out of the block. For a procedure, the execution is also said to be completed when a corresponding return statement is reached. For a function, the execution is also said to be completed after the evaluation of the result expression of a return statement. Finally the execution of a task, block statement, or subprogram is completed if an exception is raised by the execution of its sequence of statements and there is no corresponding handler, or, if there is one, when it has finished the execution of the corresponding handler.
If a task has no dependent task, its termination takes place when it has completed its execution. After its termination, a task is said to be terminated. If a task has dependent tasks, its termination takes place when the execution of the task is completed and all dependent tasks are terminated. A block statement or subprogram body whose execution is completed is not left until all of its dependent tasks are terminated.
Termination of a task otherwise takes place if and only if its execution has reached an open terminate alternative in a select statement (see 9.7.1), and the following conditions are satisfied:
When both conditions are satisfied, the task considered becomes terminated, together with all tasks that depend on the master considered.
declare type GLOBAL is access RESOURCE; -- see 9.1 A, B : RESOURCE; G : GLOBAL; begin -- activation of A and B declare type LOCAL is access RESOURCE; X : GLOBAL := new RESOURCE; -- activation of X.all L : LOCAL := new RESOURCE; -- activation of L.all C : RESOURCE; begin -- activation of C G := X; -- both G and X designate the same task object ... end; -- await termination of C and L.all (but not X.all) ... end; -- await termination of A, B, and G.all
The rules given for termination imply that all tasks that depend (directly or indirectly) on a given master and that are not already terminated, can be terminated (collectively) if and only if each of them is waiting on an open terminate alternative of a select statement and the execution of the given master is completed.
The usual rules apply to the main program. Consequently, termination of the main program awaits termination of any dependent task even if the corresponding task type is declared in a library package. On the other hand, termination of the main program does not await termination of tasks that depend on library packages; the language does not define whether such tasks are required to terminate.
For an access type derived from another access type, the corresponding access type definition is that of the parent type; the dependence is on the master that elaborates the ultimate parent access type definition.
A renaming declaration defines a new name for an existing entity and hence creates no further dependence.
References: access type, allocator, block statement, declaration, designate, and 9.1, exception, exception handler, exit statement, function, goto statement, library unit, main program, object, open alternative, package, program unit, renaming declaration, return statement, selective wait, sequence of statements, statement, subcomponent, subprogram body, subprogram call, task body, task object, terminate alternative.