*DECK DB$TQTT 
USETEXT CDCSCTX 
      PROC DB$TQTT((CONTA),(OWNRCB)); 
      BEGIN 
 #
* *   DB$TQTT - TASK QUEUE TABLE TERMINATOR      PAGE  1
* *   BOB MCALLESTER                             DATE  12/14/81 
* 
* DC  PURPOSE 
* 
*     SET THE TQT TO A STATE THAT WILL CAUSE IT TO ENTER TERMINATION
*     PROCEDURES ON ITS NEXT EXECUTION. 
* 
* DC  ENTRY CONDITIONS
* 
* D   PARAMETERS
# 
      ITEM CONTA I;          # CONTINUATION ADDRESS OF THE TERMINATION #
                             # PROCEDURE                               #
      ITEM OWNRCB I;         # ADDRESS OF THE CURRENTLY ACTIVE RCB     #
# 
* D   ASSUMPTIONS 
* 
*     P<TQT> CONTAINS THE LOCATION OF THE TQT TO BE TERMINATED. 
* 
*     THE CALLING PROCEDURE WILL RESTORE THE RCB POINTER. 
* 
* DC  CALLING ROUTINES
* 
*     DB$DSCS                OPERATOR INTERFACE - CHANGE STATUS 
*     DB$TARE                TERMINATE AREA 
*     DB$TRU                 TERMINATE RUN UNIT 
*     DB$TSCH                TERMINATE SCHEMA 
* 
* DC  CALLED PROCEDURES 
# 
      XREF PROC DB$FLOP;     # RECORD A FLOW POINT                     #
      XREF PROC DB$GOTO;     # GO TO AN ADDRESS SPECIFIED IN A VARIABLE#
      XREF PROC DB$POP;      # POP A VARIABLE FROM THE STACK           #
      XREF PROC DB$POP2;     # POP TWO VARIABLES FROM THE STACK        #
      XREF PROC DB$PSH2;     # PUSH TWO VARIABLES TO THE STACK         #
      XREF PROC DB$PSH3;     # PUSH THREE VARIABLES TO THE STACK       #
      XREF PROC DB$PUSH;     # PUSH A VARIABLE TO THE STACK            #
      XREF PROC DB$RCBC;     # CREATE AN RCB                           #
      XREF PROC DB$RSDC;     # RESET DELAY COUNTS                      #
      XREF PROC DB$RTN;      # RETURN A PERMANENT FILE                 #
      XREF PROC DB$SCHD;     # INTERRUPT THE CURRENT PROCESS.          #
# 
* DC  NON-LOCAL VARIABLE MODIFIED 
* 
*     CDCSCOMMN 
*       P<RCB>               RCB POINTER
*         RCCONSTRA          CONSTRAINING ADDRESS 
*         RCCONTA            CONTINUATION ADDRESS 
*         RCCT               CONSTRAINT TYPE
*         RCSTACKX           PUSH DOWN STACK POINTER
* 
*       TQRCB                TQT RCB POINTER (IF THERE IS NO RCB) 
# 
      XREF ITEM DB$ROAF;     # ATTACH REQUEST WAITING FLAG             #
# 
* DC  DESCRIPTION 
* 
*     IF THERE IS NO RCB, CREATE ONE TO FACILITATE THE USER DROP. 
* 
*     IF THERE IS AN RCB
*       PERFORM SPECIAL PROCESSING THAT MIGHT BE REQUIRED 
*       AND SET THE CONTINUATION ADDRESS FOR IMMEDIATE TERMINATION. 
*     FLUSH THE RCB PUSH DOWN STACK (EXCEPT FOR THE CURRENT RCB). 
 #
# 
*     EXTERNALLY DEFINED LOCAL VARIABLES
# 
      XDEF ITEM TQTTCOMP I=1;  # CONSTANT COMPLETION BIT               #
                             # ADDRESS IS AN INDICATOR THAT DB$TQTT    #
                             # BUILT THE RCB                           #
