?? RIGHT := 110 ??
*copyc osd$default_pragmats
?? NEWTITLE := 'Module iim$interrupt_timesharing_io' ??
?? NEWTITLE := 'Global Declarations' ??
  MODULE iim$interrupt_timesharing_io;
?? PUSH (LISTEXT := ON) ??
*copyc ifc$interrupt_timesharing_io
*copyc ife$error_codes
?? POP ??
*copyc iip$vt_flush_input
*copyc oss$job_paged_literal
*copyc oss$task_shared
*copyc oss$task_private
*copyc osp$decrement_locked_variable
*copyc osp$generate_log_message
*copyc osp$set_status_abnormal
*copyc osp$system_error
*copyc pmp$cause_condition
*copyc pmp$wait

*copyc iiv$connection_desc_ptr
*copyc iiv$interactive_terminated

  VAR
    iiv$io_requests_in_job: [XDCL , oss$task_shared] integer {ALIGNED [0 MOD 8]} := 0,
    iiv$io_requests_in_task: [XDCL , oss$task_private] integer :=0;

?? TITLE := '[XDCL] iip$interrupt_timesharing_io', EJECT ??

    PROCEDURE [XDCL, #GATE] iip$interrupt_timesharing_io (VAR status: ost$status);

      VAR
        decrement_error: boolean,
        io_requests_in_job: integer,
        ignore_status: ost$status,
        initial_put_info: [READ, oss$job_paged_literal] iit$task_put_info := [1, 0,
          amc$terminate, FALSE, FALSE, FALSE, 0];

      status.normal := TRUE;
      ignore_status.normal := TRUE;

      WHILE iiv$io_requests_in_job > 0 DO
        IF iiv$io_requests_in_job = iiv$io_requests_in_task THEN
          pmp$cause_condition(ifc$interrupt_timesharing_io, NIL, ignore_status);
          IF iiv$io_requests_in_task > 0 THEN

{ This implies that the current task was pulled out of an io-attempt due to
{ termination - io_request_counts will be off - can locks be set?? - do we care??
{ We must re-adjust the counts by decrementing the job count by the task count.
{ The decrement of the job count must be locked - another task may try to start io.
{ This should yield us the exit condition for the while loop.

            WHILE iiv$io_requests_in_task > 0 DO
              iiv$io_requests_in_task := iiv$io_requests_in_task - 1;
              osp$decrement_locked_variable (iiv$io_requests_in_job, iiv$io_requests_in_job,
                    io_requests_in_job, decrement_error);
            WHILEND;

          IFEND;
        ELSE
          pmp$wait (100, 100);
        IFEND;
      WHILEND;
      { Empty upline and downline queues.}
      { Note - the following references to iiv$connection_desc_ptr assume that
      { any interrupt can be presumed to relate to the first (nominal)
      { connection.  In release 1.2.1, timesharing jobs can have only one
      { connection, and it is nominal, while the system job can have multiple
      { connections, of which none are nominal.

      { It is possible for timesharing interrupts to occur when the connection
      { description has not been defined.

      IF iiv$connection_desc_ptr <> NIL THEN
        RESET iiv$connection_desc_ptr^.output_buffer_entry_loc;
        RESET iiv$connection_desc_ptr^.output_buffer_exit_loc;
        iiv$connection_desc_ptr^.downline_queue_count := 0;
        iiv$connection_desc_ptr^.put_info := initial_put_info;
        iip$vt_flush_input (iiv$connection_desc_ptr^.vtp_connection_id, ignore_status);
      IFEND;

    PROCEND iip$interrupt_timesharing_io;

  MODEND iim$interrupt_timesharing_io;
