9.3 Task Dependence - Termination of Tasks
Dynamic Semantics
1
Each
task (other than an environment task — see
10.2)
depends on one or more masters (see
7.6.1),
as follows:
2
- If the task is created by the evaluation
of an allocator for a given access type, it
depends on each master that includes the elaboration of the declaration
of the ultimate ancestor of the given access type.
3
- If the task is created by the elaboration
of an object_declaration, it depends on each
master that includes this elaboration.
3.1/2
- Otherwise, the task depends on the
master of the outermost object of which it is a part (as determined by
the accessibility level of that object — see 3.10.2
and 7.6.1), as well as on any master whose
execution includes that of the master of the outermost object.
4
Furthermore, if a task depends
on a given master, it is defined to depend on the task that executes
the master, and (recursively) on any master of that task.
5
A task is said to be
completed when the execution
of its corresponding
task_body is completed.
A task is said to be
terminated when any finalization of the
task_body
has been performed (see
7.6.1). The first
step of finalizing a master (including a
task_body)
is to wait for the termination of any tasks dependent on the master.
The task executing the master is blocked until all
the dependents have terminated. Any remaining finalization is then performed
and the master is left.
6/1
Completion of a task
(and the corresponding
task_body) can occur
when the task is blocked at a
select_statement
with an open
terminate_alternative (see
9.7.1);
the open
terminate_alternative is selected
if and only if the following conditions are satisfied:
7/2
- The task depends on some completed
master; and
8
- Each task that depends on the master
considered is either already terminated or similarly blocked at a select_statement
with an open terminate_alternative.
9
When both conditions are satisfied, the task considered
becomes completed, together with all tasks that depend on the master
considered that are not yet completed.
10
8 The full view of a limited private type
can be a task type, or can have subcomponents of a task type. Creation
of an object of such a type creates dependences according to the full
type.
11
9 An object_renaming_declaration
defines a new view of an existing entity and hence creates no further
dependence.
12
10 The rules given for the collective completion
of a group of tasks all blocked on select_statements
with open terminate_alternatives ensure that
the collective completion can occur only when there are no remaining
active tasks that could call one of the tasks being collectively completed.
13
11 If two or more tasks are blocked on
select_statements with open terminate_alternatives,
and become completed collectively, their finalization actions proceed
concurrently.
14
12 The completion
of a task can occur due to any of the following:
15
- the raising of an exception during
the elaboration of the declarative_part of
the corresponding task_body;
16
- the completion of the handled_sequence_of_statements
of the corresponding task_body;
17
- the selection of an open terminate_alternative
of a select_statement in the corresponding
task_body;
18
Examples
19
Example of task
dependence:
20
declare
type Global
is access Server; --
see 9.1
A, B : Server;
G : Global;
begin
--
activation of A and B
declare
type Local
is access Server;
X : Global :=
new Server; --
activation of X.all
L : Local :=
new Server; --
activation of L.all
C : Server;
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