6.3 terminate and the abort Statement

[ Table of Contents ] Prev ] Chapter Overview ] Next ] [ Glossary/Index ]

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

Im6-4a.gif (2568 bytes)

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.

Im6-4b.gif (4071 bytes)

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;
      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));
        when Cubing =>   
          accept Do_Cube(N : in Integer) do
            Answer := N*N*N;  
          end Do_Cube;
          Put_Line("N_Cubed = " & Integer'Image(Answer));
        accept Quit;
        Put_Line("Quit prematurely");
        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);
      Value := Integer'Value(Str);  
    if Value = 0 then
      if Squaring then
      end if;
      if Cubing then
      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)
     N_Squared = 1
     Enter an integer (3 digits or less; 0 to quit)
     N_Squared = 4
     Enter an integer (3 digits or less; 0 to quit)
     N_Squared = 9
     N_Cubed = 27
     Enter an integer (3 digits or less; 0 to quit)
     N_Squared = 16
     N_Cubed = 64
     Enter an integer (3 digits or less; 0 to quit)
     N_Squared = 25
     N_Cubed = 125
     Enter an integer (3 digits or less; 0 to quit)
     N_Cubed = 216
     Enter an integer (3 digits or less; 0 to quit)
     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

A.2  Simple and Compound Statements

[ Back to top of pagePrev ] Next ]