?? RIGHT := 110 ??
?? NEWTITLE := 'NOS/VE Network Access: UDP Service Routines Ring 1' ??
MODULE nlm$udp_service_routines_r1;
?? RIGHT := 110 ??

{ PURPOSE:
{   This module contains service routines that execute in Ring 1 and are called
{   by the UDP Access Agent.
{ DESIGN:
{   These procedures update fields in tables that can be written from ring 1 only.
{   It contains procedures to activate and deactivate receiver for a UDP socket.
{   This module contains code that executes in ring 1. It resides on OSF$SYSTEM_CORE_113.
{
{ NOTES:
{   The following abbreviations have been used in this module:
{          UDP - User Datagram Protocol

?? NEWTITLE := 'Global Declarations Referenced by This Module', EJECT ??
?? PUSH (LISTEXT := ON) ??
*copyc nlt$cl_connection
*copyc nlt$udp_active_receiver
*copyc ost$signature_lock_status
?? POP ??
*copyc pmp$get_executing_task_gtid
*copyc syp$cycle
*copyc osv$mainframe_wired_heap
?? OLDTITLE ??
?? NEWTITLE := 'Global Declarations Declared by This Module', EJECT ??

  TYPE
    t$udp_active_receiver_converter = record
      case boolean of
      = TRUE =
        value: nlt$udp_active_receiver,
      = FALSE =
        i: integer,
      casend,
    recend;

?? OLDTITLE ??
?? NEWTITLE := '[XDCL, #GATE] nlp$udp_activate_receiver', EJECT ??
*copy nlh$udp_activate_receiver

  PROCEDURE [XDCL, #GATE] nlp$udp_activate_receiver
    (    active_receiver: ^nlt$udp_active_receiver;
     VAR another_receiver_active: boolean);

    VAR
      active_receiver_ring1: ^nlt$udp_active_receiver,
      actual_active_receiver: nlt$udp_active_receiver,
      current_task_id: ost$global_task_id,
      initial_active_receiver: t$udp_active_receiver_converter,
      new_active_receiver: nlt$udp_active_receiver,
      result: osc$cs_successful .. osc$cs_variable_locked;

    another_receiver_active := FALSE;
    pmp$get_executing_task_gtid (current_task_id);
    active_receiver_ring1 := #ADDRESS (1, #SEGMENT (active_receiver), #OFFSET (active_receiver));

    initial_active_receiver.i := 0;
    new_active_receiver.task_id := current_task_id;
    new_active_receiver.fill := 0;
    REPEAT
      #COMPARE_SWAP (active_receiver_ring1^, initial_active_receiver, new_active_receiver,
            actual_active_receiver, result);
      IF result = osc$cs_failed THEN
        another_receiver_active := TRUE;
      IFEND;
    UNTIL result <> osc$cs_variable_locked;

  PROCEND nlp$udp_activate_receiver;
?? OLDTITLE ??
?? NEWTITLE := '[XDCL, #GATE] nlp$udp_allocate_receiver', EJECT ??
*copy nlh$udp_allocate_receiver

  PROCEDURE [XDCL, #GATE] nlp$udp_allocate_receiver
    (VAR active_receiver: ^nlt$udp_active_receiver);

    VAR
      active_receiver_ring1: ^nlt$udp_active_receiver,
      initial_active_receiver: t$udp_active_receiver_converter;

    REPEAT
      ALLOCATE active_receiver_ring1 IN osv$mainframe_wired_heap^;
      IF active_receiver_ring1 = NIL THEN
        syp$cycle;
      IFEND;
    UNTIL active_receiver_ring1 <> NIL;
    initial_active_receiver.i := 0;
    active_receiver_ring1^ := initial_active_receiver.value;
    active_receiver := active_receiver_ring1;

  PROCEND nlp$udp_allocate_receiver;
?? OLDTITLE ??
?? NEWTITLE := '[XDCL, #GATE] nlp$udp_deactivate_receiver', EJECT ??
*copy nlh$udp_deactivate_receiver

  PROCEDURE [XDCL, #GATE] nlp$udp_deactivate_receiver
    (    active_receiver: ^nlt$udp_active_receiver);

    VAR
      active_receiver_ring1: ^nlt$udp_active_receiver,
      actual_active_receiver: nlt$udp_active_receiver,
      initial_active_receiver: nlt$udp_active_receiver,
      new_active_receiver: t$udp_active_receiver_converter,
      result: osc$cs_successful .. osc$cs_variable_locked;

    active_receiver_ring1 := #ADDRESS (1, #SEGMENT (active_receiver), #OFFSET (active_receiver));
    pmp$get_executing_task_gtid (initial_active_receiver.task_id);
    initial_active_receiver.fill := 0;
    new_active_receiver.i := 0;

    REPEAT
      #COMPARE_SWAP (active_receiver_ring1^, initial_active_receiver, new_active_receiver,
            actual_active_receiver, result);
    UNTIL result = osc$cs_successful;

  PROCEND nlp$udp_deactivate_receiver;
?? OLDTITLE ??
?? NEWTITLE := '[XDCL, #GATE] nlp$udp_deallocate_receiver', EJECT ??
*copy nlh$udp_deallocate_receiver

  PROCEDURE [XDCL, #GATE] nlp$udp_deallocate_receiver
    (VAR active_receiver: ^nlt$udp_active_receiver);

    VAR
      active_receiver_ring1: ^nlt$udp_active_receiver;

    active_receiver_ring1 := #ADDRESS (1, #SEGMENT (active_receiver), #OFFSET (active_receiver));
    FREE active_receiver_ring1 IN osv$mainframe_wired_heap^;

  PROCEND nlp$udp_deallocate_receiver;
?? OLDTITLE ??
?? NEWTITLE := '[XDCL, #GATE] nlp$udp_store_receiver', EJECT ??
*copy nlh$udp_store_receiver

  PROCEDURE [XDCL, #GATE] nlp$udp_store_receiver
    (    active_receiver: ^nlt$udp_active_receiver;
         cl_connection: ^nlt$cl_connection);

    VAR
      active_receiver_ring1: ^nlt$udp_active_receiver,
      cl_connection_ring1: ^nlt$cl_connection;

    active_receiver_ring1 := #ADDRESS (1, #SEGMENT (active_receiver), #OFFSET (active_receiver));
    cl_connection_ring1 := #ADDRESS (1, #SEGMENT (cl_connection), #OFFSET (cl_connection));
    cl_connection_ring1^.active_receiver := active_receiver_ring1;

  PROCEND nlp$udp_store_receiver;
?? OLDTITLE ??
MODEND nlm$udp_service_routines_r1;
