*DECK DB$GETN 
USETEXT CDCSCTX 
      PROC DB$GETN; 
      BEGIN 
 #
* *   DB$GETN -- CRM SEQUENTIAL GET PROCESSOR    PAGE  1
* *   C O GIMBER                                 12/4/76
* 
* DC  PURPOSE 
* 
*     DO A CRM SEQUENTIAL GET ON THE AREA AND LOCK THE RECORD READ. 
* 
* DC  ENTRY CONDITIONS
* 
*     ALL APPROPRIATE FIT FIELDS ARE SET. 
*     P<RSARBLK> IS SET.
* 
* DC  EXIT CONDITIONS 
* 
*     P<RSARBLK> IS SET 
*     NORMAL EXIT 
*       CRM GETN PERFORMED
*       IF AREA IS OPENED FOR I/O THEN THE RECORD IS LOCKED.
*     ABNORMAL EXIT 
*       EXIT THRU ERROR ROUTINE OR END OF DATA ROUTINE SPECIFIED IN FIT.
* 
* DC  CALLED ROUTINES 
# 
      XREF PROC DB$ERR;      #CDCS ERROR PROCESSER# 
      XREF PROC DB$FLOP;     #GENERATE FLOW POINT                      #
      XREF PROC DB$FPOS;     #RESTORE ACCESS KEYS TO FIAT (REPOSITION) #
      XREF PROC DB$FSAV;     #SAVE KEYS OF ACCESS                      #
      XREF PROC DB$FSET;     #SELECT AND SET A FIT                     #
      XREF PROC DB$FTDX;     #END OF INFORMATION PROCESSOR             #
      XREF PROC GETN;        #CRM GET NEXT# 
      XREF PROC GETNR;       #CRM GET NEXT NO RECALL# 
      XREF PROC DB$LOK;      #RECORD LOCK PROCESSOR#
      XREF PROC DB$LOKD;     #LOCK DELETE PROCESSOR#
      XREF PROC DB$POP;      #POP ENTRY FROM STACK# 
      XREF PROC DB$PUSH;     #PUSH ENTRY INTO STACK#
      XREF PROC DB$SCHD;     #CDCS SCHEDULER# 
      XREF PROC SKIP;        #CRM SKIP PROCESSOR# 
# 
* DC  NON-LOCAL VARIABLES 
# 
      XREF ARRAY DB$RA0;;    #USED TO TERMINATE PARAMETER LISTS#
# 
*     CDCS COMMON 
 #
# 
*     LOCAL VARIABLES 
# 
      BASED ARRAY FIT;
*CALL FITDCLS 
      ITEM INDEX;            #SCRATCH ITEM# 
      BASED ARRAY WSA;       #WSA FOR NEW FIT#
        BEGIN 
        ITEM WSAWORD; 
        ITEM WSAKEY C(0,0,240); 
        END 
  
  
  
#     B E G I N   D B $ G E T N   E X E C U T A B L E   C O D E .      #
  
#     GENERATE A FLOW POINT.                                           #
  
      CONTROL IFGR DFFLOP,0;
        DB$FLOP ("GETN"); 
      CONTROL ENDIF;
  
 #
* 
* DC  DESCRIPTION 
* 
*     PUSH ENTRY POINT. 
 #
      DB$PUSH(DB$GETN); 
 #
*     LOOP UNTIL RECORD READ WITHOUT QUEUEING.
 #
      LOKSTATUS = FALSE;
      FOR INDEX=INDEX WHILE NOT LOKSTATUS DO
        BEGIN 
        DB$FSET;             # SELECT AND SET A FIT                    #
        IF FPCFPOS[0] 
        THEN                 # THE FIT HAS HAD ANOTHER USER.           #
          BEGIN 
          DB$FPOS;           # RESTORE PRIOR POSITION.                 #
          P<FIT> = LOC(UFFIT[0]); 
          IF FITEOI[0]
          THEN
            BEGIN 
            DB$FTDX;         # TAKE EOI EXIT                           #
            END 
          END 
 #
