*copyc OSD$DEFAULT_PRAGMATS
MODULE icm$write_end_partition;
?? TITLE := 'MODULE icm$write_end_partition' ??

?? PUSH (LISTEXT := ON) ??
*copyc AMT$FILE_BYTE_ADDRESS
*copyc AMT$FILE_POSITION
*copyc amc$fap_request_codes
*copyc AMT$MAX_BLOCK_LENGTH
*copyc AMT$TERM_OPTION
*copyc AMT$TRANSFER_COUNT
*copyc AME$PUT_VALIDATION_ERRORS
*copyc AMT$WORKING_STORAGE_LENGTH
*copyc AMP$SET_FILE_INSTANCE_ABNORMAL
*copyc ICE$ERROR_CODES
*copyc ICF$OPEN_FILE_DESCRIPTOR
*copyc ICP$PUT
*copyc ICP$SET_STATUS_ABNORMAL
*copyc ICP$STATUS_PARTNER_JOB
*copyc IFE$ERROR_CODES
*copyc MLP$FETCH_LINK_PARTNER_INFO
*copyc MLP$SEND_MESSAGE
*copyc OSP$DISESTABLISH_COND_HANDLER
*copyc OSP$ESTABLISH_CONDITION_HANDLER
*copyc OSP$SET_STATUS_ABNORMAL
*copyc PMP$CONTINUE_TO_CAUSE
*copyc PMP$EXIT
*copyc PMP$LONG_TERM_WAIT
*copyc PMP$WAIT
?? POP ??