# 
*     LOCAL VARIABLES 
# 
      BASED ARRAY CPTR; 
        BEGIN 
        ITEM COMPST B(00,59,01);  # COMPLETE STATUS                    #
        ITEM IPOINT I(00,42,18);  # INDIRECT POINTER                   #
        END 
      ITEM CONSTRA I;        # CONSTRAINING ADDRESS ON WHICH OTHER     #
                             # TASKS WOULD WAIT FOR THE SAME FILE      #
      ITEM COUNT;            # COUNT DOWN TILL OVERRIDE OF WAIT        #
      ITEM CPOINT;           # COMPLETE BIT POINTER                    #
      ITEM GOTOAD;           # ORIGINAL CONTINUATION ADDRESS           #
      ITEM OFTSAVED;         # SAVED OFT ADDRESS                       #
      ITEM TOP     I;        # SAVE THE TOP OF THE STACK               #
  
  
#     B E G I N   D B $ T Q T T   E X E C U T A B L E   C O D E .      #
  
      CONTROL IFGR DFFLOP,0;
        DB$FLOP("TQTT");
      CONTROL ENDIF;
# 
*     IF THERE IS NO RCB, CREATE ONE. 
# 
      IF TQRCB[0] LQ 0
      THEN
        BEGIN 
                                   # FOR IMMEDIATE ELIMINATION OF THE  #
                                   # USERS TABLES                      #
        DB$RCBC;                   # CREATE AN RCB FOR THIS TQT        #
        RCCONTA[0] = CONTA; 
        RCCONSTRA[0] = LOC(TQTTCOMP); 
        RCFUNC[0] = 0;
        RCTQT[0] = LOC(TQT);
        RCIR[0] = 0;
        RCIRUCPA[0] = 2;
        RCIR [DFRCIR2 - DFRCIR0] = 0; 
        RCIRRUID[0] = TQRUID[0];
        RCIRTASK[0] = TQTASK[0];
        RCIRBIAS[0] = 0;
        RCIRFL[0] = 0;
        TQRCB[0] = LOC(RCB);
        TQTERM[0] = TRUE; 
        RCCT[0] = DFWAITCOUNT;
        DB$PUSH(500);        # DELAY ABOUT TEN SECONDS               #
  
                             # IF ANOTHER REQUEST IS RECEIVED DURING   #
                             # THAT TIME, DB$IREC WILL DELETE THIS RCB #
                             # BUT USE THIS CONTINUATION ADDRESS       #
                             # FOR THE NEW REQUEST.                    #
                             # THAT AVOIDS THE CONFUSING USER JOB      #
                             # DIAGNOSTIC "HUNG IN AUTORECALL".        #
  
        CONTROL IFGR DFFLOP,0;
          DB$FLOP("TQTTRCB"); 
        CONTROL ENDIF;
  
        RETURN; 
  
        END 
# 
*     IF THERE IS AN RCB
*       PERFORM SPECIAL PROCESSING THAT MIGHT BE REQUIRED 
*       AND SET IT UP TO IMMEDIATELY ENTER THE SPECIFIED TERMINATION
*       PROCEDURE.
# 
      IF TQRCB[0] GR 0
      THEN
        BEGIN 
        P<RCB> = TQRCB[0];
        RCEREX[0] = 0;       # CLEAR PENDING ERROR EXIT ADDRESS        #
# 
*       IF THE RCB HAS BEEN SET IN DEFERRED TERMINATION MODE, 
*         PUT THE CONTINUATION ADDRESS IN THE DEFERRED SLOT AND LET 
*         THE RCB RUN UNINTERRUPTED.
*         THIS CAN PERMIT LOGGING TO COMPLETE BEFORE THE TERMINATION. 
# 
        IF RCIRDTMD[0]
        THEN
          BEGIN                    # THE DEFERRED ERROR SWITCH IS SET  #
          IF RCIRDTAD[0] NQ 0 
            AND RCIRDTAD[0] NQ CONTA
          THEN
            BEGIN                  # THIS IS A DIFFERENT ABORT.        #
            CONTROL IFGR DFFLOP,0;
              DB$FLOP("TQTT-OR"); 
            CONTROL ENDIF;
            RCIRDTAD[0] = 0;
            RCCONTA[0] = CONTA;    # DONT WAIT ANY LONGER.             #
            RCCONSTRA[0] = LOC(STATCOMP); 
            RETURN; 
  
            END 
          ELSE
            BEGIN 
            CONTROL IFGR DFFLOP,0;
              DB$FLOP("TQTT-DE"); 
            CONTROL ENDIF;
            RCIRDTAD[0] = CONTA;   # SET A DEFERRED ERROR ADDRESS      #
            RETURN; 
  
            END 
          END 
