?? RIGHT := 110 ??
?? NEWTITLE := 'NOS/VE: Disk Fault Tolerance (113)' ??
MODULE osm$disk_fault_tolerance_113;
?? NEWTITLE := 'Global Declarations Referenced by This Module', EJECT ??
?? PUSH (LISTEXT := ON) ??
*copyc osd$integer_limits
*copyc ose$disk_ft_exceptions
?? POP ??
*copyc i#current_sequence_position
*copyc osp$clear_mainframe_sig_lock
*copyc osp$copy_exception_policies
*copyc osp$set_status_condition
*copyc osp$test_set_main_sig_lock
*copyc osp$test_sig_lock
*copyc osv$mainframe_pageable_heap
?? OLDTITLE ??
?? NEWTITLE := 'Global Declarations Declared by This Module', EJECT ??

  VAR
    exception_policies_lock: [oss$mainframe_pageable] ost$signature_lock := [0],
    osv$installed_policies: [XDCL, #GATE, oss$mainframe_pageable] ^SEQ ( * ) := NIL;

?? OLDTITLE ??
?? NEWTITLE := '[XDCL, #GATE] osp$r1_get_installed_policies', EJECT ??

  PROCEDURE [XDCL, #GATE] osp$r1_get_installed_policies
    (VAR installed_policies: ^SEQ ( * );
     VAR status: ost$status);

    set_mainframe_sig_lock (exception_policies_lock, status);

    IF status.normal THEN
      IF osv$installed_policies <> NIL THEN
        IF (installed_policies <> NIL) AND (#SIZE (osv$installed_policies^) >=
              #SIZE (installed_policies)) THEN
          RESET installed_policies;
          osp$copy_exception_policies (osv$installed_policies, installed_policies, status);
        ELSE
          {Caller provided insufficient space; someone locked and replaced the installed policies
          {after the caller estimated the size of the policies by reading osv$installed_policies
          {without holding the lock.
          osp$set_status_condition (ose$exception_policies_locked, status);
        IFEND;
      ELSE
        osp$set_status_condition (ose$no_policies_installed, status);
      IFEND;
      clear_mainframe_sig_lock (exception_policies_lock);
    IFEND;

  PROCEND osp$r1_get_installed_policies;
?? OLDTITLE ??
?? NEWTITLE := '[XDCL, #GATE] osp$r1_install_exception_policy', EJECT ??

  PROCEDURE [XDCL, #GATE] osp$r1_install_exception_policy
    (    session_policies: ^SEQ ( * );
     VAR status: ost$status);

    VAR
      installed_sequence: ^SEQ ( * ),
      session_sequence: ^SEQ ( * ),
      size: ost$positive_integers;

    set_mainframe_sig_lock (exception_policies_lock, status);
    IF status.normal THEN
      size := i#current_sequence_position (session_policies);

      session_sequence := session_policies;
      RESET session_sequence;

      ALLOCATE installed_sequence: [[REP size OF cell]] IN osv$mainframe_pageable_heap^;
      RESET installed_sequence;

      osp$copy_exception_policies (session_sequence, installed_sequence, status);

      IF status.normal THEN
        IF osv$installed_policies <> NIL THEN
          FREE osv$installed_policies IN osv$mainframe_pageable_heap^;
        IFEND;
        RESET installed_sequence;
        osv$installed_policies := installed_sequence;
      IFEND;

      clear_mainframe_sig_lock (exception_policies_lock);
    IFEND;

  PROCEND osp$r1_install_exception_policy;
?? OLDTITLE ??
?? NEWTITLE := '[XDCL, #GATE] osp$r1_lock_policies', EJECT ??

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

    set_mainframe_sig_lock (exception_policies_lock, status);

  PROCEND osp$r1_lock_policies;
?? OLDTITLE ??
?? NEWTITLE := '[XDCL, #GATE] osp$r1_unlock_policies', EJECT ??

  PROCEDURE [XDCL, #GATE] osp$r1_unlock_policies;

    clear_mainframe_sig_lock (exception_policies_lock);

  PROCEND osp$r1_unlock_policies;
?? OLDTITLE ??
?? NEWTITLE := 'clear_mainframe_sig_lock', EJECT ??

  PROCEDURE clear_mainframe_sig_lock
    (VAR lock: ost$signature_lock);

    VAR
      lock_status: ost$signature_lock_status,
      locked: boolean;

    osp$test_sig_lock (lock, lock_status);
    IF lock_status = osc$sls_locked_by_current_task THEN
      osp$clear_mainframe_sig_lock (lock);
    IFEND;

  PROCEND clear_mainframe_sig_lock;

?? OLDTITLE ??
?? NEWTITLE := 'set_mainframe_sig_lock', EJECT ??

  PROCEDURE set_mainframe_sig_lock
    (VAR lock: ost$signature_lock;
     VAR status: ost$status);

    VAR
      local_status: ost$status,
      lock_status: ost$signature_lock_status,
      locked: boolean;

    status.normal := TRUE;

    osp$test_sig_lock (lock, lock_status);
    IF lock_status = osc$sls_locked_by_current_task THEN
      clear_mainframe_sig_lock (lock);
    ELSEIF lock_status = osc$sls_locked_by_another_task THEN
      osp$set_status_condition (ose$exception_policies_locked, status);
    IFEND;

    IF status.normal THEN
      osp$test_set_main_sig_lock (lock, locked);
      IF NOT locked THEN
        osp$set_status_condition (ose$exception_policies_locked, status);
      IFEND;
    IFEND;

  PROCEND set_mainframe_sig_lock;

?? OLDTITLE ??
MODEND osm$disk_fault_tolerance_113;
