--============================================================================= --| --| TASK NAME: numbers.search.synchronize --| --| ALGORITHM/STRATEGY: Wait for call to entry start_monitor, then start --| task monitor_keyboard. Main part of task accepts calls to either --| (1) keyboard_interrupt, followed by check_interrupts or --| (2) check_interrupts. --| --| NOTES: Several TERMINATE options on SELECT statements are required to --| assure proper termination under any reasonable sequence of events. --| --============================================================================= WITH other_io; WITH text_io; SEPARATE (numbers.search) TASK BODY synchronize IS -- New time requested between checkpoints checkpoint_interval : duration; -- Position of last character on input line last : natural; -- New new number of invocations of do_search.select_digits between checks -- for keyboard interrupt from user new_max_calls_to_select_digits : natural; -- Flag indicating (if true) that a prompt for a user command must be output repeat : Boolean; -- Input line entered by user response : string(1 .. line_length); BEGIN -- synchronize -- Wait for signal to begin monitoring keyboard for user commands ACCEPT start_monitor; -- Signal monitor_keyboard to accept user input monitor_keyboard.begin_keyboard_monitor; LOOP SELECT -- If user has requested service, calls are accepted first from -- task monitor_keyboard, then from task do_search ACCEPT keyboard_interrupt DO SELECT ACCEPT check_interrupts (flag : OUT interrupt_flag_type; interval : OUT duration; max_calls : OUT natural) DO repeat := true; WHILE repeat LOOP -- Prompt for user command text_io.put_line ("Enter ""r"" to resume search,"); text_io.put_line (" ""s"" for status check of search,"); text_io.put_line (" ""c"" to change checkpoint interval,"); text_io.put_line (" ""k"" to change keyboard polling" & " frequency, or"); text_io.put_line (" ""q"" to quit:"); -- Read user response text_io.get_line (item => response, last => last); -- Interpret user command IF (last = 1) THEN IF (response(1) = 'r') THEN -- Resumption of search requested text_io.new_line; flag := continue; repeat := false; ELSIF (response(1) = 's') THEN -- Status check requested flag := status; repeat := false; ELSIF (response(1) = 'c') THEN -- Checkpoint interval change requested LOOP BEGIN -- Prompt for and read new checkpoint interval text_io.put_line ("Enter new checkpoint interval in" & " seconds and tenths of seconds:"); other_io.duration_io.get (checkpoint_interval); text_io.skip_line; text_io.new_line; EXIT; EXCEPTION WHEN text_io.data_error => text_io.put_line ("Illegal value"); text_io.skip_line; END; END LOOP; flag := checkpoint_change; interval := checkpoint_interval; repeat := false; ELSIF (response(1) = 'k') THEN --Keyboard polling frequency change requested LOOP BEGIN -- Prompt for and read new polling frequency text_io.put_line ("Enter number of digits handled" & " between polling of keyboard:"); other_io.natural_io.get (new_max_calls_to_select_digits); text_io.skip_line; text_io.new_line; EXIT; EXCEPTION WHEN text_io.data_error => text_io.put_line ("Illegal value"); text_io.skip_line; END; END LOOP; flag := max_calls_change; max_calls := new_max_calls_to_select_digits; repeat := false; ELSIF (response(1) = 'q') THEN -- Program termination requested ABORT process_normal_input; ABORT do_search; ABORT monitor_keyboard; repeat := false; text_io.new_line; ELSE -- Unrecognized command text_io.new_line; END IF; ELSE -- Unrecognized command text_io.new_line; END IF; END LOOP; END check_interrupts; OR TERMINATE; END SELECT; SELECT -- Wait for signal that operation is complete ACCEPT clear_keyboard; OR TERMINATE; END SELECT; END keyboard_interrupt; OR -- If user has not requested service, check from task do_search -- comes here ACCEPT check_interrupts (flag : OUT interrupt_flag_type; interval : OUT duration; max_calls : OUT natural) DO -- Reply that no service is requested flag := no_interrupt; END check_interrupts; OR TERMINATE; END SELECT; END LOOP; END synchronize;