[ Table of Contents ]
A terminate alternative can appear in the last part of a selective wait statement. Its purpose is to allow the task to be "completed" and "terminated" when its master and other tasks having the same master are ready for termination. (See diagram below.) The master is the library package or executing unit or block upon which the task depends -- usually the unit in which the task is nested.
The abort statement is a simple statement that is used by one task to prepare another task (or tasks) for completion and termination by putting it (them) in the "abnormal" state. (See diagram below, adapted from [Gonzalez91]. See [Burns98] for a more complete story.) The abort statement is rarely used.
Possible States During a Task's Lifetime
This UML state diagram shows the five task states and eight possible transitions
that can occur during the lifetime of a task. Activation obtains during elaboration of the declarative part of the task's body. This is typically followed by the executable, completed, and terminated states. The abnormal state occurs when the task is aborted. |
Example Program with Guards and a Terminate Alternative
The selective accept statement in the body of the Server task has four alternatives, two of which have guards. (See "when Squaring" and "when Cubing" in the code.) The third is the "accept Quit" alternative, and the fourth is the terminate alternative. |
The declare block in the Client (main task) contains the declaration of a string variable whose length cannot be known until run-time.
Source Code Listing
-------------------------------------------------------------- -- This program invites the user to enter up to ten integers. -- The Server task computes and displays the square or cube -- (sometimes both) of the input value, depending on the Count -- value. A terminate alternative ensures proper completion -- if ten non-zero values are entered. -------------------------------------------------------------- with Ada.Text_IO; use Ada.Text_IO; procedure Client is Str_4 : String := "1234"; Value : Integer; Length : Integer; Squaring : Boolean := True; Cubing : Boolean := False; ---------------------------------- task Server is entry Do_Square(N : in Integer); entry Do_Cube (N : in Integer); entry Quit; end Server; ---------------------------------- task body Server is Count : Integer := 0; Answer : Integer; begin loop Count := Count + 1; if Count > 3 then Cubing := True; end if; if Count > 8 then Squaring := False; end if; select -- selective guarded accept when Squaring => accept Do_Square(N : in Integer) do Answer := N*N; end Do_Square; Put_Line("N_Squared = " & Integer'Image(Answer)); or when Cubing => accept Do_Cube(N : in Integer) do Answer := N*N*N; end Do_Cube; Put_Line("N_Cubed = " & Integer'Image(Answer)); or accept Quit; Put_Line("Quit prematurely"); exit; or terminate; -- terminate alternative end select; end loop; end Server; ----------------------------------- begin -- Client executable part for I in 1..10 loop Put_Line("Enter an integer (3 digits or less; 0 to quit)"); Get_Line(Str_4, Length); declare -- run-time declaration Str : String := Str_4(1..Length); begin Value := Integer'Value(Str); end; if Value = 0 then Server.Quit; exit; else if Squaring then Server.Do_Square(Value); end if; if Cubing then Server.Do_Cube(Value); end if; end if; end loop; end Client; ---------------------------------------------------------- |
Here is a sample output from the above program:
Enter an integer (3 digits or less; 0 to quit) 1 N_Squared = 1 Enter an integer (3 digits or less; 0 to quit) 2 N_Squared = 4 Enter an integer (3 digits or less; 0 to quit) 3 N_Squared = 9 N_Cubed = 27 Enter an integer (3 digits or less; 0 to quit) 4 N_Squared = 16 N_Cubed = 64 Enter an integer (3 digits or less; 0 to quit) 5 N_Squared = 25 N_Cubed = 125 Enter an integer (3 digits or less; 0 to quit) 6 N_Cubed = 216 Enter an integer (3 digits or less; 0 to quit) 0 Quit prematurely |
Note that the number of times through the Server loop exceeded the number of times through the client loop because both guard conditions (Squaring and Cubing) were True in the middle of the run, when the values 3, 4 and 5 were entered (Count = 4, 5, 6, 7 and 8).
The terminate alternative was not used in the above example because the user entered a zero, triggering the "accept Quit" alternative. If the user had not entered a zero, the terminate alternate would have come into play after the tenth integer value was entered.
Related Topics
[ Back to top of page ]