1-- C974011.A 2-- 3-- Grant of Unlimited Rights 4-- 5-- Under contracts F33600-87-D-0337, F33600-84-D-0280, MDA903-79-C-0687, 6-- F08630-91-C-0015, and DCA100-97-D-0025, the U.S. Government obtained 7-- unlimited rights in the software and documentation contained herein. 8-- Unlimited rights are defined in DFAR 252.227-7013(a)(19). By making 9-- this public release, the Government intends to confer upon all 10-- recipients unlimited rights equal to those held by the Government. 11-- These rights include rights to use, duplicate, release or disclose the 12-- released technical data and computer software in whole or in part, in 13-- any manner and for any purpose whatsoever, and to have or permit others 14-- to do so. 15-- 16-- DISCLAIMER 17-- 18-- ALL MATERIALS OR INFORMATION HEREIN RELEASED, MADE AVAILABLE OR 19-- DISCLOSED ARE AS IS. THE GOVERNMENT MAKES NO EXPRESS OR IMPLIED 20-- WARRANTY AS TO ANY MATTER WHATSOEVER, INCLUDING THE CONDITIONS OF THE 21-- SOFTWARE, DOCUMENTATION OR OTHER INFORMATION RELEASED, MADE AVAILABLE 22-- OR DISCLOSED, OR THE OWNERSHIP, MERCHANTABILITY, OR FITNESS FOR A 23-- PARTICULAR PURPOSE OF SAID MATERIAL. 24--* 25-- 26-- OBJECTIVE: 27-- Check that the sequence of statements of the triggering alternative 28-- of an asynchronous select statement is not executed if the triggering 29-- statement is a task entry call and the entry is not accepted 30-- before the abortable part completes. 31-- Check that the call queued on the entry is cancelled 32-- 33-- TEST DESCRIPTION: 34-- Declare a main procedure containing an asynchronous select with a task 35-- entry call as triggering statement. Force the entry call to be 36-- queued by having the task call a procedure, prior to the corresponding 37-- accept statement, which simulates (with a delay) a routine waiting 38-- for user input 39-- 40-- Once the call is known to be queued, complete the abortable part. 41-- Check that the rendezvous (and thus the trigger) does not complete. 42-- Then clear the barrier and check that the entry has been cancelled 43-- 44-- 45-- CHANGE HISTORY: 46-- 06 Dec 94 SAIC ACVC 2.0 47-- 28 Nov 95 SAIC Eliminated shared global variable for ACVC 2.0.1 48-- 49--! 50 51with ImpDef; 52-- 53package C974011_0 is -- Automated teller machine abstraction. 54 55 56 57 type Key_Enum is (None, Cancel, Deposit, Withdraw); 58 59 protected Key_PO is 60 procedure Set (K : Key_Enum); 61 function Value return Key_Enum; 62 private 63 Current : Key_Enum := None; 64 end Key_PO; 65 66 67 -- Flags for testing purposes 68 TC_Abortable_Part_Completed : Boolean := False; 69 TC_Rendezvous_Entered : Boolean := False; 70 TC_Delay_Time : constant duration := ImpDef.Switch_To_New_Task; 71 72 73 Count : Integer := 1234; -- Global to defeat optimization. 74 75 76 type Card_Number_Type is private; 77 type Card_PIN_Type is private; 78 type ATM_Card_Type is private; 79 80 81 Transaction_Canceled : exception; 82 83 84 task type ATM_Keyboard_Task is 85 entry Cancel_Pressed; 86 end ATM_Keyboard_Task; 87 88 procedure Read_Card (Card : in out ATM_Card_Type); 89 90 procedure Validate_Card (Card : in ATM_Card_Type); 91 92 procedure Perform_Transaction (Card : in ATM_Card_Type); 93 94private 95 96 type Card_Number_Type is range 1 .. 9999; 97 type Card_PIN_Type is range 100 .. 999; 98 99 type ATM_Card_Type is record 100 Number : Card_Number_Type; 101 PIN : Card_PIN_Type; 102 end record; 103 104end C974011_0; 105 106 107 --==================================================================-- 108 109 110with Report; 111package body C974011_0 is 112 113 protected body Key_PO is 114 procedure Set (K : Key_Enum) is 115 begin 116 Current := K; 117 end Set; 118 119 function Value return Key_Enum is 120 begin 121 return Current; 122 end Value; 123 end Key_PO; 124 125 126 procedure Listen_For_Input (Key : out Key_Enum) is 127 begin 128 -- Model the situation where the user does not press cancel thus 129 -- allowing validation to complete 130 131 delay TC_Delay_Time; -- Long enough to force queuing on 132 -- Keyboard.Cancel_Pressed. 133 134 Key := Key_PO.Value; 135 136 end Listen_For_Input; 137 138 139 140 -- One of these gets created as "Keyboard" for each transaction 141 -- 142 task body ATM_Keyboard_Task is 143 Key_Pressed : Key_Enum; 144 begin 145 loop 146 -- Force entry calls 147 Listen_For_Input (Key_Pressed); -- to be queued, 148 149 select 150 when (Key_Pressed = Cancel) => 151 accept Cancel_Pressed do 152 TC_Rendezvous_Entered := True; 153 end Cancel_Pressed; 154 155 -- User has cancelled the transaction so we exit the 156 -- loop and allow the task to terminate 157 exit; 158 else 159 delay ImpDef.Switch_To_New_Task; 160 end select; 161 162 end loop; 163 exception 164 when others => 165 Report.Failed ("Unexpected Exception in ATM_Keyboard_Task"); 166 end ATM_Keyboard_Task; 167 168 169 170 procedure Read_Card (Card : in out ATM_Card_Type) is 171 begin 172 Card.Number := 9999; 173 Card.PIN := 111; 174 end Read_Card; 175 176 177 procedure Validate_Card (Card : in ATM_Card_Type) is 178 begin 179 Count := (Count + 1) mod Integer (Card.PIN); 180 181 -- Simulate a validation activity which is longer than the time 182 -- taken in Listen_For_Input but not inordinately so. 183 delay TC_Delay_Time * 2; 184 185 end Validate_Card; 186 187 188 procedure Perform_Transaction (Card : in ATM_Card_Type) is 189 begin 190 if TC_Rendezvous_Entered then 191 Report.Failed ("Triggering statement completed"); 192 end if; 193 if Count = 1234 then 194 -- Initial value is unchanged 195 Report.Failed ("Abortable part did not execute"); 196 end if; 197 if not TC_Abortable_Part_Completed then 198 Report.Failed ("Abortable part did not complete"); 199 end if; 200 end Perform_Transaction; 201 202 203end C974011_0; 204 205 206 --==================================================================-- 207 208 209with Report; 210 211with C974011_0; -- Automated teller machine abstraction. 212use C974011_0; 213 214procedure C974011 is 215 216 Card_Data : ATM_Card_Type; 217 218begin -- Main program. 219 220 Report.Test ("C974011", "Asynchronous Select: Trigger is queued on a " & 221 "task entry and the abortable part " & 222 "completes first"); 223 224 Read_Card (Card_Data); 225 226 declare 227 -- Create the task for this transaction 228 Keyboard : C974011_0.ATM_Keyboard_Task; 229 begin 230 231 -- -- 232 -- Asynchronous select is tested here -- 233 -- -- 234 235 select 236 237 Keyboard.Cancel_Pressed; -- Entry call is initially queued, so 238 -- abortable part starts. 239 raise Transaction_Canceled; -- This would be executed if we 240 -- completed the rendezvous 241 then abort 242 243 Validate_Card (Card_Data); 244 TC_Abortable_Part_Completed := true; 245 246 end select; 247 248 Perform_Transaction (Card_Data); 249 250 251 -- Now clear the entry barrier to allow the rendezvous to complete 252 -- if the triggering call has not been cancelled 253 Key_PO.Set (Cancel); 254 -- 255 delay TC_Delay_Time; -- to allow it all to take place 256 257 if TC_Rendezvous_Entered then 258 Report.Failed ("Triggering Call was not cancelled"); 259 end if; 260 261 abort Keyboard; -- clean up. (Note: the task will only exit the 262 -- loop and terminate if the call hanging on the 263 -- entry is executed.) 264 265 exception 266 when Transaction_Canceled => 267 Report.Failed ("Triggering alternative sequence of statements " & 268 "executed"); 269 when Others => 270 Report.Failed ("Unexpected exception in the Main"); 271 end; 272 273 Report.Result; 274 275end C974011; 276