# 
*       IF THE TERMINATED TASK IS WAITING IN DB$ATCH
*         THEN CLEAN UP THE PENDING ATTACH AND SET OFDUMY SO THAT 
*         ANY OTHER REQUEST THAT IS WAITING IN DB$ADAX WILL CONTINUE. 
# 
        IF ( RCIRFUNC[0] EQ DFINV 
          OR RCIRFUNC[0] EQ DFVER ) 
          AND RCINOFCOMP[0] NQ 0
        THEN
          BEGIN 
# 
*         SAVE THE CONSTRAINING ADDRESS UPON WHICH OTHER TASKS WOULD
*         WAIT FOR THIS FILE. 
# 
          CONSTRA = RCINOFCOMP[0];
# 
*         RETURN THE DATA AND INDEX FILES 
*         JUST TO BE SURE THEY ARE NOT ATTACHED.
# 
          OFTSAVED = LOC(OFT);
          P<OFT> = CONSTRA - LOC(OFCOMP[0]) + LOC(OFT); 
          DB$RTN(OFFITLFN[0]);
          IF OFFITXN[0] NQ 0
          THEN
            BEGIN 
            DB$RTN(OFFITXN[0]); 
            END 
  
          OFDUMY[0] = TRUE; 
          P<OFT> = OFTSAVED;
          P<RCB> = TQRCB[0];
          RCINOFCOMP[0] = 0;
# 
*         CLEAR DB$ROAF SO THAT DB$ROLL WILL NOT ATTEMPT TO ATTACH
*         THE FILE. 
# 
          DB$ROAF = 0;
          DB$RSDC;           # RESET DELAY COUNTS                      #
          END 
        IF LOC(RCB) NQ OWNRCB 
          AND RCSTACKX[0] LS (LOC(RCB) + DFRCIR0) 
        THEN
          BEGIN 
          DB$POP(TOP);       # SAVE THE TOP OF THE STACK FOR DB$RCBF   #
          RCSTACKX[0] = LOC(RCB) + DFRCIR0;  # RESET THE STACK TO EMPTY#
          DB$PUSH(TOP); 
          END 
        IF RCCT[0] EQ DFWAITXE
          OR RCCT[0] EQ DFWAITIO
        THEN                 # WAITING FOR AN EXTERNAL EVENT           #
          BEGIN 
          CONTROL IFGR DFFLOP,0;
            DB$FLOP("TQTT-EV"); 
          CONTROL ENDIF;
          DB$PSH3(CONTA,RCCONSTRA[0],1000); 
          RCCONTA[0] = LOC(COUNTDOWN);
          END 
        ELSE                 # NOT WAITING FOR AN EXTERNAL EVENT       #
          BEGIN 
          RCCONTA[0] = CONTA; 
          END 
        RCCT[0] = DFWAITTERM; 
        RCCONSTRA[0] = LOC(STATCOMP); 
        END 
  
      RETURN; 
  
                             # DELAY LOOP                              #
                             # WAITS FOR EXTERNAL EVENT TO COMPLETE    #
 COUNTDOWN:                  # NORMALLY, BEFORE FORCING IT.            #
  
      CONTROL IFGR DFFLOP,0;
        DB$FLOP("TQTT-S1"); 
      CONTROL ENDIF;
  
      DB$POP2(COUNT,CPOINT);
      COUNT = COUNT -1; 
      P<CPTR> = CPOINT; 
      IF CPOINT LS 0
      THEN
        BEGIN 
        P<CPTR> = -CPOINT;   # INDIRECT POINTER TO THE COMPLETE BIT    #
        P<CPTR> = IPOINT[0];
        END 
      IF COMPST[0] OR COUNT LQ 0
      THEN
        BEGIN 
        IF NOT COMPST[0]
        THEN
          BEGIN 
          COMPST[0] = TRUE; 
          END 
        DB$POP(GOTOAD); 
        DB$GOTO(GOTOAD);     # GOTO THE ORIGINALLY SPECIFIED           #
                             # CONTINUATION ADDRESS                    #
        END 
      DB$PSH2(CPOINT,COUNT);
      DB$SCHD(LOC(STATCOMP), DFWAITTERM); 
      GOTO COUNTDOWN; 
  
      END 
      TERM
