[ Table of Contents ]
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. |
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
[ Back to top of page ]