?? RIGHT := 110 ??
?? TITLE := 'NOS/VE Universal Task Support Procedures' ??
MODULE osm$universal_task_support;

{  PURPOSE:
{    This module contains service routines involving universal task id.

?? NEWTITLE := '    Global Declarations Referenced by this Module' ??

?? PUSH (LISTEXT := ON) ??
*copyc dft$rpc_parameters
*copyc dft$rpc_queue_entry_location
*copyc dft$server_location
*copyc ost$df_ready_task_with_utid
*copyc ost$global_task_id
*copyc ost$status
*copyc ost$universal_task_id
*copyc ost$universal_task_id_mask
*copyc pmt$binary_mainframe_id
*copyc pmt$mainframe_id
*copyc pmt$task_id
?? POP ??
?? EJECT ??
*copyc dfp$send_remote_procedure_call
*copyc osp$set_status_from_condition
*copyc pmp$convert_binary_mainframe_id
*copyc pmp$get_binary_mainframe_id
*copyc pmp$get_executing_task_gtid
*copyc pmp$ready_task

?? TITLE := '[XDCL, #GATE] osp$get_universal_task_id', EJECT ??
*copy osh$get_universal_task_id

  PROCEDURE [XDCL, #GATE] osp$get_universal_task_id
    (VAR universal_task_id: ost$universal_task_id;
     VAR status: ost$status);

    VAR
      converted_task_id: ost$universal_task_id_mask;


    status.normal := TRUE;
    converted_task_id.padding := 0;

    pmp$get_executing_task_gtid (converted_task_id.global_task_id);
    pmp$get_binary_mainframe_id (converted_task_id.binary_mainframe_id, status);
    IF status.normal THEN
      universal_task_id := converted_task_id.universal_task_id;
    IFEND;

  PROCEND osp$get_universal_task_id;
?? TITLE := '[XDCL, #GATE] osp$ready_universal_task', EJECT ??
*copy osh$ready_universal_task

  PROCEDURE [XDCL, #GATE] osp$ready_universal_task
    (    universal_task_id: ost$universal_task_id;
     VAR status: ost$status);

?? NEWTITLE := 'dfp$remote_procedure_call_ch', EJECT ??

{ PURPOSE:
{   This procedure is a condition handler established to call a routine to clear the assignment of a task
{   services queue_entry if a task aborts with a queue_entry assigned to it.  The queue_entry must be clear
{   before the task can safely exit.

    PROCEDURE dfp$remote_procedure_call_ch
      (    condition: pmt$condition;
           cond_desc: ^pmt$condition_information;
           save: ^ost$stack_frame_save_area;
       VAR handler_status: ost$status);

      dfp$ch_cleanup;
      osp$set_status_from_condition (dfc$file_server_id, condition, save, status, handler_status);
      EXIT osp$ready_universal_task;

    PROCEND dfp$remote_procedure_call_ch;
*block
*copyc dfp$begin_ch_remote_proc_call
*copyc dfp$end_ch_remote_proc_call
*blockend
?? OLDTITLE, EJECT ??
    VAR
      binary_mainframe_id: pmt$binary_mainframe_id,
      global_task_id: ost$global_task_id,
      ignore_status: ost$status,
      mainframe_id: pmt$mainframe_id,
      p_receive_data: dft$p_receive_data,
      p_receive_from_server_params: dft$p_receive_parameters,
      p_send_data: dft$p_send_data,
      p_send_parameters: ^ost$df_ready_task_with_utid_inp,
      p_send_to_server_params: dft$p_send_parameters,
      parameter_size: dft$send_parameter_size,
      queue_entry_location: dft$rpc_queue_entry_location,
      server_location: dft$server_location,
      utid_converter: ost$universal_task_id_mask;

    status.normal := TRUE;

    utid_converter.universal_task_id := universal_task_id;
    pmp$get_binary_mainframe_id (binary_mainframe_id, ignore_status);
    IF utid_converter.binary_mainframe_id = binary_mainframe_id THEN
      pmp$ready_task (utid_converter.global_task_id, status);

    ELSE {Task executes on a different mainframe}
      server_location.server_location_selector := dfc$mainframe_id;
      pmp$convert_binary_mainframe_id (utid_converter.binary_mainframe_id, server_location.server_mainframe,
           status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;
      dfp$begin_ch_remote_proc_call (server_location, { Allowed when deactivated = } FALSE,
           queue_entry_location, p_send_to_server_params, p_send_data, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;

      NEXT p_send_parameters IN p_send_to_server_params;
      p_send_parameters^.utid_converter := utid_converter;
      parameter_size := #SIZE (utid_converter);
      dfp$send_remote_procedure_call (queue_entry_location, dfc$r2_df_server_ready_univ_tsk,
           parameter_size, 0, p_receive_from_server_params, p_receive_data, status);
      IF status.normal THEN
        dfp$end_ch_remote_proc_call (queue_entry_location, status);
      ELSE
        dfp$end_ch_remote_proc_call (queue_entry_location, ignore_status);
      IFEND;
    IFEND;
  PROCEND osp$ready_universal_task;
?? TITLE := '[XDCL] osp$server_ready_task', EJECT ??

  PROCEDURE [XDCL] osp$server_ready_task
    (VAR p_params_from_client {Input} : dft$p_receive_parameters;
     VAR p_data_from_client {Input} : dft$p_receive_data;
     VAR p_params_to_server {^Output} : dft$p_send_parameters;
     VAR p_data_to_server {^Output} : dft$p_send_data;
     VAR send_parameters_size: dft$send_parameter_size;
     VAR send_data_size: dft$send_data_size;
     VAR status: ost$status);

    VAR
      p_input_params: ^ost$df_ready_task_with_utid_inp;

    status.normal := TRUE;
    send_data_size := 0;
    send_parameters_size := 0;

    NEXT p_input_params IN p_params_from_client;
    pmp$ready_task (p_input_params^.utid_converter.global_task_id, status);

  PROCEND osp$server_ready_task;

MODEND osm$universal_task_support;
