6.2 The select Statement

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

The select statement is a compound statement used to provide for the selection of alternative choices involving a rendezvous between two tasks. When used in a calling task, it allows two-way choices known as conditional entry calls and timed entry calls. When used in a called task it allows multi-way choices known as selective accepts. Select statements often include delay "alternatives" within them, and always include the reserved word, select.

The following table shows the general forms for these three types of select statement. In the first (conditional) case the call to Entry1 is immediately withdrawn if Callee is not already waiting to accept it. In the second (timed) case the call to Entry2 is withdrawn after a specified waiting time, Duration1. In the third (selective accept) case either a call to Entry1 or a call to Entry2 will be accepted (whichever arrives first) as long as one arrives before the expiration of the specified waiting time, Duration2. Furthermore, there could be any number of  "accept alternatives" before the final "delay alternative."

Conditional Entry Call
(Caller)
select
  Callee.Entry1;
else
  -- do something else
end select;
Timed Entry Call
(Caller)
select
  Callee.Entry2;
or
  delay Duration1;
end select;
Selective Accept
(Callee)
select
  accept Entry1 do
    -- do something
  end Entry1;
or
  accept Entry2 do
    -- do something
  end Entry2;
or
  delay Duration2;
end select;

There are additional possibilities for a selective accept statement, beyond those shown in the above example. For example, the final alternative could be a "delay alternative" (as above), a "terminate alternative" (see next page), or an "else part" (similar to a conditional entry call -- with zero waiting time). There can also be guards on the various accept alternatives (see next page).

Example Program with select Statements

In this two-task program the main procedure Caller is the "main task" and Callee, nested in Caller, is the other task. Caller has two select statements (a conditional entry call and a timed entry call) and Callee has a multi-way selective accept statement ending with a delay alternative.

Im6-3.gif (4838 bytes)

The program makes use of delays within select statements, to determine how long an entry call will be left on a queue waiting to be accepted and how long some accept alternatives will be left open, waiting for an entry call to arrive.

Note that a task does not require a "start" statement or start entry. It begins executing automatically when its enclosing unit finishes elaboration.

Source Code Listing

-----------------------------------------------------------
--  This program asks the user to enter a character, 
--  preferably a 'c' or a 't'. The resultant behavior 
--  (conditional or timed) depends on the character entered
--  and the time it is entered. 
-----------------------------------------------------------
with Ada.Text_IO; use Ada.Text_IO;
procedure Caller is                        
    
  Ch : Character;
    
  task Callee is
    entry Do_This;
    entry Do_That;
    entry Do_Nothing;
  end Callee;
  
  task body Callee is
  begin
      
    delay 5.0;
      
    select                           -- Selective Accept
      accept Do_This do
        Put_Line("Do_This accepted and service provided");
      end Do_This;
    or
      accept Do_That do
        Put_Line("Do_That accepted and service provided");
      end Do_That;   
    or                              
      delay 5.0;
      Put_Line("Callee no longer waiting");
    end select;
    
    accept Do_Nothing;
    Put_Line("Both tasks shutting down");    
  end Callee;
  
begin                                -- Caller executable part

  Put_Line("Enter c or t (Conditional or Timed)");
  Get(Ch);
  
  if Ch = 'c' then                   -- Conditional Entry Call
    select
      Callee.Do_This;
    else
      Put_Line("Conditional call not accepted");
    end select;
      
  elsif Ch = 't' then                -- Timed Entry Call 
    select
      Callee.Do_That;
    or
      delay 3.0;    
      Put_Line("Timed call withdrawn");
    end select;
       
  else
    Put_Line("Invalid Input");  
  end if;
  
  Callee.Do_Nothing;                 -- Both tasks can quit
                        
end Caller;
----------------------------------------------------------

Discussion of Program Behavior

The Callee has an initial delay of 5.0 seconds and its selective accept statement has a delay alternative with another 5.0 second delay. Thus, it will accept calls only in the "window" between 5 seconds and 10 seconds after the time the program is started. There are eight possible responses, including the following five.

If a 'c' is entered during the first five seconds, the output will be:

     Enter 'c' or 't' (conditional or timed)
     c
     Conditional call not accepted
     Callee no longer waiting
     Both tasks shutting down

If a 'c' is entered after five seconds and before ten seconds, the output will be:

     Enter 'c' or 't' (conditional or timed)
     c
     Do_This call accepted and service provided
     Both tasks shutting down

If a 't' is entered during the first two seconds, the output will be:

     Enter 'c' or 't' (conditional or timed)
     t
     Timed call withdrawn
     Callee no longer waiting
     Both tasks shutting down

If a 't' is entered after two seconds and before ten seconds, the output will be:

     Enter 'c' or 't' (conditional or timed)
     t
     Do_That call accepted and service provided
     Both tasks shutting down

If neither 'c' nor 't' (say 'x') is entered during the first ten seconds, the output will be:

     Enter 'c' or 't' (conditional or timed)
     x
     Invalid input
     Callee no longer waiting
     Both tasks shutting down

The Do_Nothing entry and accept were included in the Callee task in order to prevent a "tasking error" exception from arising in cases where the user enters nothing during the first ten seconds. The "accept Do_Nothing" statement allows Callee to wait indefinitely until the user finally enters a character -- allowing the two tasks to engage in a rendezvous before reaching the end of their executable parts and shutting down.

Related Topics

3.12  The delay Statement A.2  Simple and Compound Statements

[ Back to top of pagePrev ] Next ]