*       LOOP DOING GETNR UNTIL COMPLETE OR DFSEEKLIMIT TIMES. 
*       IF DONE DFSEEKLIMIT TIMES THEN DO NORMAL GETN.
 #
        RSARSEKCNT[0] = DFSEEKLIMIT;
        P<FIT> = LOC(UFFIT[0]); 
        FOR INDEX=INDEX DO
          BEGIN 
          P<OFT> = RSAROFIT[0]; 
          IF OFSTATUS[0] NQ S"UP" 
            AND OFSTATUS[0] NQ S"IDLING"
          THEN
            BEGIN                      # AREA NOT UP                   #
            DB$ERR(10); 
  
            END 
          GETNR(FIT,DB$RA0);
          IF FITFP[0] NQ 0
          THEN
            BEGIN 
            GOTO EXITCRMGETN; 
  
            END 
          DB$SCHD(-LOC(OFFITBZF[0]),DFWAITIO);  # INDIRECT THRU BZF    #
  
          CONTROL IFGR DFFLOP,0;
            ITEM GETFLOP C(10) = "GETN=00   ";
            B<36,6>GETFLOP = B<3,3>RSARSEKCNT[0] + O"33"; 
            DB$FLOP(GETFLOP); 
          CONTROL ENDIF;
  
          DB$FSET;           # SELECT A FIT FOR THE NEXT TRY.          #
                             # THE OLD ONE IS SELECTED                 #
                             # IF IT IS STILL AVAILABLE.               #
          IF FPCFPOS[0] 
          THEN               # THE FIT HAS HAD ANOTHER USER.           #
            BEGIN 
            DB$FPOS;         # RESTORE PRIOR POSITION.                 #
            P<FIT> = LOC(UFFIT[0]); 
            IF FITEOI[0]
            THEN
              BEGIN 
              DB$FTDX;       # TAKE EOI EXIT                           #
              END 
            END 
  
          P<FIT> = LOC(UFFIT[0]); 
          RSARSEKCNT[0] = RSARSEKCNT[0]-1;
          IF RSARSEKCNT[0] EQ 0 THEN
            BEGIN 
            GETN(FIT,DB$RA0); 
            GOTO EXITCRMGETN; 
  
            END 
          END 
  
EXITCRMGETN:  
 #
*     IF CRM ERROR OR END-OF-INFORMATION THEN 
*         EXIT
 #
      IF FITES[0] NQ 0
      OR FITEOI[0]
      THEN
          BEGIN 
          DB$LOKD(FALSE); 
  
          CONTROL IFGR DFFLOP,0;
            DB$FLOP ("GETN-3");        #GENERATE A FLOW POINT.         #
          CONTROL ENDIF;
  
          GOTO EXIT;
          END 
        P<OFT> = RSAROFIT[0]; 
        P<WSA> = UFFITWSA[0]; 
 #
*       LOCK RECORD WITHOUT QUEUEING. 
*       IF LOCK NOT OBTAINED THEN 
*         SKIP BACK ON FILE (MUST BE DONE WITHOUT INTERRUPTION AFTER
*         GETN HAS COMPLETED).
*       LOCK RECORD WITH QUEUEING.
*         DELETE LOCK.
*     SET LOCK STATUS FALSE, REREAD RECORD. 
 #
        DB$LOK(LOC(WSA)+OFPRIRKW[0],OFPRIRKP[0],FALSE); 
        IF NOT LOKSTATUS THEN 
          BEGIN 
  
          CONTROL IFGR DFFLOP,0;
            DB$FLOP ("GETN-4");        #GENERATE A FLOW POINT.         #
          CONTROL ENDIF;
  
          SKIP(FIT,-1,DB$RA0);
          DB$LOK(LOC(WSA)+OFPRIRKW[0],OFPRIRKP[0],TRUE);
          LOKSTATUS = FALSE;
          END  #IF NOT LOKSTATUS# 
        END  #WHILE NOT LOKSTATUS#
EXIT: 
 #
*     SAVE THE PRIMARY KEY (AND ALTERNATE KEY IF USED) SO THAT FILE 
*     POSITION CAN BE RE-ESTABLISHED IN THE EVENT THAT THIS UFT IS
*     USED IN ANOTHER SEQUENCE. 
 #
      DB$FSAV;
  
#     SAVE VALUES FROM THE UFT BEFORE IT CAN BE RE-ASSIGNED.           #
  
      FPFITFP[0] = UFFITFP[0];
      DB$POP(DB$GETN);
      END  #DB$GETN#
      TERM; 
