1-- C974003.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 abortable part of an asynchronous select statement 28-- is aborted if it does not complete before the triggering statement 29-- completes, where the triggering statement is a task entry call, and 30-- the entry call is queued. 31-- 32-- Check that the sequence of statements of the triggering alternative 33-- is executed after the abortable part is left. 34-- 35-- TEST DESCRIPTION: 36-- Declare a main procedure containing an asynchronous select with a task 37-- entry call as triggering statement. Force the entry call to be 38-- queued by having the task call a procedure, prior to the corresponding 39-- accept statement, which simulates a routine waiting for user input 40-- (with a delay). 41-- 42-- Simulate a time-consuming routine in the abortable part by calling a 43-- procedure containing an infinite loop. Meanwhile, simulate input by 44-- the user (the delay expires), which causes the task to execute the 45-- accept statement corresponding to the triggering entry call. 46-- 47-- 48-- CHANGE HISTORY: 49-- 06 Dec 94 SAIC ACVC 2.0 50-- 51--! 52 53package C974003_0 is -- Automated teller machine abstraction. 54 55 56 -- Flags for testing purposes: 57 -- 58 TC_Triggering_Statement_Completed : Boolean := False; 59 TC_Count : Integer := 1234; -- Global to defeat 60 -- optimization. 61 62 type Key_Enum is (None, Cancel, Deposit, Withdraw); 63 64 type Card_Number_Type is private; 65 type Card_PIN_Type is private; 66 type ATM_Card_Type is private; 67 68 69 Transaction_Canceled : exception; 70 71 72 task type ATM_Keyboard_Task is 73 entry Cancel_Pressed; 74 end ATM_Keyboard_Task; 75 76 77 procedure Read_Card (Card : in out ATM_Card_Type); 78 79 procedure Validate_Card (Card : in ATM_Card_Type); 80 81 procedure Perform_Transaction (Card : in ATM_Card_Type); 82 83private 84 85 type Card_Number_Type is range 1 .. 9999; 86 type Card_PIN_Type is range 100 .. 999; 87 88 type ATM_Card_Type is record 89 Number : Card_Number_Type; 90 PIN : Card_PIN_Type; 91 end record; 92 93end C974003_0; 94 95 96 --==================================================================-- 97 98 99with Report; 100with ImpDef; 101 102package body C974003_0 is 103 104 105 procedure Listen_For_Input (Key : out Key_Enum) is 106 begin 107 -- Model the situation where the user waits a bit for the card to 108 -- be validated, then presses cancel before it completes. 109 110 -- Delay long enough to force queuing of Keyboard.Cancel_Pressed. 111 delay ImpDef.Minimum_Task_Switch; 112 113 if Report.Equal (3, 3) then -- Always true. 114 Key := Cancel; 115 end if; 116 end Listen_For_Input; 117 118 119 120 -- One of these gets created as "Keyboard" for each transaction 121 -- 122 task body ATM_Keyboard_Task is 123 Key_Pressed : Key_Enum := None; 124 begin 125 loop 126 -- Force entry calls 127 Listen_For_Input (Key_Pressed); -- to be queued, 128 -- then set guard to 129 -- true. 130 select 131 when (Key_Pressed = Cancel) => -- Guard is now 132 accept Cancel_Pressed do -- true, so accept 133 TC_Triggering_Statement_Completed := True; -- queued entry 134 end Cancel_Pressed; -- call. 135 136 -- User has cancelled the transaction so we exit the 137 -- loop and allow the task to terminate 138 exit; 139 else 140 Key_Pressed := None; 141 end select; 142 143 end loop; 144 exception 145 when others => 146 Report.Failed ("Unexpected Exception in ATM_Keyboard_Task"); 147 end ATM_Keyboard_Task; 148 149 150 151 procedure Read_Card (Card : in out ATM_Card_Type) is 152 begin 153 Card.Number := 9999; 154 Card.PIN := 111; 155 end Read_Card; 156 157 158 procedure Validate_Card (Card : in ATM_Card_Type) is 159 begin 160 -- Simulate an exceedingly long validation activity. 161 loop -- Infinite loop. 162 TC_Count := (TC_Count + 1) mod Integer (Card.PIN); 163 -- Synch. point to allow transfer of control to Keyboard 164 -- task during this simulation 165 delay ImpDef.Minimum_Task_Switch; 166 exit when not Report.Equal (TC_Count, TC_Count); -- Always false. 167 end loop; 168 end Validate_Card; 169 170 171 procedure Perform_Transaction (Card : in ATM_Card_Type) is 172 begin 173 Report.Failed ("Triggering alternative sequence of statements " & 174 "not executed"); 175 if not TC_Triggering_Statement_Completed then 176 Report.Failed ("Triggering statement did not complete"); 177 end if; 178 if TC_Count = 1234 then 179 -- Initial value is unchanged 180 Report.Failed ("Abortable part did not execute"); 181 end if; 182 end Perform_Transaction; 183 184 185end C974003_0; 186 187 188 --==================================================================-- 189 190 191with Report; 192 193with C974003_0; -- Automated teller machine abstraction. 194use C974003_0; 195 196procedure C974003 is 197 198 Card_Data : ATM_Card_Type; 199 200begin -- Main program. 201 202 Report.Test ("C974003", "Asynchronous Select: Trigger is queued on a " & 203 "task entry and completes first"); 204 205 Read_Card (Card_Data); 206 207 declare 208 -- Create the task for this transaction 209 Keyboard : C974003_0.ATM_Keyboard_Task; 210 begin 211 212 -- -- 213 -- Asynchronous select is tested here -- 214 -- -- 215 216 select 217 Keyboard.Cancel_Pressed; -- Entry call is initially queued, so 218 -- abortable part starts. 219 220 raise Transaction_Canceled; -- This is executed after Validate_Card 221 -- is aborted. 222 then abort 223 Validate_Card (Card_Data); -- Keyboard.Cancel_Pressed is accepted 224 -- and completes before this call 225 -- finishes; it is then aborted. 226 227 -- Check that the whole of the abortable part is aborted, not 228 -- just the statement in the abortable part that was executing 229 -- at the time 230 Report.Failed ("Abortable part not aborted"); 231 232 end select; 233 234 Perform_Transaction (Card_Data); -- Should not be reached. 235 exception 236 when Transaction_Canceled => 237 if not TC_Triggering_Statement_Completed then 238 Report.Failed ("Triggering alternative sequence of statements " & 239 "executed but triggering statement not complete"); 240 end if; 241 if TC_Count = 1234 then 242 -- Initial value is unchanged 243 Report.Failed ("Abortable part did not execute"); 244 end if; 245 end; 246 247 Report.Result; 248 249end C974003; 250