?? NEWTITLE := 'PROCEDURE icp$write_end_partition' ??
{  ICP$WRITE_END_PARTITION
{
{     The purpose of this procedure is to send an EOP indication
{ to the 170 partner job.

  PROCEDURE [XDCL] icp$write_end_partition
    (    icf_file: ^icf_open_file_descriptor;
         operation: amt$fap_operation;
     VAR status: ost$status);

    VAR
      ptr: ^cell,
      eop: boolean,
      first_message: boolean,
      last_message: boolean,
      last_op: mlt$operation,
      arbitrary_info: mlt$arbitrary_info,
      signal_record: mlt$signal_record,
      signal: mlt$signal,
      partner_stat: ict$status_partner_status,
      stat: ost$status;


    PROCEDURE handle_break
      (    cond: pmt$condition;
           condition_info: ^pmt$condition_information;
           stack_frame_save_area: ^ost$stack_frame_save_area;
       VAR break_status: ost$status);

      VAR
        local_status: ost$status;

      IF (cond.selector = ifc$interactive_condition) THEN
        IF cond.interactive_condition = ifc$pause_break THEN
          osp$set_status_abnormal (ifc$interactive_facility_id,
                ife$pause_break_received, '', status);
        ELSEIF cond.interactive_condition = ifc$terminate_break THEN
          osp$set_status_abnormal (ifc$interactive_facility_id,
                ife$terminate_break_received, '', status);
        IFEND;
        pmp$continue_to_cause (pmc$execute_standard_procedure, local_status);
        EXIT icp$write_end_partition;
      IFEND;
      break_status.normal := TRUE;
      RETURN;
    PROCEND handle_break;

{ Begin procedure ICM$WRITE_END_PARTITION.

    status.normal := TRUE;
    osp$establish_condition_handler (^handle_break, FALSE);
    IF NOT icf_file^.opened_for_put THEN
      amp$set_file_instance_abnormal (icf_file^.file_id,
            ame$improper_output_attempt, operation, '', status);
      osp$disestablish_cond_handler;
      RETURN;
    IFEND;

{  Terminate any prior partial record.

    ptr := icf_file;
    IF icf_file^.position = amc$mid_record THEN
      icp$put (icf_file, amc$put_next_req, ptr, 0, amc$terminate, stat);
      IF NOT stat.normal THEN
        osp$disestablish_cond_handler;
        pmp$exit (stat);
      IFEND;
    IFEND;
    signal := ^signal_record;
    eop := TRUE;
    first_message := TRUE;
    last_message := TRUE;
    arbitrary_info := $INTEGER (eop) * 4 + $INTEGER (first_message) *
          2 + $INTEGER (last_message);

{  Send the EOP indication.

  /loop/
    WHILE TRUE DO

      mlp$send_message (icf_file^.application_name, arbitrary_info, signal,
            ptr, 0, icf_file^.partner_id.application_name, stat);

      IF (stat.normal) OR (stat.condition = mlc$ok) OR (stat.condition =
            mlc$signal_failed_ignored) OR (stat.condition =
            mlc$signal_to_c170_ignored) THEN
        EXIT /loop/;
      ELSE
        CASE stat.condition OF
        = mlc$busy_interlock, mlc$pool_buffer_not_avail =
          pmp$wait (icf_short_interval, icf_short_interval);
          CYCLE /loop/;
        = mlc$receiver_not_signed_on =
          icp$status_partner_job (icf_file^.partner_id, partner_stat, stat);
          IF stat.normal THEN
            IF partner_stat = icc$partner_not_found THEN
              amp$set_file_instance_abnormal (icf_file^.file_id,
                    ice$partner_ended, operation, '', status);
              RETURN;
            ELSE
              pmp$long_term_wait (icf_interval, icf_interval);
              CYCLE /loop/;
            IFEND;
          ELSE
            osp$disestablish_cond_handler;
            pmp$exit (stat);
          IFEND;
        = mlc$prior_msg_not_received, mlc$receive_list_full =

        /flpi_loop/
          WHILE TRUE DO
            mlp$fetch_link_partner_info (icf_file^.application_name,
                  icf_file^.partner_id.application_name, last_op, stat);
            IF (stat.normal) OR (stat.condition = mlc$ok) THEN
              EXIT /flpi_loop/;
            ELSE
              CASE stat.condition OF
              = mlc$busy_interlock =
                pmp$wait (icf_short_interval, icf_short_interval);
                CYCLE /flpi_loop/;
              = mlc$receiver_not_signed_on =
                icp$status_partner_job (icf_file^.partner_id, partner_stat,
                    stat);
                IF stat.normal THEN
                  IF partner_stat = icc$partner_not_found THEN
                    amp$set_file_instance_abnormal
                          (icf_file^.file_id, ice$partner_ended, operation, '',
                          status);
                    RETURN;
                  ELSE
                    pmp$long_term_wait (icf_interval, icf_interval);
                    CYCLE /loop/;
                  IFEND;
                ELSE
                  osp$disestablish_cond_handler;
                  pmp$exit (stat);
                IFEND;
              ELSE
                icp$set_status_abnormal (stat);
                osp$disestablish_cond_handler;
                pmp$exit (stat);
              CASEND;
            IFEND;
          WHILEND /flpi_loop/;

          IF ((last_op.req = mlc$send_message_req) OR
                (last_op.req = mlc$confirm_send_req)) AND
                ((last_op.stat_condition = mlc$prior_msg_not_received) OR
                (last_op.stat_condition = mlc$receive_list_full)) THEN
            amp$set_file_instance_abnormal (icf_file^.file_id,
                  ice$write_deadlock, operation, '', status);
            osp$disestablish_cond_handler;
            RETURN;
          ELSE
            pmp$long_term_wait (icf_interval, icf_interval);
            CYCLE /loop/;
          IFEND;
        ELSE
          icp$set_status_abnormal (stat);
          osp$disestablish_cond_handler;
          pmp$exit (stat);
        CASEND;
      IFEND;
    WHILEND /loop/;

{  Store the file position information.

    icf_file^.position := amc$eop;
    osp$disestablish_cond_handler;

  PROCEND icp$write_end_partition;

MODEND icm$write_end_partition;
