DbtcMain.cpp
上传用户:romrleung
上传日期:2022-05-23
资源大小:18897k
文件大小:428k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1.   lqhKeyReq->variableData[nextPos + 1] = sig1;
  2.   lqhKeyReq->variableData[nextPos + 2] = sig2;
  3.   lqhKeyReq->variableData[nextPos + 3] = sig3;
  4.   if (Tkeylen < 4) {
  5.     nextPos += Tkeylen;
  6.   } else {
  7.     nextPos += 4;
  8.   }//if
  9.   sig0 = regCachePtr->attrinfo0;
  10.   sig1 = regCachePtr->attrinfo15[0];
  11.   sig2 = regCachePtr->attrinfo15[1];
  12.   sig3 = regCachePtr->attrinfo15[2];
  13.   sig4 = regCachePtr->attrinfo15[3];
  14.   UintR TlenAi = regCachePtr->lenAiInTckeyreq;
  15.   lqhKeyReq->variableData[nextPos + 0] = sig0;
  16.   lqhKeyReq->variableData[nextPos + 1] = sig1;
  17.   lqhKeyReq->variableData[nextPos + 2] = sig2;
  18.   lqhKeyReq->variableData[nextPos + 3] = sig3;
  19.   lqhKeyReq->variableData[nextPos + 4] = sig4;
  20.   nextPos += TlenAi;
  21.   // Reset trigger count
  22.   regTcPtr->accumulatingTriggerData.i = RNIL;  
  23.   regTcPtr->accumulatingTriggerData.p = NULL;  
  24.   regTcPtr->noFiredTriggers = 0;
  25.   regTcPtr->triggerExecutionCount = 0;
  26.   sendSignal(TBRef, GSN_LQHKEYREQ, signal, 
  27.              nextPos + LqhKeyReq::FixedSignalLength, JBB);
  28. }//Dbtc::sendlqhkeyreq()
  29. void Dbtc::packLqhkeyreq040Lab(Signal* signal,
  30.                                UintR anAttrBufIndex,
  31.                                BlockReference TBRef) 
  32. {
  33.   TcConnectRecord * const regTcPtr = tcConnectptr.p;
  34.   CacheRecord * const regCachePtr = cachePtr.p;
  35. #ifdef ERROR_INSERT
  36.   ApiConnectRecord * const regApiPtr = apiConnectptr.p;
  37.   if (ERROR_INSERTED(8009)) {
  38.     if (regApiPtr->apiConnectstate == CS_STARTED) {
  39.       attrbufptr.i = RNIL;
  40.       CLEAR_ERROR_INSERT_VALUE;
  41.       return;
  42.     }//if
  43.   }//if
  44.   if (ERROR_INSERTED(8010)) {
  45.     if (regApiPtr->apiConnectstate == CS_START_COMMITTING) {
  46.       attrbufptr.i = RNIL;
  47.       CLEAR_ERROR_INSERT_VALUE;
  48.       return;
  49.     }//if
  50.   }//if
  51. #endif
  52.   UintR TattrbufFilesize = cattrbufFilesize;
  53.   AttrbufRecord *localAttrbufRecord = attrbufRecord;
  54.   while (1) {
  55.     if (anAttrBufIndex == RNIL) {
  56.       UintR TtcTimer = ctcTimer;
  57.       UintR Tread = (regTcPtr->operation == ZREAD);
  58.       UintR Tsimple = (regCachePtr->opSimple == ZTRUE);
  59.       UintR Tboth = Tread & Tsimple;
  60.       setApiConTimer(apiConnectptr.i, TtcTimer, __LINE__);
  61.       jam();
  62.       /*--------------------------------------------------------------------
  63.        *   WE HAVE SENT ALL THE SIGNALS OF THIS OPERATION. SET STATE AND EXIT.
  64.        *---------------------------------------------------------------------*/
  65.       releaseAttrinfo();
  66.       if (Tboth) {
  67.         jam();
  68.         releaseSimpleRead(signal, apiConnectptr, tcConnectptr.p);
  69.         return;
  70.       }//if
  71.       regTcPtr->tcConnectstate = OS_OPERATING;
  72.       return;
  73.     }//if
  74.     if (anAttrBufIndex < TattrbufFilesize) {
  75.       AttrbufRecord * const regAttrPtr = &localAttrbufRecord[anAttrBufIndex];
  76.       anAttrBufIndex = regAttrPtr->attrbuf[ZINBUF_NEXT];
  77.       sendAttrinfo(signal,
  78.                    tcConnectptr.i,
  79.                    regAttrPtr,
  80.                    TBRef);
  81.     } else {
  82.       TCKEY_abort(signal, 17);
  83.       return;
  84.     }//if
  85.   }//while
  86. }//Dbtc::packLqhkeyreq040Lab()
  87. /* ========================================================================= */
  88. /* -------      RELEASE ALL ATTRINFO RECORDS IN AN OPERATION RECORD  ------- */
  89. /* ========================================================================= */
  90. void Dbtc::releaseAttrinfo() 
  91. {
  92.   UintR Tmp;
  93.   AttrbufRecordPtr Tattrbufptr;
  94.   CacheRecord * const regCachePtr = cachePtr.p;
  95.   UintR TattrbufFilesize = cattrbufFilesize;
  96.   UintR TfirstfreeAttrbuf = cfirstfreeAttrbuf;
  97.   Tattrbufptr.i = regCachePtr->firstAttrbuf;
  98.   AttrbufRecord *localAttrbufRecord = attrbufRecord;
  99.   while (Tattrbufptr.i < TattrbufFilesize) {
  100.     Tattrbufptr.p = &localAttrbufRecord[Tattrbufptr.i];
  101.     Tmp = Tattrbufptr.p->attrbuf[ZINBUF_NEXT];
  102.     Tattrbufptr.p->attrbuf[ZINBUF_NEXT] = TfirstfreeAttrbuf;
  103.     TfirstfreeAttrbuf = Tattrbufptr.i;
  104.     Tattrbufptr.i = Tmp;
  105.     jam();
  106.   }//while
  107.   if (Tattrbufptr.i == RNIL) {
  108. //---------------------------------------------------
  109. // Now we will release the cache record at the same
  110. // time as releasing the attrinfo records.
  111. //---------------------------------------------------
  112.     ApiConnectRecord * const regApiPtr = apiConnectptr.p;
  113.     UintR TfirstfreeCacheRec = cfirstfreeCacheRec;
  114.     UintR TCacheIndex = cachePtr.i;
  115.     cfirstfreeAttrbuf = TfirstfreeAttrbuf;
  116.     regCachePtr->nextCacheRec = TfirstfreeCacheRec;
  117.     cfirstfreeCacheRec = TCacheIndex;
  118.     regApiPtr->cachePtr = RNIL;
  119.     return;
  120.   }//if
  121.   systemErrorLab(0);
  122.   return;
  123. }//Dbtc::releaseAttrinfo()
  124. /* ========================================================================= */
  125. /* -------   RELEASE ALL RECORDS CONNECTED TO A SIMPLE OPERATION     ------- */
  126. /* ========================================================================= */
  127. void Dbtc::releaseSimpleRead(Signal* signal, 
  128.      ApiConnectRecordPtr regApiPtr,
  129.      TcConnectRecord* regTcPtr) 
  130. {
  131.   Uint32 Ttckeyrec = regApiPtr.p->tckeyrec;
  132.   Uint32 TclientData = regTcPtr->clientData;
  133.   Uint32 Tnode = regTcPtr->tcNodedata[0];
  134.   Uint32 Tlqhkeyreqrec = regApiPtr.p->lqhkeyreqrec;
  135.   Uint32 TsimpleReadCount = c_counters.csimpleReadCount;
  136.   ConnectionState state = regApiPtr.p->apiConnectstate;
  137.   
  138.   regApiPtr.p->tcSendArray[Ttckeyrec] = TclientData;
  139.   regApiPtr.p->tcSendArray[Ttckeyrec + 1] = TcKeyConf::SimpleReadBit | Tnode;
  140.   regApiPtr.p->tckeyrec = Ttckeyrec + 2;
  141.   
  142.   unlinkReadyTcCon(signal);
  143.   releaseTcCon();
  144.   /**
  145.    * No LQHKEYCONF in Simple/Dirty read
  146.    * Therefore decrese no LQHKEYCONF(REF) we are waiting for
  147.    */
  148.   c_counters.csimpleReadCount = TsimpleReadCount + 1;
  149.   regApiPtr.p->lqhkeyreqrec = --Tlqhkeyreqrec;
  150.   
  151.   if(Tlqhkeyreqrec == 0)
  152.   {
  153.     /**
  154.      * Special case of lqhKeyConf_checkTransactionState:
  155.      * - commit with zero operations: handle only for simple read
  156.      */
  157.     sendtckeyconf(signal, state == CS_START_COMMITTING);
  158.     regApiPtr.p->apiConnectstate = 
  159.       (state == CS_START_COMMITTING ? CS_CONNECTED : state);
  160.     setApiConTimer(regApiPtr.i, 0, __LINE__);
  161.     return;
  162.   }
  163.   
  164.   /**
  165.    * Emulate LQHKEYCONF
  166.    */
  167.   lqhKeyConf_checkTransactionState(signal, regApiPtr.p);
  168. }//Dbtc::releaseSimpleRead()
  169. /* ------------------------------------------------------------------------- */
  170. /* -------        CHECK IF ALL TC CONNECTIONS ARE COMPLETED          ------- */
  171. /* ------------------------------------------------------------------------- */
  172. void Dbtc::unlinkReadyTcCon(Signal* signal) 
  173. {
  174.   TcConnectRecordPtr urtTcConnectptr;
  175.   TcConnectRecord * const regTcPtr = tcConnectptr.p;
  176.   TcConnectRecord *localTcConnectRecord = tcConnectRecord;
  177.   UintR TtcConnectFilesize = ctcConnectFilesize;
  178.   ApiConnectRecord * const regApiPtr = apiConnectptr.p;
  179.   if (regTcPtr->prevTcConnect != RNIL) {
  180.     jam();
  181.     urtTcConnectptr.i = regTcPtr->prevTcConnect;
  182.     ptrCheckGuard(urtTcConnectptr, TtcConnectFilesize, localTcConnectRecord);
  183.     urtTcConnectptr.p->nextTcConnect = regTcPtr->nextTcConnect;
  184.   } else {
  185.     jam();
  186.     regApiPtr->firstTcConnect = regTcPtr->nextTcConnect;
  187.   }//if
  188.   if (regTcPtr->nextTcConnect != RNIL) {
  189.     jam();
  190.     urtTcConnectptr.i = regTcPtr->nextTcConnect;
  191.     ptrCheckGuard(urtTcConnectptr, TtcConnectFilesize, localTcConnectRecord);
  192.     urtTcConnectptr.p->prevTcConnect = regTcPtr->prevTcConnect;
  193.   } else {
  194.     jam();
  195.     regApiPtr->lastTcConnect = tcConnectptr.p->prevTcConnect;
  196.   }//if
  197. }//Dbtc::unlinkReadyTcCon()
  198. void Dbtc::releaseTcCon() 
  199. {
  200.   TcConnectRecord * const regTcPtr = tcConnectptr.p;
  201.   UintR TfirstfreeTcConnect = cfirstfreeTcConnect;
  202.   UintR TconcurrentOp = c_counters.cconcurrentOp;
  203.   UintR TtcConnectptrIndex = tcConnectptr.i;
  204.   regTcPtr->tcConnectstate = OS_CONNECTED;
  205.   regTcPtr->nextTcConnect = TfirstfreeTcConnect;
  206.   regTcPtr->apiConnect = RNIL;
  207.   regTcPtr->isIndexOp = false;
  208.   regTcPtr->indexOp = RNIL;
  209.   cfirstfreeTcConnect = TtcConnectptrIndex;
  210.   c_counters.cconcurrentOp = TconcurrentOp - 1;
  211. }//Dbtc::releaseTcCon()
  212. void Dbtc::execPACKED_SIGNAL(Signal* signal) 
  213. {
  214.   LqhKeyConf * const lqhKeyConf = (LqhKeyConf *)signal->getDataPtr();
  215.   UintR Ti;
  216.   UintR Tstep = 0;
  217.   UintR Tlength;
  218.   UintR TpackedData[28];
  219.   UintR Tdata1, Tdata2, Tdata3, Tdata4;
  220.   jamEntry();
  221.   Tlength = signal->length();
  222.   if (Tlength > 25) {
  223.     jam();
  224.     systemErrorLab(signal);
  225.     return;
  226.   }//if
  227.   Uint32* TpackDataPtr;
  228.   for (Ti = 0; Ti < Tlength; Ti += 4) {
  229.     Uint32* TsigDataPtr = &signal->theData[Ti];
  230.     Tdata1 = TsigDataPtr[0];
  231.     Tdata2 = TsigDataPtr[1];
  232.     Tdata3 = TsigDataPtr[2];
  233.     Tdata4 = TsigDataPtr[3];
  234.     TpackDataPtr = &TpackedData[Ti];
  235.     TpackDataPtr[0] = Tdata1;
  236.     TpackDataPtr[1] = Tdata2;
  237.     TpackDataPtr[2] = Tdata3;
  238.     TpackDataPtr[3] = Tdata4;
  239.   }//for
  240.   while (Tlength > Tstep) {
  241.     TpackDataPtr = &TpackedData[Tstep];
  242.     Tdata1 = TpackDataPtr[0];
  243.     Tdata2 = TpackDataPtr[1];
  244.     Tdata3 = TpackDataPtr[2];
  245.     lqhKeyConf->connectPtr = Tdata1 & 0x0FFFFFFF;
  246.     lqhKeyConf->opPtr = Tdata2;
  247.     lqhKeyConf->userRef = Tdata3;
  248.     switch (Tdata1 >> 28) {
  249.     case ZCOMMITTED:
  250.       signal->header.theLength = 3;
  251.       execCOMMITTED(signal);
  252.       Tstep += 3;
  253.       break;
  254.     case ZCOMPLETED:
  255.       signal->header.theLength = 3;
  256.       execCOMPLETED(signal);
  257.       Tstep += 3;
  258.       break;
  259.     case ZLQHKEYCONF:
  260.       jam();
  261.       Tdata1 = TpackDataPtr[3];
  262.       Tdata2 = TpackDataPtr[4];
  263.       Tdata3 = TpackDataPtr[5];
  264.       Tdata4 = TpackDataPtr[6];
  265.       lqhKeyConf->readLen = Tdata1;
  266.       lqhKeyConf->transId1 = Tdata2;
  267.       lqhKeyConf->transId2 = Tdata3;
  268.       lqhKeyConf->noFiredTriggers = Tdata4;
  269.       signal->header.theLength = LqhKeyConf::SignalLength;
  270.       execLQHKEYCONF(signal);
  271.       Tstep += LqhKeyConf::SignalLength;
  272.       break;
  273.     default:
  274.       systemErrorLab(signal);
  275.       return;
  276.     }//switch
  277.   }//while
  278.   return;
  279. }//Dbtc::execPACKED_SIGNAL()
  280. void Dbtc::execLQHKEYCONF(Signal* signal) 
  281. {
  282.   const LqhKeyConf * const lqhKeyConf = (LqhKeyConf *)signal->getDataPtr();
  283.   UintR compare_transid1, compare_transid2;
  284.   BlockReference tlastLqhBlockref;
  285.   UintR tlastLqhConnect;
  286.   UintR treadlenAi;
  287.   UintR TtcConnectptrIndex;
  288.   UintR TtcConnectFilesize = ctcConnectFilesize;
  289.   tlastLqhConnect = lqhKeyConf->connectPtr;
  290.   TtcConnectptrIndex = lqhKeyConf->opPtr;
  291.   tlastLqhBlockref = lqhKeyConf->userRef;
  292.   treadlenAi = lqhKeyConf->readLen;
  293.   TcConnectRecord *localTcConnectRecord = tcConnectRecord;
  294.   /*------------------------------------------------------------------------
  295.    * NUMBER OF EXTERNAL TRIGGERS FIRED IN DATA[6] 
  296.    * OPERATION IS NOW COMPLETED. CHECK FOR CORRECT OPERATION POINTER  
  297.    * TO ENSURE NO CRASHES BECAUSE OF ERRONEUS NODES. CHECK STATE OF   
  298.    * OPERATION. THEN SET OPERATION STATE AND RETRIEVE ALL POINTERS    
  299.    * OF THIS OPERATION. PUT COMPLETED OPERATION IN LIST OF COMPLETED  
  300.    * OPERATIONS ON THE LQH CONNECT RECORD.                          
  301.    *------------------------------------------------------------------------
  302.    * THIS SIGNAL ALWAYS ARRIVE BEFORE THE ABORTED SIGNAL ARRIVES SINCE IT USES
  303.    * THE SAME PATH BACK TO TC AS THE ABORTED SIGNAL DO. WE DO HOWEVER HAVE A 
  304.    * PROBLEM  WHEN WE ENCOUNTER A TIME-OUT WAITING FOR THE ABORTED SIGNAL.  
  305.    * THEN THIS SIGNAL MIGHT ARRIVE WHEN THE TC CONNECT RECORD HAVE BEEN REUSED
  306.    * BY OTHER TRANSACTION THUS WE CHECK THE TRANSACTION ID OF THE SIGNAL 
  307.    * BEFORE ACCEPTING THIS SIGNAL.
  308.    * Due to packing of LQHKEYCONF the ABORTED signal can now arrive before 
  309.    * this. 
  310.    * This is more reason to ignore the signal if not all states are correct.
  311.    *------------------------------------------------------------------------*/
  312.   if (TtcConnectptrIndex >= TtcConnectFilesize) {
  313.     TCKEY_abort(signal, 25);
  314.     return;
  315.   }//if
  316.   TcConnectRecord* const regTcPtr = &localTcConnectRecord[TtcConnectptrIndex];
  317.   OperationState TtcConnectstate = regTcPtr->tcConnectstate;
  318.   tcConnectptr.i = TtcConnectptrIndex;
  319.   tcConnectptr.p = regTcPtr;
  320.   if (TtcConnectstate != OS_OPERATING) {
  321.     warningReport(signal, 23);
  322.     return;
  323.   }//if
  324.   ApiConnectRecord *localApiConnectRecord = apiConnectRecord;
  325.   UintR TapiConnectptrIndex = regTcPtr->apiConnect;
  326.   UintR TapiConnectFilesize = capiConnectFilesize;
  327.   UintR Ttrans1 = lqhKeyConf->transId1;
  328.   UintR Ttrans2 = lqhKeyConf->transId2;
  329.   Uint32 noFired = lqhKeyConf->noFiredTriggers;
  330.   if (TapiConnectptrIndex >= TapiConnectFilesize) {
  331.     TCKEY_abort(signal, 29);
  332.     return;
  333.   }//if
  334.   ApiConnectRecord * const regApiPtr = 
  335.                             &localApiConnectRecord[TapiConnectptrIndex];
  336.   apiConnectptr.i = TapiConnectptrIndex;
  337.   apiConnectptr.p = regApiPtr;
  338.   compare_transid1 = regApiPtr->transid[0] ^ Ttrans1;
  339.   compare_transid2 = regApiPtr->transid[1] ^ Ttrans2;
  340.   compare_transid1 = compare_transid1 | compare_transid2;
  341.   if (compare_transid1 != 0) {
  342.     warningReport(signal, 24);
  343.     return;
  344.   }//if
  345. #ifdef ERROR_INSERT
  346.   if (ERROR_INSERTED(8029)) {
  347.     systemErrorLab(signal);
  348.   }//if
  349.   if (ERROR_INSERTED(8003)) {
  350.     if (regApiPtr->apiConnectstate == CS_STARTED) {
  351.       CLEAR_ERROR_INSERT_VALUE;
  352.       return;
  353.     }//if
  354.   }//if
  355.   if (ERROR_INSERTED(8004)) {
  356.     if (regApiPtr->apiConnectstate == CS_RECEIVING) {
  357.       CLEAR_ERROR_INSERT_VALUE;
  358.       return;
  359.     }//if
  360.   }//if
  361.   if (ERROR_INSERTED(8005)) {
  362.     if (regApiPtr->apiConnectstate == CS_REC_COMMITTING) {
  363.       CLEAR_ERROR_INSERT_VALUE;
  364.       return;
  365.     }//if
  366.   }//if
  367.   if (ERROR_INSERTED(8006)) {
  368.     if (regApiPtr->apiConnectstate == CS_START_COMMITTING) {
  369.       CLEAR_ERROR_INSERT_VALUE;
  370.       return;
  371.     }//if
  372.   }//if
  373.   if (ERROR_INSERTED(8023)) {
  374.     SET_ERROR_INSERT_VALUE(8024);
  375.     return;
  376.   }//if
  377. #endif
  378.   UintR TtcTimer = ctcTimer;
  379.   regTcPtr->lastLqhCon = tlastLqhConnect;
  380.   regTcPtr->lastLqhNodeId = refToNode(tlastLqhBlockref);
  381.   regTcPtr->noFiredTriggers = noFired;
  382.   UintR Ttckeyrec = (UintR)regApiPtr->tckeyrec;
  383.   UintR TclientData = regTcPtr->clientData;
  384.   UintR TdirtyOp = regTcPtr->dirtyOp;
  385.   ConnectionState TapiConnectstate = regApiPtr->apiConnectstate;
  386.   if (Ttckeyrec > (ZTCOPCONF_SIZE - 2)) {
  387.     TCKEY_abort(signal, 30);
  388.     return;
  389.   }
  390.   if (TapiConnectstate == CS_ABORTING) {
  391.     warningReport(signal, 27);
  392.     return;
  393.   }//if
  394.   setApiConTimer(apiConnectptr.i, TtcTimer, __LINE__);
  395.   if (regTcPtr->isIndexOp) {
  396.     jam();
  397.     // This was an internal TCKEYREQ
  398.     // will be returned unpacked
  399.     regTcPtr->attrInfoLen = treadlenAi;
  400.   } else {
  401.     if (noFired == 0 && regTcPtr->triggeringOperation == RNIL) {
  402.       jam();
  403.       /*
  404.        * Skip counting triggering operations the first round
  405.        * since they will enter execLQHKEYCONF a second time
  406.        * Skip counting internally generated TcKeyReq
  407.        */
  408.       regApiPtr->tcSendArray[Ttckeyrec] = TclientData;
  409.       regApiPtr->tcSendArray[Ttckeyrec + 1] = treadlenAi;
  410.       regApiPtr->tckeyrec = Ttckeyrec + 2;
  411.     }//if
  412.   }//if
  413.   if (TdirtyOp == ZTRUE) {
  414.     UintR Tlqhkeyreqrec = regApiPtr->lqhkeyreqrec;
  415.     jam();
  416.     releaseDirtyWrite(signal);
  417.     regApiPtr->lqhkeyreqrec = Tlqhkeyreqrec - 1;
  418.   } else {
  419.     jam();
  420.     if (noFired == 0) {
  421.       jam();
  422.       // No triggers to execute
  423.       UintR Tlqhkeyconfrec = regApiPtr->lqhkeyconfrec;
  424.       regApiPtr->lqhkeyconfrec = Tlqhkeyconfrec + 1;
  425.       regTcPtr->tcConnectstate = OS_PREPARED;
  426.     }
  427.   }//if
  428.   /**
  429.    * And now decide what to do next
  430.    */
  431.   if (regTcPtr->triggeringOperation != RNIL) {
  432.     jam();
  433.     // This operation was created by a trigger execting operation
  434.     // Restart it if we have executed all it's triggers
  435.     TcConnectRecordPtr opPtr;
  436.     opPtr.i = regTcPtr->triggeringOperation;
  437.     ptrCheckGuard(opPtr, ctcConnectFilesize, localTcConnectRecord);
  438.     opPtr.p->triggerExecutionCount--;
  439.     if (opPtr.p->triggerExecutionCount == 0) {
  440.       /*
  441.       We have completed current trigger execution
  442.       Continue triggering operation
  443.       */
  444.       jam();
  445.       continueTriggeringOp(signal, opPtr.p);
  446.     }
  447.   } else if (noFired == 0) {
  448.     // This operation did not fire any triggers, finish operation
  449.     jam();
  450.     if (regTcPtr->isIndexOp) {
  451.       jam();
  452.       setupIndexOpReturn(regApiPtr, regTcPtr);
  453.     }
  454.     lqhKeyConf_checkTransactionState(signal, regApiPtr);
  455.   } else {
  456.     // We have fired triggers
  457.     jam();
  458.     saveTriggeringOpState(signal, regTcPtr);
  459.     if (regTcPtr->noReceivedTriggers == noFired) {
  460.       ApiConnectRecordPtr transPtr;
  461.       
  462.       // We have received all data
  463.       jam();
  464.       transPtr.i = TapiConnectptrIndex;
  465.       transPtr.p = regApiPtr;
  466.       executeTriggers(signal, &transPtr);
  467.     }
  468.     // else wait for more trigger data
  469.   }
  470. }//Dbtc::execLQHKEYCONF()
  471.  
  472. void Dbtc::setupIndexOpReturn(ApiConnectRecord* regApiPtr,
  473.       TcConnectRecord* regTcPtr) 
  474. {
  475.   regApiPtr->indexOpReturn = true;
  476.   regApiPtr->indexOp = regTcPtr->indexOp;
  477.   regApiPtr->clientData = regTcPtr->clientData;
  478.   regApiPtr->attrInfoLen = regTcPtr->attrInfoLen;
  479. }
  480. /**
  481.  * lqhKeyConf_checkTransactionState
  482.  *
  483.  * This functions checks state variables, and
  484.  *   decides if it should wait for more LQHKEYCONF signals
  485.  *   or if it should start commiting
  486.  */
  487. void
  488. Dbtc::lqhKeyConf_checkTransactionState(Signal * signal,
  489.        ApiConnectRecord * const apiConnectPtrP)
  490. {
  491. /*---------------------------------------------------------------*/
  492. /* IF THE COMMIT FLAG IS SET IN SIGNAL TCKEYREQ THEN DBTC HAS TO */
  493. /* SEND TCKEYCONF FOR ALL OPERATIONS EXCEPT THE LAST ONE. WHEN   */
  494. /* THE TRANSACTION THEN IS COMMITTED TCKEYCONF IS SENT FOR THE   */
  495. /* WHOLE TRANSACTION                                             */
  496. /* IF THE COMMIT FLAG IS NOT RECECIVED DBTC WILL SEND TCKEYCONF  */
  497. /* FOR ALL OPERATIONS, AND THEN WAIT FOR THE API TO CONCLUDE THE */
  498. /* TRANSACTION                                                   */
  499. /*---------------------------------------------------------------*/
  500.   ConnectionState TapiConnectstate = apiConnectPtrP->apiConnectstate;
  501.   UintR Tlqhkeyconfrec = apiConnectPtrP->lqhkeyconfrec;
  502.   UintR Tlqhkeyreqrec = apiConnectPtrP->lqhkeyreqrec;
  503.   int TnoOfOutStanding = Tlqhkeyreqrec - Tlqhkeyconfrec;
  504.   switch (TapiConnectstate) {
  505.   case CS_START_COMMITTING:
  506.     if (TnoOfOutStanding == 0) {
  507.       jam();
  508.       diverify010Lab(signal);
  509.       return;
  510.     } else if (TnoOfOutStanding > 0) {
  511.       if (apiConnectPtrP->tckeyrec == ZTCOPCONF_SIZE) {
  512.         jam();
  513.         sendtckeyconf(signal, 0);
  514.         return;
  515.       } else if (apiConnectPtrP->indexOpReturn) {
  516. jam();
  517.         sendtckeyconf(signal, 0);
  518.         return;
  519.       }//if
  520.       jam();
  521.       return;
  522.     } else {
  523.       TCKEY_abort(signal, 44);
  524.       return;
  525.     }//if
  526.     return;
  527.   case CS_STARTED:
  528.   case CS_RECEIVING:
  529.     if (TnoOfOutStanding == 0) {
  530.       jam();
  531.       sendtckeyconf(signal, 2);
  532.       return;
  533.     } else {
  534.       if (apiConnectPtrP->tckeyrec == ZTCOPCONF_SIZE) {
  535.         jam();
  536.         sendtckeyconf(signal, 0);
  537.         return;
  538.       } else if (apiConnectPtrP->indexOpReturn) {
  539. jam();
  540.         sendtckeyconf(signal, 0);
  541.         return;
  542. }//if
  543.       jam();
  544.     }//if
  545.     return;
  546.   case CS_REC_COMMITTING:
  547.     if (TnoOfOutStanding > 0) {
  548.       if (apiConnectPtrP->tckeyrec == ZTCOPCONF_SIZE) {
  549.         jam();
  550.         sendtckeyconf(signal, 0);
  551.         return;
  552.       } else if (apiConnectPtrP->indexOpReturn) {
  553.         jam();
  554.         sendtckeyconf(signal, 0);
  555.         return;
  556.       }//if
  557.       jam();
  558.       return;
  559.     }//if
  560.     TCKEY_abort(signal, 45);
  561.     return;
  562.   case CS_CONNECTED:
  563.     jam();
  564. /*---------------------------------------------------------------*/
  565. /*       WE HAVE CONCLUDED THE TRANSACTION SINCE IT WAS ONLY     */
  566. /*       CONSISTING OF DIRTY WRITES AND ALL OF THOSE WERE        */
  567. /*       COMPLETED. ENSURE TCKEYREC IS ZERO TO PREVENT ERRORS.   */
  568. /*---------------------------------------------------------------*/
  569.     apiConnectPtrP->tckeyrec = 0;
  570.     return;
  571.   default:
  572.     TCKEY_abort(signal, 46);
  573.     return;
  574.   }//switch
  575. }//Dbtc::lqhKeyConf_checkTransactionState()
  576. void Dbtc::sendtckeyconf(Signal* signal, UintR TcommitFlag) 
  577. {
  578.   if(ERROR_INSERTED(8049)){
  579.     CLEAR_ERROR_INSERT_VALUE;
  580.     signal->theData[0] = TcContinueB::DelayTCKEYCONF;
  581.     signal->theData[1] = apiConnectptr.i;
  582.     signal->theData[2] = TcommitFlag;
  583.     sendSignalWithDelay(cownref, GSN_CONTINUEB, signal, 3000, 3);
  584.     return;
  585.   }
  586.   
  587.   HostRecordPtr localHostptr;
  588.   ApiConnectRecord * const regApiPtr = apiConnectptr.p;
  589.   const UintR TopWords = (UintR)regApiPtr->tckeyrec;
  590.   localHostptr.i = refToNode(regApiPtr->ndbapiBlockref);
  591.   const Uint32 type = getNodeInfo(localHostptr.i).m_type;
  592.   const bool is_api = (type >= NodeInfo::API && type <= NodeInfo::REP);
  593.   const BlockNumber TblockNum = refToBlock(regApiPtr->ndbapiBlockref);
  594.   const Uint32 Tmarker = (regApiPtr->commitAckMarker == RNIL) ? 0 : 1;
  595.   ptrAss(localHostptr, hostRecord);
  596.   UintR TcurrLen = localHostptr.p->noOfWordsTCKEYCONF;
  597.   UintR confInfo = 0;
  598.   TcKeyConf::setCommitFlag(confInfo, TcommitFlag == 1);
  599.   TcKeyConf::setMarkerFlag(confInfo, Tmarker);
  600.   const UintR TpacketLen = 6 + TopWords;
  601.   regApiPtr->tckeyrec = 0;
  602.   if (regApiPtr->indexOpReturn) {
  603.     jam();
  604.     // Return internally generated TCKEY
  605.     TcKeyConf * const tcKeyConf = (TcKeyConf *)signal->getDataPtrSend();
  606.     TcKeyConf::setNoOfOperations(confInfo, 1);
  607.     tcKeyConf->apiConnectPtr = regApiPtr->indexOp;
  608.     tcKeyConf->gci = regApiPtr->globalcheckpointid;
  609.     tcKeyConf->confInfo = confInfo;
  610.     tcKeyConf->transId1 = regApiPtr->transid[0];
  611.     tcKeyConf->transId2 = regApiPtr->transid[1];
  612.     tcKeyConf->operations[0].apiOperationPtr = regApiPtr->clientData;
  613.     tcKeyConf->operations[0].attrInfoLen = regApiPtr->attrInfoLen;
  614.     Uint32 sigLen = TcKeyConf::StaticLength + TcKeyConf::OperationLength;
  615.     EXECUTE_DIRECT(DBTC, GSN_TCKEYCONF, signal, sigLen);
  616.     regApiPtr->indexOpReturn = false;
  617.     if (TopWords == 0) {
  618.       jam();
  619.       return; // No queued TcKeyConf
  620.     }//if
  621.   }//if
  622.   if(TcommitFlag){
  623.     jam();
  624.     regApiPtr->m_exec_flag = 0;
  625.   }
  626.   TcKeyConf::setNoOfOperations(confInfo, (TopWords >> 1));
  627.   if ((TpacketLen > 25) || !is_api){
  628.     TcKeyConf * const tcKeyConf = (TcKeyConf *)signal->getDataPtrSend();
  629.     
  630.     jam();
  631.     tcKeyConf->apiConnectPtr = regApiPtr->ndbapiConnect;
  632.     tcKeyConf->gci = regApiPtr->globalcheckpointid;;
  633.     tcKeyConf->confInfo = confInfo;
  634.     tcKeyConf->transId1 = regApiPtr->transid[0];
  635.     tcKeyConf->transId2 = regApiPtr->transid[1];
  636.     copyFromToLen(&regApiPtr->tcSendArray[0],
  637.   (UintR*)&tcKeyConf->operations,
  638.   (UintR)ZTCOPCONF_SIZE);
  639.     sendSignal(regApiPtr->ndbapiBlockref,
  640.        GSN_TCKEYCONF, signal, (TpacketLen - 1), JBB);
  641.     return;
  642.   } else if (((TcurrLen + TpacketLen) > 25) && (TcurrLen > 0)) {
  643.     jam();
  644.     sendPackedTCKEYCONF(signal, localHostptr.p, localHostptr.i);
  645.     TcurrLen = 0;
  646.   } else {
  647.     jam();
  648.     updatePackedList(signal, localHostptr.p, localHostptr.i);
  649.   }//if
  650.   // -------------------------------------------------------------------------
  651.   // The header contains the block reference of receiver plus the real signal
  652.   // length - 3, since we have the real signal length plus one additional word
  653.   // for the header we have to do - 4.
  654.   // -------------------------------------------------------------------------
  655.   UintR Tpack0 = (TblockNum << 16) + (TpacketLen - 4);
  656.   UintR Tpack1 = regApiPtr->ndbapiConnect;
  657.   UintR Tpack2 = regApiPtr->globalcheckpointid;
  658.   UintR Tpack3 = confInfo;
  659.   UintR Tpack4 = regApiPtr->transid[0];
  660.   UintR Tpack5 = regApiPtr->transid[1];
  661.   
  662.   localHostptr.p->noOfWordsTCKEYCONF = TcurrLen + TpacketLen;
  663.   
  664.   localHostptr.p->packedWordsTCKEYCONF[TcurrLen + 0] = Tpack0;
  665.   localHostptr.p->packedWordsTCKEYCONF[TcurrLen + 1] = Tpack1;
  666.   localHostptr.p->packedWordsTCKEYCONF[TcurrLen + 2] = Tpack2;
  667.   localHostptr.p->packedWordsTCKEYCONF[TcurrLen + 3] = Tpack3;
  668.   localHostptr.p->packedWordsTCKEYCONF[TcurrLen + 4] = Tpack4;
  669.   localHostptr.p->packedWordsTCKEYCONF[TcurrLen + 5] = Tpack5;
  670.   
  671.   UintR Ti;
  672.   for (Ti = 6; Ti < TpacketLen; Ti++) {
  673.     localHostptr.p->packedWordsTCKEYCONF[TcurrLen + Ti] = 
  674.       regApiPtr->tcSendArray[Ti - 6];
  675.   }//for
  676. }//Dbtc::sendtckeyconf()
  677. void Dbtc::copyFromToLen(UintR* sourceBuffer, UintR* destBuffer, UintR Tlen)
  678. {
  679.   UintR Tindex = 0;
  680.   UintR Ti;
  681.   while (Tlen >= 4) {
  682.     UintR Tdata0 = sourceBuffer[Tindex + 0];
  683.     UintR Tdata1 = sourceBuffer[Tindex + 1];
  684.     UintR Tdata2 = sourceBuffer[Tindex + 2];
  685.     UintR Tdata3 = sourceBuffer[Tindex + 3];
  686.     Tlen -= 4;
  687.     destBuffer[Tindex + 0] = Tdata0;
  688.     destBuffer[Tindex + 1] = Tdata1;
  689.     destBuffer[Tindex + 2] = Tdata2;
  690.     destBuffer[Tindex + 3] = Tdata3;
  691.     Tindex += 4;
  692.   }//while
  693.   for (Ti = 0; Ti < Tlen; Ti++, Tindex++) {
  694.     destBuffer[Tindex] = sourceBuffer[Tindex];
  695.   }//for
  696. }//Dbtc::copyFromToLen()
  697. void Dbtc::execSEND_PACKED(Signal* signal) 
  698. {
  699.   HostRecordPtr Thostptr;
  700.   HostRecord *localHostRecord = hostRecord;
  701.   UintR i;
  702.   UintR TpackedListIndex = cpackedListIndex;
  703.   jamEntry();
  704.   for (i = 0; i < TpackedListIndex; i++) {
  705.     Thostptr.i = cpackedList[i];
  706.     ptrAss(Thostptr, localHostRecord);
  707.     arrGuard(Thostptr.i - 1, MAX_NODES - 1);
  708.     UintR TnoOfPackedWordsLqh = Thostptr.p->noOfPackedWordsLqh;
  709.     UintR TnoOfWordsTCKEYCONF = Thostptr.p->noOfWordsTCKEYCONF;
  710.     UintR TnoOfWordsTCINDXCONF = Thostptr.p->noOfWordsTCINDXCONF;
  711.     jam();
  712.     if (TnoOfPackedWordsLqh > 0) {
  713.       jam();
  714.       sendPackedSignalLqh(signal, Thostptr.p);
  715.     }//if
  716.     if (TnoOfWordsTCKEYCONF > 0) {
  717.       jam();
  718.       sendPackedTCKEYCONF(signal, Thostptr.p, (Uint32)Thostptr.i);
  719.     }//if
  720.     if (TnoOfWordsTCINDXCONF > 0) {
  721.       jam();
  722.       sendPackedTCINDXCONF(signal, Thostptr.p, (Uint32)Thostptr.i);
  723.     }//if
  724.     Thostptr.p->inPackedList = false;
  725.   }//for
  726.   cpackedListIndex = 0;
  727.   return;
  728. }//Dbtc::execSEND_PACKED()
  729. void 
  730. Dbtc::updatePackedList(Signal* signal, HostRecord* ahostptr, Uint16 ahostIndex)
  731. {
  732.   if (ahostptr->inPackedList == false) {
  733.     UintR TpackedListIndex = cpackedListIndex;
  734.     jam();
  735.     ahostptr->inPackedList = true;
  736.     cpackedList[TpackedListIndex] = ahostIndex;
  737.     cpackedListIndex = TpackedListIndex + 1;
  738.   }//if
  739. }//Dbtc::updatePackedList()
  740. void Dbtc::sendPackedSignalLqh(Signal* signal, HostRecord * ahostptr)
  741. {
  742.   UintR Tj;
  743.   UintR TnoOfWords = ahostptr->noOfPackedWordsLqh;
  744.   for (Tj = 0; Tj < TnoOfWords; Tj += 4) {
  745.     UintR sig0 = ahostptr->packedWordsLqh[Tj + 0];
  746.     UintR sig1 = ahostptr->packedWordsLqh[Tj + 1];
  747.     UintR sig2 = ahostptr->packedWordsLqh[Tj + 2];
  748.     UintR sig3 = ahostptr->packedWordsLqh[Tj + 3];
  749.     signal->theData[Tj + 0] = sig0;
  750.     signal->theData[Tj + 1] = sig1;
  751.     signal->theData[Tj + 2] = sig2;
  752.     signal->theData[Tj + 3] = sig3;
  753.   }//for
  754.   ahostptr->noOfPackedWordsLqh = 0;
  755.   sendSignal(ahostptr->hostLqhBlockRef,
  756.              GSN_PACKED_SIGNAL,
  757.              signal,
  758.              TnoOfWords,
  759.              JBB);
  760. }//Dbtc::sendPackedSignalLqh()
  761. void Dbtc::sendPackedTCKEYCONF(Signal* signal,
  762.                                HostRecord * ahostptr,
  763.                                UintR hostId)
  764. {
  765.   UintR Tj;
  766.   UintR TnoOfWords = ahostptr->noOfWordsTCKEYCONF;
  767.   BlockReference TBref = numberToRef(API_PACKED, hostId);
  768.   for (Tj = 0; Tj < ahostptr->noOfWordsTCKEYCONF; Tj += 4) {
  769.     UintR sig0 = ahostptr->packedWordsTCKEYCONF[Tj + 0];
  770.     UintR sig1 = ahostptr->packedWordsTCKEYCONF[Tj + 1];
  771.     UintR sig2 = ahostptr->packedWordsTCKEYCONF[Tj + 2];
  772.     UintR sig3 = ahostptr->packedWordsTCKEYCONF[Tj + 3];
  773.     signal->theData[Tj + 0] = sig0;
  774.     signal->theData[Tj + 1] = sig1;
  775.     signal->theData[Tj + 2] = sig2;
  776.     signal->theData[Tj + 3] = sig3;
  777.   }//for
  778.   ahostptr->noOfWordsTCKEYCONF = 0;
  779.   sendSignal(TBref, GSN_TCKEYCONF, signal, TnoOfWords, JBB);
  780. }//Dbtc::sendPackedTCKEYCONF()
  781. void Dbtc::sendPackedTCINDXCONF(Signal* signal,
  782.                                 HostRecord * ahostptr,
  783.                                 UintR hostId)
  784. {
  785.   UintR Tj;
  786.   UintR TnoOfWords = ahostptr->noOfWordsTCINDXCONF;
  787.   BlockReference TBref = numberToRef(API_PACKED, hostId);
  788.   for (Tj = 0; Tj < ahostptr->noOfWordsTCINDXCONF; Tj += 4) {
  789.     UintR sig0 = ahostptr->packedWordsTCINDXCONF[Tj + 0];
  790.     UintR sig1 = ahostptr->packedWordsTCINDXCONF[Tj + 1];
  791.     UintR sig2 = ahostptr->packedWordsTCINDXCONF[Tj + 2];
  792.     UintR sig3 = ahostptr->packedWordsTCINDXCONF[Tj + 3];
  793.     signal->theData[Tj + 0] = sig0;
  794.     signal->theData[Tj + 1] = sig1;
  795.     signal->theData[Tj + 2] = sig2;
  796.     signal->theData[Tj + 3] = sig3;
  797.   }//for
  798.   ahostptr->noOfWordsTCINDXCONF = 0;
  799.   sendSignal(TBref, GSN_TCINDXCONF, signal, TnoOfWords, JBB);
  800. }//Dbtc::sendPackedTCINDXCONF()
  801. /*
  802. 4.3.11 DIVERIFY 
  803. ---------------
  804. */
  805. /*****************************************************************************/
  806. /*                               D I V E R I F Y                             */
  807. /*                                                                           */
  808. /*****************************************************************************/
  809. void Dbtc::diverify010Lab(Signal* signal) 
  810. {
  811.   UintR TfirstfreeApiConnectCopy = cfirstfreeApiConnectCopy;
  812.   ApiConnectRecord * const regApiPtr = apiConnectptr.p;
  813.   signal->theData[0] = apiConnectptr.i;
  814.   if (ERROR_INSERTED(8022)) {
  815.     jam();
  816.     systemErrorLab(signal);
  817.   }//if
  818.   if (TfirstfreeApiConnectCopy != RNIL) {
  819.     seizeApiConnectCopy(signal);
  820.     regApiPtr->apiConnectstate = CS_PREPARE_TO_COMMIT;
  821.     /*-----------------------------------------------------------------------
  822.      * WE COME HERE ONLY IF THE TRANSACTION IS PREPARED ON ALL TC CONNECTIONS.
  823.      * THUS WE CAN START THE COMMIT PHASE BY SENDING DIVERIFY ON ALL TC     
  824.      * CONNECTIONS AND THEN WHEN ALL DIVERIFYCONF HAVE BEEN RECEIVED THE 
  825.      * COMMIT MESSAGE CAN BE SENT TO ALL INVOLVED PARTS.
  826.      *-----------------------------------------------------------------------*/
  827.     EXECUTE_DIRECT(DBDIH, GSN_DIVERIFYREQ, signal, 1);
  828.     if (signal->theData[2] == 0) {
  829.       execDIVERIFYCONF(signal);
  830.     }
  831.     return;
  832.   } else {
  833.     /*-----------------------------------------------------------------------
  834.      * There were no free copy connections available. We must abort the 
  835.      * transaction since otherwise we will have a problem with the report 
  836.      * to the application.
  837.      * This should more or less not happen but if it happens we do not want to
  838.      * crash and we do not want to create code to handle it properly since 
  839.      * it is difficult to test it and will be complex to handle a problem 
  840.      * more or less not occurring.
  841.      *-----------------------------------------------------------------------*/
  842.     terrorCode = ZSEIZE_API_COPY_ERROR;
  843.     abortErrorLab(signal);
  844.     return;
  845.   }//if
  846. }//Dbtc::diverify010Lab()
  847. /* ------------------------------------------------------------------------- */
  848. /* -------                  SEIZE_API_CONNECT                        ------- */
  849. /*                  SEIZE CONNECT RECORD FOR A REQUEST                       */
  850. /* ------------------------------------------------------------------------- */
  851. void Dbtc::seizeApiConnectCopy(Signal* signal) 
  852. {
  853.   ApiConnectRecordPtr locApiConnectptr;
  854.   ApiConnectRecord *localApiConnectRecord = apiConnectRecord;
  855.   UintR TapiConnectFilesize = capiConnectFilesize;
  856.   ApiConnectRecord * const regApiPtr = apiConnectptr.p;
  857.   locApiConnectptr.i = cfirstfreeApiConnectCopy;
  858.   ptrCheckGuard(locApiConnectptr, TapiConnectFilesize, localApiConnectRecord);
  859.   cfirstfreeApiConnectCopy = locApiConnectptr.p->nextApiConnect;
  860.   locApiConnectptr.p->nextApiConnect = RNIL;
  861.   regApiPtr->apiCopyRecord = locApiConnectptr.i;
  862.   regApiPtr->triggerPending = false;
  863.   regApiPtr->isIndexOp = false;
  864. }//Dbtc::seizeApiConnectCopy()
  865. void Dbtc::execDIVERIFYCONF(Signal* signal) 
  866. {
  867.   UintR TapiConnectptrIndex = signal->theData[0];
  868.   UintR TapiConnectFilesize = capiConnectFilesize;
  869.   UintR Tgci = signal->theData[1];
  870.   ApiConnectRecord *localApiConnectRecord = apiConnectRecord;
  871.   jamEntry();
  872.   if (ERROR_INSERTED(8017)) {
  873.     CLEAR_ERROR_INSERT_VALUE;
  874.     return;
  875.   }//if
  876.   if (TapiConnectptrIndex >= TapiConnectFilesize) {
  877.     TCKEY_abort(signal, 31);
  878.     return;
  879.   }//if
  880.   ApiConnectRecord * const regApiPtr = 
  881.                             &localApiConnectRecord[TapiConnectptrIndex];
  882.   ConnectionState TapiConnectstate = regApiPtr->apiConnectstate;
  883.   UintR TApifailureNr = regApiPtr->failureNr;
  884.   UintR Tfailure_nr = cfailure_nr;
  885.   apiConnectptr.i = TapiConnectptrIndex;
  886.   apiConnectptr.p = regApiPtr;
  887.   if (TapiConnectstate != CS_PREPARE_TO_COMMIT) {
  888.     TCKEY_abort(signal, 32);
  889.     return;
  890.   }//if
  891.   /*--------------------------------------------------------------------------
  892.    * THIS IS THE COMMIT POINT. IF WE ARRIVE HERE THE TRANSACTION IS COMMITTED 
  893.    * UNLESS EVERYTHING CRASHES BEFORE WE HAVE BEEN ABLE TO REPORT THE COMMIT 
  894.    * DECISION. THERE IS NO TURNING BACK FROM THIS DECISION FROM HERE ON.     
  895.    * WE WILL INSERT THE TRANSACTION INTO ITS PROPER QUEUE OF 
  896.    * TRANSACTIONS FOR ITS GLOBAL CHECKPOINT.              
  897.    *-------------------------------------------------------------------------*/
  898.   if (TApifailureNr != Tfailure_nr) {
  899.     DIVER_node_fail_handling(signal, Tgci);
  900.     return;
  901.   }//if
  902.   commitGciHandling(signal, Tgci);
  903.   /**************************************************************************
  904.    *                                 C O M M I T                      
  905.    * THE TRANSACTION HAVE NOW BEEN VERIFIED AND NOW THE COMMIT PHASE CAN START 
  906.    **************************************************************************/
  907.   UintR TtcConnectptrIndex = regApiPtr->firstTcConnect;
  908.   UintR TtcConnectFilesize = ctcConnectFilesize;
  909.   TcConnectRecord *localTcConnectRecord = tcConnectRecord;
  910.   regApiPtr->counter = regApiPtr->lqhkeyconfrec;
  911.   regApiPtr->apiConnectstate = CS_COMMITTING;
  912.   if (TtcConnectptrIndex >= TtcConnectFilesize) {
  913.     TCKEY_abort(signal, 33);
  914.     return;
  915.   }//if
  916.   TcConnectRecord* const regTcPtr = &localTcConnectRecord[TtcConnectptrIndex];
  917.   tcConnectptr.i = TtcConnectptrIndex;
  918.   tcConnectptr.p = regTcPtr;
  919.   commit020Lab(signal);
  920. }//Dbtc::execDIVERIFYCONF()
  921. /*--------------------------------------------------------------------------*/
  922. /*                             COMMIT_GCI_HANDLING                          */
  923. /*       SET UP GLOBAL CHECKPOINT DATA STRUCTURE AT THE COMMIT POINT.       */
  924. /*--------------------------------------------------------------------------*/
  925. void Dbtc::commitGciHandling(Signal* signal, UintR Tgci) 
  926. {
  927.   GcpRecordPtr localGcpPointer;
  928.   UintR TgcpFilesize = cgcpFilesize;
  929.   UintR Tfirstgcp = cfirstgcp;
  930.   ApiConnectRecord * const regApiPtr = apiConnectptr.p;
  931.   GcpRecord *localGcpRecord = gcpRecord;
  932.   regApiPtr->globalcheckpointid = Tgci;
  933.   if (Tfirstgcp != RNIL) {
  934.     /* IF THIS GLOBAL CHECKPOINT ALREADY EXISTS */
  935.     localGcpPointer.i = Tfirstgcp;
  936.     ptrCheckGuard(localGcpPointer, TgcpFilesize, localGcpRecord);
  937.     do {
  938.       if (regApiPtr->globalcheckpointid == localGcpPointer.p->gcpId) {
  939.         jam();
  940.         gcpPtr.i = localGcpPointer.i;
  941.         gcpPtr.p = localGcpPointer.p;
  942.         linkApiToGcp(signal);
  943.         return;
  944.       } else {
  945.         localGcpPointer.i = localGcpPointer.p->nextGcp;
  946.         jam();
  947.         if (localGcpPointer.i != RNIL) {
  948.           jam();
  949.           ptrCheckGuard(localGcpPointer, TgcpFilesize, localGcpRecord);
  950.           continue;
  951.         }//if
  952.       }//if
  953.       seizeGcp(signal);
  954.       linkApiToGcp(signal);
  955.       return;
  956.     } while (1);
  957.   } else {
  958.     jam();
  959.     seizeGcp(signal);
  960.     linkApiToGcp(signal);
  961.   }//if
  962. }//Dbtc::commitGciHandling()
  963. /* --------------------------------------------------------------------------*/
  964. /* -LINK AN API CONNECT RECORD IN STATE PREPARED INTO THE LIST WITH GLOBAL - */
  965. /* CHECKPOINTS. WHEN THE TRANSACTION I COMPLETED THE API CONNECT RECORD IS   */
  966. /* LINKED OUT OF THE LIST.                                                   */
  967. /*---------------------------------------------------------------------------*/
  968. void Dbtc::linkApiToGcp(Signal* signal) 
  969. {
  970.   ApiConnectRecordPtr localApiConnectptr;
  971.   ApiConnectRecord * const regApiPtr = apiConnectptr.p;
  972.   GcpRecord * const regGcpPtr = gcpPtr.p;
  973.   UintR TapiConnectptrIndex = apiConnectptr.i;
  974.   ApiConnectRecord *localApiConnectRecord = apiConnectRecord;
  975.   regApiPtr->nextGcpConnect = RNIL;
  976.   if (regGcpPtr->firstApiConnect == RNIL) {
  977.     regGcpPtr->firstApiConnect = TapiConnectptrIndex;
  978.     jam();
  979.   } else {
  980.     UintR TapiConnectFilesize = capiConnectFilesize;
  981.     localApiConnectptr.i = regGcpPtr->lastApiConnect;
  982.     jam();
  983.     ptrCheckGuard(localApiConnectptr,
  984.                   TapiConnectFilesize, localApiConnectRecord);
  985.     localApiConnectptr.p->nextGcpConnect = TapiConnectptrIndex;
  986.   }//if
  987.   UintR TlastApiConnect = regGcpPtr->lastApiConnect;
  988.   regApiPtr->gcpPointer = gcpPtr.i;
  989.   regApiPtr->prevGcpConnect = TlastApiConnect;
  990.   regGcpPtr->lastApiConnect = TapiConnectptrIndex;
  991. }//Dbtc::linkApiToGcp()
  992. void Dbtc::seizeGcp(Signal* signal) 
  993. {
  994.   GcpRecordPtr tmpGcpPointer;
  995.   GcpRecordPtr localGcpPointer;
  996.   UintR Tfirstgcp = cfirstgcp;
  997.   UintR Tglobalcheckpointid = apiConnectptr.p->globalcheckpointid;
  998.   UintR TgcpFilesize = cgcpFilesize;
  999.   GcpRecord *localGcpRecord = gcpRecord;
  1000.   localGcpPointer.i = cfirstfreeGcp;
  1001.   ptrCheckGuard(localGcpPointer, TgcpFilesize, localGcpRecord);
  1002.   UintR TfirstfreeGcp = localGcpPointer.p->nextGcp;
  1003.   localGcpPointer.p->gcpId = Tglobalcheckpointid;
  1004.   localGcpPointer.p->nextGcp = RNIL;
  1005.   localGcpPointer.p->firstApiConnect = RNIL;
  1006.   localGcpPointer.p->lastApiConnect = RNIL;
  1007.   localGcpPointer.p->gcpNomoretransRec = ZFALSE;
  1008.   cfirstfreeGcp = TfirstfreeGcp;
  1009.   if (Tfirstgcp == RNIL) {
  1010.     jam();
  1011.     cfirstgcp = localGcpPointer.i;
  1012.   } else {
  1013.     tmpGcpPointer.i = clastgcp;
  1014.     jam();
  1015.     ptrCheckGuard(tmpGcpPointer, TgcpFilesize, localGcpRecord);
  1016.     tmpGcpPointer.p->nextGcp = localGcpPointer.i;
  1017.   }//if
  1018.   clastgcp = localGcpPointer.i;
  1019.   gcpPtr = localGcpPointer;
  1020. }//Dbtc::seizeGcp()
  1021. /*---------------------------------------------------------------------------*/
  1022. // Send COMMIT messages to all LQH operations involved in the transaction.
  1023. /*---------------------------------------------------------------------------*/
  1024. void Dbtc::commit020Lab(Signal* signal) 
  1025. {
  1026.   TcConnectRecordPtr localTcConnectptr;
  1027.   ApiConnectRecord * const regApiPtr = apiConnectptr.p;
  1028.   UintR TtcConnectFilesize = ctcConnectFilesize;
  1029.   TcConnectRecord *localTcConnectRecord = tcConnectRecord;
  1030.   localTcConnectptr.p = tcConnectptr.p;
  1031.   setApiConTimer(apiConnectptr.i, ctcTimer, __LINE__);
  1032.   UintR Tcount = 0;
  1033.   do {
  1034.     /*-----------------------------------------------------------------------
  1035.      * WE ARE NOW READY TO RELEASE ALL OPERATIONS ON THE LQH                  
  1036.      *-----------------------------------------------------------------------*/
  1037.     /* *********< */
  1038.     /*  COMMIT  < */
  1039.     /* *********< */
  1040.     localTcConnectptr.i = localTcConnectptr.p->nextTcConnect;
  1041.     localTcConnectptr.p->tcConnectstate = OS_COMMITTING;
  1042.     sendCommitLqh(signal, localTcConnectptr.p);
  1043.     if (localTcConnectptr.i != RNIL) {
  1044.       Tcount = Tcount + 1;
  1045.       if (Tcount < 16) {
  1046.         ptrCheckGuard(localTcConnectptr,
  1047.                       TtcConnectFilesize, localTcConnectRecord);
  1048.         jam();
  1049.         continue;
  1050.       } else {
  1051.         jam();
  1052.         if (ERROR_INSERTED(8014)) {
  1053.           CLEAR_ERROR_INSERT_VALUE;
  1054.           return;
  1055.         }//if
  1056.         signal->theData[0] = TcContinueB::ZSEND_COMMIT_LOOP;
  1057.         signal->theData[1] = apiConnectptr.i;
  1058.         signal->theData[2] = localTcConnectptr.i;
  1059.         sendSignal(cownref, GSN_CONTINUEB, signal, 3, JBB);
  1060.         return;
  1061.       }//if
  1062.     } else {
  1063.       jam();
  1064.       regApiPtr->apiConnectstate = CS_COMMIT_SENT;
  1065.       return;
  1066.     }//if
  1067.   } while (1);
  1068. }//Dbtc::commit020Lab()
  1069. void Dbtc::sendCommitLqh(Signal* signal,
  1070.                          TcConnectRecord * const regTcPtr)
  1071. {
  1072.   HostRecordPtr Thostptr;
  1073.   UintR ThostFilesize = chostFilesize;
  1074.   ApiConnectRecord * const regApiPtr = apiConnectptr.p;
  1075.   Thostptr.i = regTcPtr->lastLqhNodeId;
  1076.   ptrCheckGuard(Thostptr, ThostFilesize, hostRecord);
  1077.   if (Thostptr.p->noOfPackedWordsLqh > 21) {
  1078.     jam();
  1079.     sendPackedSignalLqh(signal, Thostptr.p);
  1080.   } else {
  1081.     jam();
  1082.     updatePackedList(signal, Thostptr.p, Thostptr.i);
  1083.   }//if
  1084.   UintR Tindex = Thostptr.p->noOfPackedWordsLqh;
  1085.   UintR* TDataPtr = &Thostptr.p->packedWordsLqh[Tindex];
  1086.   UintR Tdata1 = regTcPtr->lastLqhCon;
  1087.   UintR Tdata2 = regApiPtr->globalcheckpointid;
  1088.   UintR Tdata3 = regApiPtr->transid[0];
  1089.   UintR Tdata4 = regApiPtr->transid[1];
  1090.   TDataPtr[0] = Tdata1 | (ZCOMMIT << 28);
  1091.   TDataPtr[1] = Tdata2;
  1092.   TDataPtr[2] = Tdata3;
  1093.   TDataPtr[3] = Tdata4;
  1094.   Thostptr.p->noOfPackedWordsLqh = Tindex + 4;
  1095. }//Dbtc::sendCommitLqh()
  1096. void
  1097. Dbtc::DIVER_node_fail_handling(Signal* signal, UintR Tgci)
  1098. {
  1099.   /*------------------------------------------------------------------------
  1100.    * AT LEAST ONE NODE HAS FAILED DURING THE TRANSACTION. WE NEED TO CHECK IF  
  1101.    * THIS IS SO SERIOUS THAT WE NEED TO ABORT THE TRANSACTION. IN BOTH THE     
  1102.    * ABORT AND THE COMMIT CASES WE NEED  TO SET-UP THE DATA FOR THE           
  1103.    * ABORT/COMMIT/COMPLETE  HANDLING AS ALSO USED BY TAKE OVER FUNCTIONALITY. 
  1104.    *------------------------------------------------------------------------*/
  1105.   tabortInd = ZFALSE;
  1106.   setupFailData(signal);
  1107.   if (false && tabortInd == ZFALSE) {
  1108.     jam();
  1109.     commitGciHandling(signal, Tgci);
  1110.     toCommitHandlingLab(signal);
  1111.   } else {
  1112.     jam();
  1113.     apiConnectptr.p->returnsignal = RS_TCROLLBACKREP;
  1114.     apiConnectptr.p->returncode = ZNODEFAIL_BEFORE_COMMIT;
  1115.     toAbortHandlingLab(signal);
  1116.   }//if
  1117.   return;
  1118. }//Dbtc::DIVER_node_fail_handling()
  1119. /* ------------------------------------------------------------------------- */
  1120. /* -------                       ENTER COMMITTED                     ------- */
  1121. /*                                                                           */
  1122. /* ------------------------------------------------------------------------- */
  1123. void Dbtc::execCOMMITTED(Signal* signal) 
  1124. {
  1125.   TcConnectRecordPtr localTcConnectptr;
  1126.   ApiConnectRecordPtr localApiConnectptr;
  1127.   UintR TtcConnectFilesize = ctcConnectFilesize;
  1128.   UintR TapiConnectFilesize = capiConnectFilesize;
  1129.   TcConnectRecord *localTcConnectRecord = tcConnectRecord;
  1130.   ApiConnectRecord *localApiConnectRecord = apiConnectRecord;
  1131. #ifdef ERROR_INSERT
  1132.   if (ERROR_INSERTED(8018)) {
  1133.     CLEAR_ERROR_INSERT_VALUE;
  1134.     return;
  1135.   }//if
  1136.   if (ERROR_INSERTED(8030)) {
  1137.     systemErrorLab(signal);
  1138.   }//if
  1139.   if (ERROR_INSERTED(8025)) {
  1140.     SET_ERROR_INSERT_VALUE(8026);
  1141.     return;
  1142.   }//if
  1143.   if (ERROR_INSERTED(8041)) {
  1144.     CLEAR_ERROR_INSERT_VALUE;
  1145.     sendSignalWithDelay(cownref, GSN_COMMITTED, signal, 2000, 3);
  1146.     return;
  1147.   }//if
  1148.   if (ERROR_INSERTED(8042)) {
  1149.     SET_ERROR_INSERT_VALUE(8046);
  1150.     sendSignalWithDelay(cownref, GSN_COMMITTED, signal, 2000, 4);
  1151.     return;
  1152.   }//if
  1153. #endif
  1154.   localTcConnectptr.i = signal->theData[0];
  1155.   jamEntry();
  1156.   ptrCheckGuard(localTcConnectptr, TtcConnectFilesize, localTcConnectRecord);
  1157.   localApiConnectptr.i = localTcConnectptr.p->apiConnect;
  1158.   if (localTcConnectptr.p->tcConnectstate != OS_COMMITTING) {
  1159.     warningReport(signal, 4);
  1160.     return;
  1161.   }//if
  1162.   ptrCheckGuard(localApiConnectptr, TapiConnectFilesize, 
  1163. localApiConnectRecord);
  1164.   UintR Tcounter = localApiConnectptr.p->counter - 1;
  1165.   ConnectionState TapiConnectstate = localApiConnectptr.p->apiConnectstate;
  1166.   UintR Tdata1 = localApiConnectptr.p->transid[0] - signal->theData[1];
  1167.   UintR Tdata2 = localApiConnectptr.p->transid[1] - signal->theData[2];
  1168.   Tdata1 = Tdata1 | Tdata2;
  1169.   bool TcheckCondition = 
  1170.     (TapiConnectstate != CS_COMMIT_SENT) || (Tcounter != 0);
  1171.   setApiConTimer(localApiConnectptr.i, ctcTimer, __LINE__);
  1172.   localApiConnectptr.p->counter = Tcounter;
  1173.   localTcConnectptr.p->tcConnectstate = OS_COMMITTED;
  1174.   if (Tdata1 != 0) {
  1175.     warningReport(signal, 5);
  1176.     return;
  1177.   }//if
  1178.   if (TcheckCondition) {
  1179.     jam();
  1180.     /*-------------------------------------------------------*/
  1181.     // We have not sent all COMMIT requests yet. We could be
  1182.     // in the state that all sent are COMMITTED but we are
  1183.     // still waiting for a CONTINUEB to send the rest of the
  1184.     // COMMIT requests.
  1185.     /*-------------------------------------------------------*/
  1186.     return;
  1187.   }//if
  1188.   if (ERROR_INSERTED(8020)) {
  1189.     jam();
  1190.     systemErrorLab(signal);
  1191.   }//if
  1192.   /*-------------------------------------------------------*/
  1193.   /* THE ENTIRE TRANSACTION IS NOW COMMITED                */
  1194.   /* NOW WE NEED TO SEND THE RESPONSE TO THE APPLICATION.  */
  1195.   /* THE APPLICATION CAN THEN REUSE THE API CONNECTION AND */
  1196.   /* THEREFORE WE NEED TO MOVE THE API CONNECTION TO A     */
  1197.   /* NEW API CONNECT RECORD.                               */
  1198.   /*-------------------------------------------------------*/
  1199.   apiConnectptr = localApiConnectptr;
  1200.   sendApiCommit(signal);
  1201.   ApiConnectRecord * const regApiPtr = apiConnectptr.p;
  1202.   localTcConnectptr.i = regApiPtr->firstTcConnect;
  1203.   UintR Tlqhkeyconfrec = regApiPtr->lqhkeyconfrec;
  1204.   ptrCheckGuard(localTcConnectptr, TtcConnectFilesize, localTcConnectRecord);
  1205.   regApiPtr->counter = Tlqhkeyconfrec;
  1206.   tcConnectptr = localTcConnectptr;
  1207.   complete010Lab(signal);
  1208.   return;
  1209. }//Dbtc::execCOMMITTED()
  1210. /*-------------------------------------------------------*/
  1211. /*                       SEND_API_COMMIT                 */
  1212. /*       SEND COMMIT DECISION TO THE API.                */
  1213. /*-------------------------------------------------------*/
  1214. void Dbtc::sendApiCommit(Signal* signal) 
  1215. {
  1216.   ApiConnectRecord * const regApiPtr = apiConnectptr.p;
  1217.   if (regApiPtr->returnsignal == RS_TCKEYCONF) {
  1218.     sendtckeyconf(signal, 1);
  1219.   } else if (regApiPtr->returnsignal == RS_TC_COMMITCONF) {
  1220.     jam();
  1221.     TcCommitConf * const commitConf = (TcCommitConf *)&signal->theData[0];
  1222.     if(regApiPtr->commitAckMarker == RNIL){
  1223.       jam();
  1224.       commitConf->apiConnectPtr = regApiPtr->ndbapiConnect;
  1225.     } else {
  1226.       jam();
  1227.       commitConf->apiConnectPtr = regApiPtr->ndbapiConnect | 1;
  1228.     }
  1229.     commitConf->transId1 = regApiPtr->transid[0];
  1230.     commitConf->transId2 = regApiPtr->transid[1];
  1231.     
  1232.     sendSignal(regApiPtr->ndbapiBlockref, GSN_TC_COMMITCONF, signal, 3, JBB);
  1233.   } else if (regApiPtr->returnsignal == RS_NO_RETURN) {
  1234.     jam();
  1235.   } else {
  1236.     TCKEY_abort(signal, 37);
  1237.     return;
  1238.   }//if
  1239.   UintR TapiConnectFilesize = capiConnectFilesize;
  1240.   UintR TcommitCount = c_counters.ccommitCount;
  1241.   UintR TapiIndex = apiConnectptr.i;
  1242.   UintR TnewApiIndex = regApiPtr->apiCopyRecord;
  1243.   UintR TapiFailState = regApiPtr->apiFailState;
  1244.   ApiConnectRecord *localApiConnectRecord = apiConnectRecord;
  1245.   tmpApiConnectptr.p = apiConnectptr.p;
  1246.   tmpApiConnectptr.i = TapiIndex;
  1247.   c_counters.ccommitCount = TcommitCount + 1;
  1248.   apiConnectptr.i = TnewApiIndex;
  1249.   ptrCheckGuard(apiConnectptr, TapiConnectFilesize, localApiConnectRecord);
  1250.   copyApi(signal);
  1251.   if (TapiFailState != ZTRUE) {
  1252.     return;
  1253.   } else {
  1254.     jam();
  1255.     handleApiFailState(signal, tmpApiConnectptr.i);
  1256.     return;
  1257.   }//if
  1258. }//Dbtc::sendApiCommit()
  1259. /* ========================================================================= */
  1260. /* =======                  COPY_API                                 ======= */
  1261. /*   COPY API RECORD ALSO RESET THE OLD API RECORD SO THAT IT                */
  1262. /*   IS PREPARED TO RECEIVE A NEW TRANSACTION.                               */
  1263. /*===========================================================================*/
  1264. void Dbtc::copyApi(Signal* signal) 
  1265. {
  1266.   ApiConnectRecord * const regApiPtr = apiConnectptr.p;
  1267.   ApiConnectRecord * const regTmpApiPtr = tmpApiConnectptr.p;
  1268.   UintR TndbapiConnect = regTmpApiPtr->ndbapiConnect;
  1269.   UintR TfirstTcConnect = regTmpApiPtr->firstTcConnect;
  1270.   UintR Ttransid1 = regTmpApiPtr->transid[0];
  1271.   UintR Ttransid2 = regTmpApiPtr->transid[1];
  1272.   UintR Tlqhkeyconfrec = regTmpApiPtr->lqhkeyconfrec;
  1273.   UintR TgcpPointer = regTmpApiPtr->gcpPointer;
  1274.   UintR TgcpFilesize = cgcpFilesize;
  1275.   UintR TcommitAckMarker = regTmpApiPtr->commitAckMarker;
  1276.   GcpRecord *localGcpRecord = gcpRecord;
  1277.   regApiPtr->ndbapiBlockref = regTmpApiPtr->ndbapiBlockref;
  1278.   regApiPtr->ndbapiConnect = TndbapiConnect;
  1279.   regApiPtr->firstTcConnect = TfirstTcConnect;
  1280.   regApiPtr->apiConnectstate = CS_COMPLETING;
  1281.   regApiPtr->transid[0] = Ttransid1;
  1282.   regApiPtr->transid[1] = Ttransid2;
  1283.   regApiPtr->lqhkeyconfrec = Tlqhkeyconfrec;
  1284.   regApiPtr->commitAckMarker = TcommitAckMarker;
  1285.   gcpPtr.i = TgcpPointer;
  1286.   ptrCheckGuard(gcpPtr, TgcpFilesize, localGcpRecord);
  1287.   unlinkApiConnect(signal);
  1288.   linkApiToGcp(signal);
  1289.   setApiConTimer(tmpApiConnectptr.i, 0, __LINE__);
  1290.   regTmpApiPtr->apiConnectstate = CS_CONNECTED;
  1291.   regTmpApiPtr->commitAckMarker = RNIL;
  1292.   regTmpApiPtr->firstTcConnect = RNIL;
  1293.   regTmpApiPtr->lastTcConnect = RNIL;
  1294.   releaseAllSeizedIndexOperations(regTmpApiPtr);
  1295. }//Dbtc::copyApi()
  1296. void Dbtc::unlinkApiConnect(Signal* signal) 
  1297. {
  1298.   ApiConnectRecordPtr localApiConnectptr;
  1299.   ApiConnectRecord * const regTmpApiPtr = tmpApiConnectptr.p;
  1300.   UintR TapiConnectFilesize = capiConnectFilesize;
  1301.   UintR TprevGcpConnect = regTmpApiPtr->prevGcpConnect;
  1302.   UintR TnextGcpConnect = regTmpApiPtr->nextGcpConnect;
  1303.   ApiConnectRecord *localApiConnectRecord = apiConnectRecord;
  1304.   if (TprevGcpConnect == RNIL) {
  1305.     gcpPtr.p->firstApiConnect = TnextGcpConnect;
  1306.     jam();
  1307.   } else {
  1308.     localApiConnectptr.i = TprevGcpConnect;
  1309.     jam();
  1310.     ptrCheckGuard(localApiConnectptr,
  1311.                   TapiConnectFilesize, localApiConnectRecord);
  1312.     localApiConnectptr.p->nextGcpConnect = TnextGcpConnect;
  1313.   }//if
  1314.   if (TnextGcpConnect == RNIL) {
  1315.     gcpPtr.p->lastApiConnect = TprevGcpConnect;
  1316.     jam();
  1317.   } else {
  1318.     localApiConnectptr.i = TnextGcpConnect;
  1319.     jam();
  1320.     ptrCheckGuard(localApiConnectptr,
  1321.                   TapiConnectFilesize, localApiConnectRecord);
  1322.     localApiConnectptr.p->prevGcpConnect = TprevGcpConnect;
  1323.   }//if
  1324. }//Dbtc::unlinkApiConnect()
  1325. void Dbtc::complete010Lab(Signal* signal) 
  1326. {
  1327.   TcConnectRecordPtr localTcConnectptr;
  1328.   ApiConnectRecord * const regApiPtr = apiConnectptr.p;
  1329.   UintR TtcConnectFilesize = ctcConnectFilesize;
  1330.   TcConnectRecord *localTcConnectRecord = tcConnectRecord;
  1331.   localTcConnectptr.p = tcConnectptr.p;
  1332.   setApiConTimer(apiConnectptr.i, ctcTimer, __LINE__);
  1333.   UintR TapiConnectptrIndex = apiConnectptr.i;
  1334.   UintR Tcount = 0;
  1335.   do {
  1336.     localTcConnectptr.p->apiConnect = TapiConnectptrIndex;
  1337.     localTcConnectptr.p->tcConnectstate = OS_COMPLETING;
  1338.     /* ************ */
  1339.     /*  COMPLETE  < */
  1340.     /* ************ */
  1341.     const Uint32 nextTcConnect = localTcConnectptr.p->nextTcConnect;
  1342.     sendCompleteLqh(signal, localTcConnectptr.p);
  1343.     localTcConnectptr.i = nextTcConnect;
  1344.     if (localTcConnectptr.i != RNIL) {
  1345.       Tcount++;
  1346.       if (Tcount < 16) {
  1347.         ptrCheckGuard(localTcConnectptr,
  1348.                       TtcConnectFilesize, localTcConnectRecord);
  1349.         jam();
  1350.         continue;
  1351.       } else {
  1352.         jam();
  1353.         if (ERROR_INSERTED(8013)) {
  1354.           CLEAR_ERROR_INSERT_VALUE;
  1355.           return;
  1356.         }//if
  1357.         signal->theData[0] = TcContinueB::ZSEND_COMPLETE_LOOP;
  1358.         signal->theData[1] = apiConnectptr.i;
  1359.         signal->theData[2] = localTcConnectptr.i;
  1360.         sendSignal(cownref, GSN_CONTINUEB, signal, 3, JBB);
  1361.         return;
  1362.       }//if
  1363.     } else {
  1364.       jam();
  1365.       regApiPtr->apiConnectstate = CS_COMPLETE_SENT;
  1366.       return;
  1367.     }//if
  1368.   } while (1);
  1369. }//Dbtc::complete010Lab()
  1370. void Dbtc::sendCompleteLqh(Signal* signal,
  1371.                            TcConnectRecord * const regTcPtr)
  1372. {
  1373.   HostRecordPtr Thostptr;
  1374.   UintR ThostFilesize = chostFilesize;
  1375.   ApiConnectRecord * const regApiPtr = apiConnectptr.p;
  1376.   Thostptr.i = regTcPtr->lastLqhNodeId;
  1377.   ptrCheckGuard(Thostptr, ThostFilesize, hostRecord);
  1378.   if (Thostptr.p->noOfPackedWordsLqh > 22) {
  1379.     jam();
  1380.     sendPackedSignalLqh(signal, Thostptr.p);
  1381.   } else {
  1382.     jam();
  1383.     updatePackedList(signal, Thostptr.p, Thostptr.i);
  1384.   }//if
  1385.   UintR Tindex = Thostptr.p->noOfPackedWordsLqh;
  1386.   UintR* TDataPtr = &Thostptr.p->packedWordsLqh[Tindex];
  1387.   UintR Tdata1 = regTcPtr->lastLqhCon | (ZCOMPLETE << 28);
  1388.   UintR Tdata2 = regApiPtr->transid[0];
  1389.   UintR Tdata3 = regApiPtr->transid[1];
  1390.   
  1391.   TDataPtr[0] = Tdata1;
  1392.   TDataPtr[1] = Tdata2;
  1393.   TDataPtr[2] = Tdata3;
  1394.   Thostptr.p->noOfPackedWordsLqh = Tindex + 3;
  1395. }//Dbtc::sendCompleteLqh()
  1396. void
  1397. Dbtc::execTC_COMMIT_ACK(Signal* signal){
  1398.   jamEntry();
  1399.   CommitAckMarker key;
  1400.   key.transid1 = signal->theData[0];
  1401.   key.transid2 = signal->theData[1];
  1402.   CommitAckMarkerPtr removedMarker;
  1403.   m_commitAckMarkerHash.release(removedMarker, key);
  1404.   if (removedMarker.i == RNIL) {
  1405.     jam();
  1406.     warningHandlerLab(signal);
  1407.     return;
  1408.   }//if
  1409.   sendRemoveMarkers(signal, removedMarker.p);
  1410. }
  1411. void
  1412. Dbtc::sendRemoveMarkers(Signal* signal, const CommitAckMarker * marker){
  1413.   jam();
  1414.   const Uint32 noOfLqhs = marker->noOfLqhs;
  1415.   const Uint32 transId1 = marker->transid1;
  1416.   const Uint32 transId2 = marker->transid2;
  1417.   
  1418.   for(Uint32 i = 0; i<noOfLqhs; i++){
  1419.     jam();
  1420.     const NodeId nodeId = marker->lqhNodeId[i];
  1421.     sendRemoveMarker(signal, nodeId, transId1, transId2);
  1422.   }
  1423. }
  1424. void
  1425. Dbtc::sendRemoveMarker(Signal* signal, 
  1426.                        NodeId nodeId,
  1427.                        Uint32 transid1, 
  1428.                        Uint32 transid2){
  1429.   /**
  1430.    * Seize host ptr
  1431.    */
  1432.   HostRecordPtr hostPtr;
  1433.   const UintR ThostFilesize = chostFilesize;
  1434.   hostPtr.i = nodeId;
  1435.   ptrCheckGuard(hostPtr, ThostFilesize, hostRecord);
  1436.   if (hostPtr.p->noOfPackedWordsLqh > (25 - 3)){
  1437.     jam();
  1438.     sendPackedSignalLqh(signal, hostPtr.p);
  1439.   } else {
  1440.     jam();
  1441.     updatePackedList(signal, hostPtr.p, hostPtr.i);
  1442.   }//if
  1443.   
  1444.   UintR  numWord = hostPtr.p->noOfPackedWordsLqh;
  1445.   UintR* dataPtr = &hostPtr.p->packedWordsLqh[numWord];
  1446.   dataPtr[0] = (ZREMOVE_MARKER << 28);
  1447.   dataPtr[1] = transid1;
  1448.   dataPtr[2] = transid2;
  1449.   hostPtr.p->noOfPackedWordsLqh = numWord + 3;
  1450. }
  1451. void Dbtc::execCOMPLETED(Signal* signal) 
  1452. {
  1453.   TcConnectRecordPtr localTcConnectptr;
  1454.   ApiConnectRecordPtr localApiConnectptr;
  1455.   UintR TtcConnectFilesize = ctcConnectFilesize;
  1456.   UintR TapiConnectFilesize = capiConnectFilesize;
  1457.   TcConnectRecord *localTcConnectRecord = tcConnectRecord;
  1458.   ApiConnectRecord *localApiConnectRecord = apiConnectRecord;
  1459. #ifdef ERROR_INSERT
  1460.   if (ERROR_INSERTED(8031)) {
  1461.     systemErrorLab(signal);
  1462.   }//if
  1463.   if (ERROR_INSERTED(8019)) {
  1464.     CLEAR_ERROR_INSERT_VALUE;
  1465.     return;
  1466.   }//if
  1467.   if (ERROR_INSERTED(8027)) {
  1468.     SET_ERROR_INSERT_VALUE(8028);
  1469.     return;
  1470.   }//if
  1471.   if (ERROR_INSERTED(8043)) {
  1472.     CLEAR_ERROR_INSERT_VALUE;
  1473.     sendSignalWithDelay(cownref, GSN_COMPLETED, signal, 2000, 3);
  1474.     return;
  1475.   }//if
  1476.   if (ERROR_INSERTED(8044)) {
  1477.     SET_ERROR_INSERT_VALUE(8047);
  1478.     sendSignalWithDelay(cownref, GSN_COMPLETED, signal, 2000, 3);
  1479.     return;
  1480.   }//if
  1481. #endif
  1482.   localTcConnectptr.i = signal->theData[0];
  1483.   jamEntry();
  1484.   ptrCheckGuard(localTcConnectptr, TtcConnectFilesize, localTcConnectRecord);
  1485.   bool Tcond1 = (localTcConnectptr.p->tcConnectstate != OS_COMPLETING);
  1486.   localApiConnectptr.i = localTcConnectptr.p->apiConnect;
  1487.   if (Tcond1) {
  1488.     warningReport(signal, 6);
  1489.     return;
  1490.   }//if
  1491.   ptrCheckGuard(localApiConnectptr, TapiConnectFilesize, 
  1492. localApiConnectRecord);
  1493.   UintR Tdata1 = localApiConnectptr.p->transid[0] - signal->theData[1];
  1494.   UintR Tdata2 = localApiConnectptr.p->transid[1] - signal->theData[2];
  1495.   UintR Tcounter = localApiConnectptr.p->counter - 1;
  1496.   ConnectionState TapiConnectstate = localApiConnectptr.p->apiConnectstate;
  1497.   Tdata1 = Tdata1 | Tdata2;
  1498.   bool TcheckCondition = 
  1499.     (TapiConnectstate != CS_COMPLETE_SENT) || (Tcounter != 0);
  1500.   if (Tdata1 != 0) {
  1501.     warningReport(signal, 7);
  1502.     return;
  1503.   }//if
  1504.   setApiConTimer(localApiConnectptr.i, ctcTimer, __LINE__);
  1505.   localApiConnectptr.p->counter = Tcounter;
  1506.   localTcConnectptr.p->tcConnectstate = OS_COMPLETED;
  1507.   localTcConnectptr.p->noOfNodes = 0; // == releaseNodes(signal)
  1508.   if (TcheckCondition) {
  1509.     jam();
  1510.     /*-------------------------------------------------------*/
  1511.     // We have not sent all COMPLETE requests yet. We could be
  1512.     // in the state that all sent are COMPLETED but we are
  1513.     // still waiting for a CONTINUEB to send the rest of the
  1514.     // COMPLETE requests.
  1515.     /*-------------------------------------------------------*/
  1516.     return;
  1517.   }//if
  1518.   if (ERROR_INSERTED(8021)) {
  1519.     jam();
  1520.     systemErrorLab(signal);
  1521.   }//if
  1522.   apiConnectptr = localApiConnectptr;
  1523.   releaseTransResources(signal);
  1524. }//Dbtc::execCOMPLETED()
  1525. /*---------------------------------------------------------------------------*/
  1526. /*                               RELEASE_TRANS_RESOURCES                     */
  1527. /*       RELEASE ALL RESOURCES THAT ARE CONNECTED TO THIS TRANSACTION.       */
  1528. /*---------------------------------------------------------------------------*/
  1529. void Dbtc::releaseTransResources(Signal* signal) 
  1530. {
  1531.   TcConnectRecordPtr localTcConnectptr;
  1532.   UintR TtcConnectFilesize = ctcConnectFilesize;
  1533.   TcConnectRecord *localTcConnectRecord = tcConnectRecord;
  1534.   localTcConnectptr.i = apiConnectptr.p->firstTcConnect;
  1535.   do {
  1536.     jam();
  1537.     ptrCheckGuard(localTcConnectptr, TtcConnectFilesize, localTcConnectRecord);
  1538.     UintR rtrTcConnectptrIndex = localTcConnectptr.p->nextTcConnect;
  1539.     tcConnectptr.i = localTcConnectptr.i;
  1540.     tcConnectptr.p = localTcConnectptr.p;
  1541.     localTcConnectptr.i = rtrTcConnectptrIndex;
  1542.     releaseTcCon();
  1543.   } while (localTcConnectptr.i != RNIL);
  1544.   handleGcp(signal);
  1545.   releaseFiredTriggerData(&apiConnectptr.p->theFiredTriggers);
  1546.   releaseAllSeizedIndexOperations(apiConnectptr.p);
  1547.   releaseApiConCopy(signal);
  1548. }//Dbtc::releaseTransResources()
  1549. /* *********************************************************************>> */
  1550. /*       MODULE: HANDLE_GCP                                                */
  1551. /*       DESCRIPTION: HANDLES GLOBAL CHECKPOINT HANDLING AT THE COMPLETION */
  1552. /*       OF THE COMMIT PHASE AND THE ABORT PHASE. WE MUST ENSURE THAT TC   */
  1553. /*       SENDS GCP_TCFINISHED WHEN ALL TRANSACTIONS BELONGING TO A CERTAIN */
  1554. /*       GLOBAL CHECKPOINT HAVE COMPLETED.                                 */
  1555. /* *********************************************************************>> */
  1556. void Dbtc::handleGcp(Signal* signal) 
  1557. {
  1558.   GcpRecord *localGcpRecord = gcpRecord;
  1559.   GcpRecordPtr localGcpPtr;
  1560.   UintR TapiConnectptrIndex = apiConnectptr.i;
  1561.   UintR TgcpFilesize = cgcpFilesize;
  1562.   localGcpPtr.i = apiConnectptr.p->gcpPointer;
  1563.   tmpApiConnectptr.i = TapiConnectptrIndex;
  1564.   tmpApiConnectptr.p = apiConnectptr.p;
  1565.   ptrCheckGuard(localGcpPtr, TgcpFilesize, localGcpRecord);
  1566.   gcpPtr.i = localGcpPtr.i;
  1567.   gcpPtr.p = localGcpPtr.p;
  1568.   unlinkApiConnect(signal);
  1569.   if (localGcpPtr.p->firstApiConnect == RNIL) {
  1570.     if (localGcpPtr.p->gcpNomoretransRec == ZTRUE) {
  1571.       jam();
  1572.       tcheckGcpId = localGcpPtr.p->gcpId;
  1573.       gcpTcfinished(signal);
  1574.       unlinkGcp(signal);
  1575.     }//if
  1576.   }//if
  1577. }//Dbtc::handleGcp()
  1578. void Dbtc::releaseApiConCopy(Signal* signal) 
  1579. {
  1580.   ApiConnectRecord * const regApiPtr = apiConnectptr.p;
  1581.   UintR TfirstfreeApiConnectCopyOld = cfirstfreeApiConnectCopy;
  1582.   cfirstfreeApiConnectCopy = apiConnectptr.i;
  1583.   regApiPtr->nextApiConnect = TfirstfreeApiConnectCopyOld;
  1584.   setApiConTimer(apiConnectptr.i, 0, __LINE__);
  1585.   regApiPtr->apiConnectstate = CS_RESTART;
  1586. }//Dbtc::releaseApiConCopy()
  1587. /* ========================================================================= */
  1588. /* -------  RELEASE ALL RECORDS CONNECTED TO A DIRTY WRITE OPERATION ------- */
  1589. /* ========================================================================= */
  1590. void Dbtc::releaseDirtyWrite(Signal* signal) 
  1591. {
  1592.   unlinkReadyTcCon(signal);
  1593.   releaseTcCon();
  1594.   ApiConnectRecord * const regApiPtr = apiConnectptr.p;
  1595.   if (regApiPtr->apiConnectstate == CS_START_COMMITTING) {
  1596.     if (regApiPtr->firstTcConnect == RNIL) {
  1597.       jam();
  1598.       regApiPtr->apiConnectstate = CS_CONNECTED;
  1599.       setApiConTimer(apiConnectptr.i, 0, __LINE__);
  1600.       sendtckeyconf(signal, 1);
  1601.     }//if
  1602.   }//if
  1603. }//Dbtc::releaseDirtyWrite()
  1604. /*****************************************************************************
  1605.  *                               L Q H K E Y R E F                          
  1606.  * WHEN LQHKEYREF IS RECEIVED DBTC WILL CHECK IF COMMIT FLAG WAS SENT FROM THE
  1607.  * APPLICATION. IF SO, THE WHOLE TRANSACTION WILL BE ROLLED BACK AND SIGNAL  
  1608.  * TCROLLBACKREP WILL BE SENT TO THE API.                                    
  1609.  *                                                                          
  1610.  * OTHERWISE TC WILL CHECK THE ERRORCODE. IF THE ERRORCODE IS INDICATING THAT
  1611.  * THE "ROW IS NOT FOUND" FOR UPDATE/READ/DELETE OPERATIONS AND "ROW ALREADY 
  1612.  * EXISTS" FOR INSERT OPERATIONS, DBTC WILL RELEASE THE OPERATION AND THEN   
  1613.  * SEND RETURN SIGNAL TCKEYREF TO THE USER. THE USER THEN HAVE TO SEND     
  1614.  * SIGNAL TC_COMMITREQ OR TC_ROLLBACKREQ TO CONCLUDE THE TRANSACTION. 
  1615.  * IF ANY TCKEYREQ WITH COMMIT IS RECEIVED AND API_CONNECTSTATE EQUALS 
  1616.  * "REC_LQHREFUSE",
  1617.  * THE OPERATION WILL BE TREATED AS AN OPERATION WITHOUT COMMIT. WHEN ANY    
  1618.  * OTHER FAULTCODE IS RECEIVED THE WHOLE TRANSACTION MUST BE ROLLED BACK     
  1619.  *****************************************************************************/
  1620. void Dbtc::execLQHKEYREF(Signal* signal) 
  1621. {
  1622.   const LqhKeyRef * const lqhKeyRef = (LqhKeyRef *)signal->getDataPtr();
  1623.   jamEntry();
  1624.   
  1625.   UintR compare_transid1, compare_transid2;
  1626.   UintR TtcConnectFilesize = ctcConnectFilesize;
  1627.   /*-------------------------------------------------------------------------
  1628.    *                                                                         
  1629.    * RELEASE NODE BUFFER(S) TO INDICATE THAT THIS OPERATION HAVE NO 
  1630.    * TRANSACTION PARTS ACTIVE ANYMORE. 
  1631.    * LQHKEYREF HAVE CLEARED ALL PARTS ON ITS PATH BACK TO TC.
  1632.    *-------------------------------------------------------------------------*/
  1633.   if (lqhKeyRef->connectPtr < TtcConnectFilesize) {
  1634.     /*-----------------------------------------------------------------------
  1635.      * WE HAVE TO CHECK THAT THE TRANSACTION IS STILL VALID. FIRST WE CHECK 
  1636.      * THAT THE LQH IS STILL CONNECTED TO A TC, IF THIS HOLDS TRUE THEN THE 
  1637.      * TC MUST BE CONNECTED TO AN API CONNECT RECORD. 
  1638.      * WE MUST ENSURE THAT THE TRANSACTION ID OF THIS API CONNECT 
  1639.      * RECORD IS STILL THE SAME AS THE ONE LQHKEYREF REFERS TO. 
  1640.      * IF NOT SIMPLY EXIT AND FORGET THE SIGNAL SINCE THE TRANSACTION IS    
  1641.      * ALREADY COMPLETED (ABORTED).
  1642.      *-----------------------------------------------------------------------*/
  1643.     tcConnectptr.i = lqhKeyRef->connectPtr;
  1644.     Uint32 errCode = terrorCode = lqhKeyRef->errorCode;
  1645.     ptrAss(tcConnectptr, tcConnectRecord);
  1646.     TcConnectRecord * const regTcPtr = tcConnectptr.p;
  1647.     if (regTcPtr->tcConnectstate == OS_OPERATING) {
  1648.       apiConnectptr.i = regTcPtr->apiConnect;
  1649.       ptrCheckGuard(apiConnectptr, capiConnectFilesize, apiConnectRecord);
  1650.       ApiConnectRecord * const regApiPtr = apiConnectptr.p;
  1651.       compare_transid1 = regApiPtr->transid[0] ^ lqhKeyRef->transId1;
  1652.       compare_transid2 = regApiPtr->transid[1] ^ lqhKeyRef->transId2;
  1653.       compare_transid1 = compare_transid1 | compare_transid2;
  1654.       if (compare_transid1 != 0) {
  1655. warningReport(signal, 25);
  1656. return;
  1657.       }//if
  1658.       const ConnectionState state = regApiPtr->apiConnectstate;
  1659.       const Uint32 triggeringOp = regTcPtr->triggeringOperation;
  1660.       if (triggeringOp != RNIL) {
  1661.         jam();
  1662. // This operation was created by a trigger execting operation
  1663. TcConnectRecordPtr opPtr;
  1664. TcConnectRecord *localTcConnectRecord = tcConnectRecord;
  1665.        
  1666. const Uint32 currentIndexId = regTcPtr->currentIndexId;
  1667. ndbassert(currentIndexId != 0); // Only index triggers so far
  1668. opPtr.i = triggeringOp;
  1669. ptrCheckGuard(opPtr, ctcConnectFilesize, localTcConnectRecord);
  1670. // The operation executed an index trigger
  1671. const Uint32 opType = regTcPtr->operation;
  1672. if (errCode == ZALREADYEXIST)
  1673.   errCode = terrorCode = ZNOTUNIQUE;
  1674. else if (!(opType == ZDELETE && errCode == ZNOT_FOUND)) {
  1675.   jam();
  1676.   /**
  1677.    * "Normal path"
  1678.    */
  1679.   // fall-through
  1680. } else {
  1681.   jam();
  1682.   /** ZDELETE && NOT_FOUND */
  1683.   TcIndexData* indexData = c_theIndexes.getPtr(currentIndexId);
  1684.   if(indexData->indexState == IS_BUILDING && state != CS_ABORTING){
  1685.     jam();
  1686.     /**
  1687.      * Ignore error
  1688.      */
  1689.     regApiPtr->lqhkeyconfrec++;
  1690.     
  1691.     unlinkReadyTcCon(signal);
  1692.     releaseTcCon();
  1693.     
  1694.     opPtr.p->triggerExecutionCount--;
  1695.     if (opPtr.p->triggerExecutionCount == 0) {
  1696.       /**
  1697.        * We have completed current trigger execution
  1698.        * Continue triggering operation
  1699.        */
  1700.       jam();
  1701.       continueTriggeringOp(signal, opPtr.p);
  1702.     }
  1703.     return;
  1704.   }
  1705. }
  1706.       }
  1707.       
  1708.       Uint32 marker = regTcPtr->commitAckMarker;
  1709.       markOperationAborted(regApiPtr, regTcPtr);
  1710.       
  1711.       if(regApiPtr->apiConnectstate == CS_ABORTING){
  1712. /**
  1713.  * We're already aborting' so don't send an "extra" TCKEYREF
  1714.  */
  1715. jam();
  1716. return;
  1717.       }
  1718.       
  1719.       const Uint32 abort = regTcPtr->m_execAbortOption;
  1720.       if (abort == TcKeyReq::AbortOnError || triggeringOp != RNIL) {
  1721. /**
  1722.  * No error is allowed on this operation
  1723.  */
  1724. TCKEY_abort(signal, 49);
  1725. return;
  1726.       }//if
  1727.       if (marker != RNIL){
  1728. /**
  1729.  * This was an insert/update/delete/write which failed
  1730.  *   that contained the marker
  1731.  * Currently unsupported to place new marker
  1732.  */
  1733. TCKEY_abort(signal, 49);
  1734. return;
  1735.       }
  1736.       
  1737.       /* *************** */
  1738.       /*    TCKEYREF   < */
  1739.       /* *************** */
  1740.       TcKeyRef * const tcKeyRef = (TcKeyRef *) signal->getDataPtrSend();
  1741.       tcKeyRef->transId[0] = regApiPtr->transid[0];
  1742.       tcKeyRef->transId[1] = regApiPtr->transid[1];
  1743.       tcKeyRef->errorCode = terrorCode;
  1744.       bool isIndexOp = regTcPtr->isIndexOp;
  1745.       Uint32 indexOp = tcConnectptr.p->indexOp;
  1746.       Uint32 clientData = regTcPtr->clientData;
  1747.       unlinkReadyTcCon(signal);   /* LINK TC CONNECT RECORD OUT OF  */
  1748.       releaseTcCon();       /* RELEASE THE TC CONNECT RECORD  */
  1749.       setApiConTimer(apiConnectptr.i, ctcTimer, __LINE__);
  1750.       if (isIndexOp) {
  1751.         jam();
  1752. regApiPtr->lqhkeyreqrec--; // Compensate for extra during read
  1753. tcKeyRef->connectPtr = indexOp;
  1754. EXECUTE_DIRECT(DBTC, GSN_TCKEYREF, signal, TcKeyRef::SignalLength);
  1755. apiConnectptr.i = regTcPtr->apiConnect;
  1756. apiConnectptr.p = regApiPtr;
  1757.       } else {
  1758.         jam();
  1759. tcKeyRef->connectPtr = clientData;
  1760. sendSignal(regApiPtr->ndbapiBlockref, 
  1761.    GSN_TCKEYREF, signal, TcKeyRef::SignalLength, JBB);
  1762.       }//if
  1763.       
  1764.       /*---------------------------------------------------------------------
  1765.        * SINCE WE ARE NOT ABORTING WE NEED TO UPDATE THE COUNT OF HOW MANY 
  1766.        * LQHKEYREQ THAT HAVE RETURNED. 
  1767.        * IF NO MORE OUTSTANDING LQHKEYREQ'S THEN WE NEED TO 
  1768.        * TCKEYCONF (IF THERE IS ANYTHING TO SEND).          
  1769.        *---------------------------------------------------------------------*/
  1770.       regApiPtr->lqhkeyreqrec--;
  1771.       if (regApiPtr->lqhkeyconfrec == regApiPtr->lqhkeyreqrec) {
  1772. if (regApiPtr->apiConnectstate == CS_START_COMMITTING) {
  1773.   if(regApiPtr->lqhkeyconfrec) {
  1774.     jam();
  1775.     diverify010Lab(signal);
  1776.   } else {
  1777.     jam();
  1778.     sendtckeyconf(signal, 1);
  1779.     regApiPtr->apiConnectstate = CS_CONNECTED;
  1780.   }
  1781.   return;
  1782. } else if (regApiPtr->tckeyrec > 0 || regApiPtr->m_exec_flag) {
  1783.   jam();
  1784.   sendtckeyconf(signal, 2);
  1785.   return;
  1786. }
  1787.       }//if
  1788.       return;
  1789.       
  1790.     } else {
  1791.       warningReport(signal, 26);
  1792.     }//if
  1793.   } else {
  1794.     errorReport(signal, 6);
  1795.   }//if
  1796.   return;
  1797. }//Dbtc::execLQHKEYREF()
  1798. void Dbtc::clearCommitAckMarker(ApiConnectRecord * const regApiPtr,
  1799. TcConnectRecord * const regTcPtr)
  1800. {
  1801.   const Uint32 commitAckMarker = regTcPtr->commitAckMarker;
  1802.   if (regApiPtr->commitAckMarker == RNIL)
  1803.     ndbassert(commitAckMarker == RNIL);
  1804.   if (commitAckMarker != RNIL)
  1805.     ndbassert(regApiPtr->commitAckMarker != RNIL);
  1806.   if(commitAckMarker != RNIL){
  1807.     jam();
  1808.     m_commitAckMarkerHash.release(commitAckMarker);
  1809.     regTcPtr->commitAckMarker = RNIL;
  1810.     regApiPtr->commitAckMarker = RNIL;
  1811.   }
  1812. }
  1813. void Dbtc::markOperationAborted(ApiConnectRecord * const regApiPtr,
  1814. TcConnectRecord * const regTcPtr)
  1815. {
  1816.   /*------------------------------------------------------------------------
  1817.    * RELEASE NODES TO INDICATE THAT THE OPERATION IS ALREADY ABORTED IN THE 
  1818.    * LQH'S ALSO SET STATE TO ABORTING TO INDICATE THE ABORT IS 
  1819.    * ALREADY COMPLETED.  
  1820.    *------------------------------------------------------------------------*/
  1821.   regTcPtr->noOfNodes = 0; // == releaseNodes(signal)
  1822.   regTcPtr->tcConnectstate = OS_ABORTING;
  1823.   clearCommitAckMarker(regApiPtr, regTcPtr);
  1824. }
  1825. /*--------------------------------------*/
  1826. /* EXIT AND WAIT FOR SIGNAL TCOMMITREQ  */
  1827. /* OR TCROLLBACKREQ FROM THE USER TO    */
  1828. /* CONTINUE THE TRANSACTION             */
  1829. /*--------------------------------------*/
  1830. void Dbtc::execTC_COMMITREQ(Signal* signal) 
  1831. {
  1832.   UintR compare_transid1, compare_transid2;
  1833.   jamEntry();
  1834.   apiConnectptr.i = signal->theData[0];
  1835.   if (apiConnectptr.i < capiConnectFilesize) {
  1836.     ptrAss(apiConnectptr, apiConnectRecord);
  1837.     compare_transid1 = apiConnectptr.p->transid[0] ^ signal->theData[1];
  1838.     compare_transid2 = apiConnectptr.p->transid[1] ^ signal->theData[2];
  1839.     compare_transid1 = compare_transid1 | compare_transid2;
  1840.     if (compare_transid1 != 0) {
  1841.       jam();
  1842.       return;
  1843.     }//if
  1844.     
  1845.     ApiConnectRecord * const regApiPtr = apiConnectptr.p;
  1846.     const Uint32 apiConnectPtr = regApiPtr->ndbapiConnect;
  1847.     const Uint32 apiBlockRef   = regApiPtr->ndbapiBlockref;
  1848.     const Uint32 transId1      = regApiPtr->transid[0];
  1849.     const Uint32 transId2      = regApiPtr->transid[1];
  1850.     Uint32 errorCode           = 0;
  1851.     regApiPtr->m_exec_flag = 1;
  1852.     switch (regApiPtr->apiConnectstate) {
  1853.     case CS_STARTED:
  1854.       tcConnectptr.i = regApiPtr->firstTcConnect;
  1855.       if (tcConnectptr.i != RNIL) {
  1856.         ptrCheckGuard(tcConnectptr, ctcConnectFilesize, tcConnectRecord);
  1857.         if (regApiPtr->lqhkeyconfrec == regApiPtr->lqhkeyreqrec) {
  1858.           jam();
  1859.           /*******************************************************************/
  1860.           // The proper case where the application is waiting for commit or 
  1861.           // abort order.
  1862.           // Start the commit order.
  1863.           /*******************************************************************/
  1864.           regApiPtr->returnsignal = RS_TC_COMMITCONF;
  1865.           setApiConTimer(apiConnectptr.i, ctcTimer, __LINE__);
  1866.           diverify010Lab(signal);
  1867.           return;
  1868.         } else {
  1869.           jam();
  1870.           /*******************************************************************/
  1871.           // The transaction is started but not all operations are completed. 
  1872.           // It is not possible to commit the transaction in this state. 
  1873.           // We will abort it instead.
  1874.           /*******************************************************************/
  1875.           regApiPtr->returnsignal = RS_NO_RETURN;
  1876.           errorCode = ZTRANS_STATUS_ERROR;
  1877.           abort010Lab(signal);
  1878.         }//if
  1879.       } else {
  1880.         jam();
  1881.         /**
  1882.          * No operations, accept commit
  1883.          */
  1884.         TcCommitConf * const commitConf = (TcCommitConf *)&signal->theData[0];
  1885.         commitConf->apiConnectPtr = apiConnectPtr;
  1886.         commitConf->transId1 = transId1;
  1887.         commitConf->transId2 = transId2;
  1888.         
  1889.         sendSignal(apiBlockRef, GSN_TC_COMMITCONF, signal, 3, JBB);
  1890.         
  1891.         regApiPtr->returnsignal = RS_NO_RETURN;
  1892.         releaseAbortResources(signal);
  1893.         return;
  1894.       }//if
  1895.       break;
  1896.     case CS_RECEIVING:
  1897.       jam();
  1898.       /***********************************************************************/
  1899.       // A transaction is still receiving data. We cannot commit an unfinished 
  1900.       // transaction. We will abort it instead.
  1901.       /***********************************************************************/
  1902.       regApiPtr->returnsignal = RS_NO_RETURN;
  1903.       errorCode = ZPREPAREINPROGRESS;
  1904.       abort010Lab(signal);
  1905.       break;
  1906.       
  1907.     case CS_START_COMMITTING:
  1908.     case CS_COMMITTING:
  1909.     case CS_COMMIT_SENT:
  1910.     case CS_COMPLETING:
  1911.     case CS_COMPLETE_SENT:
  1912.     case CS_REC_COMMITTING:
  1913.     case CS_PREPARE_TO_COMMIT:
  1914.       jam();
  1915.       /***********************************************************************/
  1916.       // The transaction is already performing a commit but it is not concluded
  1917.       // yet.
  1918.       /***********************************************************************/
  1919.       errorCode = ZCOMMITINPROGRESS;
  1920.       break;
  1921.     case CS_ABORTING:
  1922.       jam();
  1923.       errorCode = ZABORTINPROGRESS;
  1924.       break;
  1925.     case CS_START_SCAN:
  1926.       jam();
  1927.       /***********************************************************************/
  1928.       // The transaction is a scan. Scans cannot commit
  1929.       /***********************************************************************/
  1930.       errorCode = ZSCANINPROGRESS;
  1931.       break;
  1932.     case CS_PREPARED:
  1933.       jam();
  1934.       return;
  1935.     case CS_START_PREPARING:
  1936.       jam();
  1937.       return;
  1938.     case CS_REC_PREPARING:
  1939.       jam();
  1940.       return;
  1941.       break;
  1942.     default:
  1943.       warningHandlerLab(signal);
  1944.       return;
  1945.     }//switch
  1946.     TcCommitRef * const commitRef = (TcCommitRef*)&signal->theData[0];
  1947.     commitRef->apiConnectPtr = apiConnectPtr;
  1948.     commitRef->transId1 = transId1;
  1949.     commitRef->transId2 = transId2;
  1950.     commitRef->errorCode = errorCode;
  1951.     sendSignal(apiBlockRef, GSN_TC_COMMITREF, signal, 
  1952.        TcCommitRef::SignalLength, JBB);
  1953.     return;
  1954.   } else /** apiConnectptr.i < capiConnectFilesize */ {
  1955.     jam();
  1956.     warningHandlerLab(signal);
  1957.     return;
  1958.   }
  1959. }//Dbtc::execTC_COMMITREQ()
  1960. void Dbtc::execTCROLLBACKREQ(Signal* signal) 
  1961. {
  1962.   UintR compare_transid1, compare_transid2;
  1963.   jamEntry();
  1964.   apiConnectptr.i = signal->theData[0];
  1965.   if (apiConnectptr.i >= capiConnectFilesize) {
  1966.     goto TC_ROLL_warning;
  1967.   }//if
  1968.   ptrAss(apiConnectptr, apiConnectRecord);
  1969.   compare_transid1 = apiConnectptr.p->transid[0] ^ signal->theData[1];
  1970.   compare_transid2 = apiConnectptr.p->transid[1] ^ signal->theData[2];
  1971.   compare_transid1 = compare_transid1 | compare_transid2;
  1972.   if (compare_transid1 != 0) {
  1973.     jam();
  1974.     return;
  1975.   }//if
  1976.   apiConnectptr.p->m_exec_flag = 1;
  1977.   switch (apiConnectptr.p->apiConnectstate) {
  1978.   case CS_STARTED:
  1979.   case CS_RECEIVING:
  1980.     jam();
  1981.     apiConnectptr.p->returnsignal = RS_TCROLLBACKCONF;
  1982.     abort010Lab(signal);
  1983.     return;
  1984.   case CS_CONNECTED:
  1985.     jam();
  1986.     signal->theData[0] = apiConnectptr.p->ndbapiConnect;
  1987.     signal->theData[1] = apiConnectptr.p->transid[0];
  1988.     signal->theData[2] = apiConnectptr.p->transid[1];
  1989.     sendSignal(apiConnectptr.p->ndbapiBlockref, GSN_TCROLLBACKCONF, 
  1990.        signal, 3, JBB);
  1991.     break;
  1992.   case CS_START_SCAN:
  1993.   case CS_PREPARE_TO_COMMIT:
  1994.   case CS_COMMITTING:
  1995.   case CS_COMMIT_SENT:
  1996.   case CS_COMPLETING:
  1997.   case CS_COMPLETE_SENT:
  1998.   case CS_WAIT_COMMIT_CONF:
  1999.   case CS_WAIT_COMPLETE_CONF:
  2000.   case CS_RESTART:
  2001.   case CS_DISCONNECTED:
  2002.   case CS_START_COMMITTING:
  2003.   case CS_REC_COMMITTING:
  2004.     jam();
  2005.     /* ***************< */
  2006.     /* TC_ROLLBACKREF < */
  2007.     /* ***************< */
  2008.     signal->theData[0] = apiConnectptr.p->ndbapiConnect;
  2009.     signal->theData[1] = apiConnectptr.p->transid[0];
  2010.     signal->theData[2] = apiConnectptr.p->transid[1];
  2011.     signal->theData[3] = ZROLLBACKNOTALLOWED;
  2012.     signal->theData[4] = apiConnectptr.p->apiConnectstate;
  2013.     sendSignal(apiConnectptr.p->ndbapiBlockref, GSN_TCROLLBACKREF, 
  2014.        signal, 5, JBB);
  2015.     break;
  2016.                                                  /* SEND A REFUSAL SIGNAL*/
  2017.   case CS_ABORTING:
  2018.     jam();
  2019.     if (apiConnectptr.p->abortState == AS_IDLE) {
  2020.       jam();
  2021.       signal->theData[0] = apiConnectptr.p->ndbapiConnect;
  2022.       signal->theData[1] = apiConnectptr.p->transid[0];
  2023.       signal->theData[2] = apiConnectptr.p->transid[1];
  2024.       sendSignal(apiConnectptr.p->ndbapiBlockref, GSN_TCROLLBACKCONF, 
  2025.  signal, 3, JBB);
  2026.     } else {
  2027.       jam();
  2028.       apiConnectptr.p->returnsignal = RS_TCROLLBACKCONF;
  2029.     }//if
  2030.     break;
  2031.   case CS_WAIT_ABORT_CONF:
  2032.     jam();
  2033.     apiConnectptr.p->returnsignal = RS_TCROLLBACKCONF;
  2034.     break;
  2035.   case CS_START_PREPARING:
  2036.     jam();
  2037.   case CS_PREPARED:
  2038.     jam();
  2039.   case CS_REC_PREPARING:
  2040.     jam();
  2041.   default:
  2042.     goto TC_ROLL_system_error;
  2043.     break;
  2044.   }//switch
  2045.   return;
  2046. TC_ROLL_warning:
  2047.   jam();
  2048.   warningHandlerLab(signal);
  2049.   return;
  2050. TC_ROLL_system_error:
  2051.   jam();
  2052.   systemErrorLab(signal);
  2053.   return;
  2054. }//Dbtc::execTCROLLBACKREQ()
  2055. void Dbtc::execTC_HBREP(Signal* signal) 
  2056. {
  2057.   const TcHbRep * const tcHbRep = 
  2058.     (TcHbRep *)signal->getDataPtr();
  2059.   jamEntry();
  2060.   apiConnectptr.i = tcHbRep->apiConnectPtr;
  2061.   ptrCheckGuard(apiConnectptr, capiConnectFilesize, apiConnectRecord);
  2062.   if (apiConnectptr.p->transid[0] == tcHbRep->transId1 &&
  2063.       apiConnectptr.p->transid[1] == tcHbRep->transId2){
  2064.     if (getApiConTimer(apiConnectptr.i) != 0){
  2065.       setApiConTimer(apiConnectptr.i, ctcTimer, __LINE__);
  2066.     } else {
  2067.       DEBUG("TCHBREP received when timer was off apiConnectptr.i=" 
  2068.     << apiConnectptr.i);
  2069.     }
  2070.   }
  2071. }//Dbtc::execTCHBREP()
  2072. /*
  2073. 4.3.15 ABORT 
  2074. -----------
  2075. */
  2076. /*****************************************************************************/
  2077. /*                                  A B O R T                                */
  2078. /*                                                                           */
  2079. /*****************************************************************************/
  2080. void Dbtc::warningReport(Signal* signal, int place)
  2081. {
  2082.   switch (place) {
  2083.   case 0:
  2084.     jam();
  2085. #ifdef ABORT_TRACE
  2086.     ndbout << "ABORTED to not active TC record" << endl;
  2087. #endif
  2088.     break;
  2089.   case 1:
  2090.     jam();
  2091. #ifdef ABORT_TRACE
  2092.     ndbout << "ABORTED to TC record active with new transaction" << endl;
  2093. #endif
  2094.     break;
  2095.   case 2:
  2096.     jam();
  2097. #ifdef ABORT_TRACE
  2098.     ndbout << "ABORTED to active TC record not expecting ABORTED" << endl;
  2099. #endif
  2100.     break;
  2101.   case 3:
  2102.     jam();
  2103. #ifdef ABORT_TRACE
  2104.     ndbout << "ABORTED to TC rec active with trans but wrong node" << endl;
  2105.     ndbout << "This is ok when aborting in node failure situations" << endl;
  2106. #endif
  2107.     break;
  2108.   case 4:
  2109.     jam();
  2110. #ifdef ABORT_TRACE
  2111.     ndbout << "Received COMMITTED in wrong state in Dbtc" << endl;
  2112. #endif
  2113.     break;
  2114.   case 5:
  2115.     jam();
  2116. #ifdef ABORT_TRACE
  2117.     ndbout << "Received COMMITTED with wrong transid in Dbtc" << endl;
  2118. #endif
  2119.     break;
  2120.   case 6:
  2121.     jam();
  2122. #ifdef ABORT_TRACE
  2123.     ndbout << "Received COMPLETED in wrong state in Dbtc" << endl;
  2124. #endif
  2125.     break;
  2126.   case 7:
  2127.     jam();
  2128. #ifdef ABORT_TRACE
  2129.     ndbout << "Received COMPLETED with wrong transid in Dbtc" << endl;
  2130. #endif
  2131.     break;
  2132.   case 8:
  2133.     jam();
  2134. #ifdef ABORT_TRACE
  2135.     ndbout << "Received COMMITCONF with tc-rec in wrong state in Dbtc" << endl;
  2136. #endif
  2137.     break;
  2138.   case 9:
  2139.     jam();
  2140. #ifdef ABORT_TRACE
  2141.     ndbout << "Received COMMITCONF with api-rec in wrong state in Dbtc" <<endl;
  2142. #endif
  2143.     break;
  2144.   case 10:
  2145.     jam();
  2146. #ifdef ABORT_TRACE
  2147.     ndbout << "Received COMMITCONF with wrong transid in Dbtc" << endl;
  2148. #endif
  2149.     break;
  2150.   case 11:
  2151.     jam();
  2152. #ifdef ABORT_TRACE
  2153.     ndbout << "Received COMMITCONF from wrong nodeid in Dbtc" << endl;
  2154. #endif
  2155.     break;
  2156.   case 12:
  2157.     jam();
  2158. #ifdef ABORT_TRACE
  2159.     ndbout << "Received COMPLETECONF, tc-rec in wrong state in Dbtc" << endl;
  2160. #endif
  2161.     break;
  2162.   case 13:
  2163.     jam();
  2164. #ifdef ABORT_TRACE
  2165.     ndbout << "Received COMPLETECONF, api-rec in wrong state in Dbtc" << endl;
  2166. #endif
  2167.     break;
  2168.   case 14:
  2169.     jam();
  2170. #ifdef ABORT_TRACE
  2171.     ndbout << "Received COMPLETECONF with wrong transid in Dbtc" << endl;
  2172. #endif
  2173.     break;
  2174.   case 15:
  2175.     jam();
  2176. #ifdef ABORT_TRACE
  2177.     ndbout << "Received COMPLETECONF from wrong nodeid in Dbtc" << endl;
  2178. #endif
  2179.     break;
  2180.   case 16:
  2181.     jam();
  2182. #ifdef ABORT_TRACE
  2183.     ndbout << "Received ABORTCONF, tc-rec in wrong state in Dbtc" << endl;
  2184. #endif
  2185.     break;
  2186.   case 17:
  2187.     jam();
  2188. #ifdef ABORT_TRACE
  2189.     ndbout << "Received ABORTCONF, api-rec in wrong state in Dbtc" << endl;
  2190. #endif
  2191.     break;
  2192.   case 18:
  2193.     jam();
  2194. #ifdef ABORT_TRACE
  2195.     ndbout << "Received ABORTCONF with wrong transid in Dbtc" << endl;
  2196. #endif
  2197.     break;
  2198.   case 19:
  2199.     jam();
  2200. #ifdef ABORT_TRACE
  2201.     ndbout << "Received ABORTCONF from wrong nodeid in Dbtc" << endl;
  2202. #endif
  2203.     break;
  2204.   case 20:
  2205.     jam();
  2206. #ifdef ABORT_TRACE
  2207.     ndbout << "Time-out waiting for ABORTCONF in Dbtc" << endl;
  2208. #endif
  2209.     break;
  2210.   case 21:
  2211.     jam();
  2212. #ifdef ABORT_TRACE
  2213.     ndbout << "Time-out waiting for COMMITCONF in Dbtc" << endl;
  2214. #endif
  2215.     break;
  2216.   case 22:
  2217.     jam();
  2218. #ifdef ABORT_TRACE
  2219.     ndbout << "Time-out waiting for COMPLETECONF in Dbtc" << endl;
  2220. #endif
  2221.     break;
  2222.   case 23:
  2223.     jam();
  2224. #ifdef ABORT_TRACE
  2225.     ndbout << "Received LQHKEYCONF in wrong tc-state in Dbtc" << endl;
  2226. #endif
  2227.     break;
  2228.   case 24:
  2229.     jam();
  2230. #ifdef ABORT_TRACE
  2231.     ndbout << "Received LQHKEYREF to wrong transid in Dbtc" << endl;
  2232. #endif
  2233.     break;
  2234.   case 25:
  2235.     jam();
  2236. #ifdef ABORT_TRACE
  2237.     ndbout << "Received LQHKEYREF in wrong state in Dbtc" << endl;
  2238. #endif
  2239.     break;
  2240.   case 26:
  2241.     jam();
  2242. #ifdef ABORT_TRACE
  2243.     ndbout << "Received LQHKEYCONF to wrong transid in Dbtc" << endl;
  2244. #endif
  2245.     break;
  2246.   case 27:
  2247.     jam();
  2248.     // printState(signal, 27);
  2249. #ifdef ABORT_TRACE
  2250.     ndbout << "Received LQHKEYCONF in wrong api-state in Dbtc" << endl;
  2251. #endif
  2252.     break;
  2253.   default:
  2254.     jam();
  2255.     break;
  2256.   }//switch
  2257.   return;
  2258. }//Dbtc::warningReport()
  2259. void Dbtc::errorReport(Signal* signal, int place)
  2260. {
  2261.   switch (place) {
  2262.   case 0:
  2263.     jam();
  2264.     break;
  2265.   case 1:
  2266.     jam();
  2267.     break;
  2268.   case 2:
  2269.     jam();
  2270.     break;
  2271.   case 3:
  2272.     jam();
  2273.     break;
  2274.   case 4:
  2275.     jam();
  2276.     break;
  2277.   case 5:
  2278.     jam();
  2279.     break;
  2280.   case 6:
  2281.     jam();
  2282.     break;
  2283.   default:
  2284.     jam();
  2285.     break;
  2286.   }//switch
  2287.   systemErrorLab(signal);
  2288.   return;
  2289. }//Dbtc::errorReport()
  2290. /* ------------------------------------------------------------------------- */
  2291. /* -------                       ENTER ABORTED                       ------- */
  2292. /*                                                                           */
  2293. /*-------------------------------------------------------------------------- */
  2294. void Dbtc::execABORTED(Signal* signal) 
  2295. {
  2296.   UintR compare_transid1, compare_transid2;
  2297.   jamEntry();
  2298.   tcConnectptr.i = signal->theData[0];
  2299.   UintR Tnodeid = signal->theData[3];
  2300.   UintR TlastLqhInd = signal->theData[4];
  2301.   if (ERROR_INSERTED(8040)) {
  2302.     CLEAR_ERROR_INSERT_VALUE;
  2303.     sendSignalWithDelay(cownref, GSN_ABORTED, signal, 2000, 5);
  2304.     return;
  2305.   }//if
  2306.   /*------------------------------------------------------------------------
  2307.    *    ONE PARTICIPANT IN THE TRANSACTION HAS REPORTED THAT IT IS ABORTED.
  2308.    *------------------------------------------------------------------------*/
  2309.   if (tcConnectptr.i >= ctcConnectFilesize) {
  2310.     errorReport(signal, 0);
  2311.     return;
  2312.   }//if
  2313.   /*-------------------------------------------------------------------------
  2314.    *     WE HAVE TO CHECK THAT THIS IS NOT AN OLD SIGNAL BELONGING TO A     
  2315.    *     TRANSACTION ALREADY ABORTED. THIS CAN HAPPEN WHEN TIME-OUT OCCURS  
  2316.    *     IN TC WAITING FOR ABORTED.                                         
  2317.    *-------------------------------------------------------------------------*/
  2318.   ptrAss(tcConnectptr, tcConnectRecord);
  2319.   if (tcConnectptr.p->tcConnectstate != OS_ABORT_SENT) {
  2320.     warningReport(signal, 2);
  2321.     return;
  2322.     /*-----------------------------------------------------------------------*/
  2323.     // ABORTED reported on an operation not expecting ABORT.
  2324.     /*-----------------------------------------------------------------------*/
  2325.   }//if
  2326.   apiConnectptr.i = tcConnectptr.p->apiConnect;
  2327.   if (apiConnectptr.i >= capiConnectFilesize) {
  2328.     warningReport(signal, 0);
  2329.     return;
  2330.   }//if
  2331.   ptrAss(apiConnectptr, apiConnectRecord);
  2332.   compare_transid1 = apiConnectptr.p->transid[0] ^ signal->theData[1];
  2333.   compare_transid2 = apiConnectptr.p->transid[1] ^ signal->theData[2];
  2334.   compare_transid1 = compare_transid1 | compare_transid2;
  2335.   if (compare_transid1 != 0) {
  2336.     warningReport(signal, 1);
  2337.     return;
  2338.   }//if
  2339.   if (ERROR_INSERTED(8024)) {
  2340.     jam();
  2341.     systemErrorLab(signal);
  2342.   }//if
  2343.   /**
  2344.    * Release marker
  2345.    */
  2346.   clearCommitAckMarker(apiConnectptr.p, tcConnectptr.p);
  2347.   Uint32 i;
  2348.   Uint32 Tfound = 0;
  2349.   for (i = 0; i < tcConnectptr.p->noOfNodes; i++) {
  2350.     jam();
  2351.     if (tcConnectptr.p->tcNodedata[i] == Tnodeid) {
  2352.       /*---------------------------------------------------------------------
  2353.        * We have received ABORTED from one of the participants in this 
  2354.        * operation in this aborted transaction.
  2355.        * Record all nodes that have completed abort.
  2356.        * If last indicator is set it means that no more replica has 
  2357.        * heard of the operation and are thus also aborted.
  2358.        *---------------------------------------------------------------------*/
  2359.       jam();
  2360.       Tfound = 1;
  2361.       clearTcNodeData(signal, TlastLqhInd, i);
  2362.     }//if
  2363.   }//for
  2364.   if (Tfound == 0) {
  2365.     warningReport(signal, 3);
  2366.     return;
  2367.   }
  2368.   for (i = 0; i < tcConnectptr.p->noOfNodes; i++) {
  2369.     if (tcConnectptr.p->tcNodedata[i] != 0) {
  2370.       /*--------------------------------------------------------------------
  2371.        * There are still outstanding ABORTED's to wait for.
  2372.        *--------------------------------------------------------------------*/
  2373.       jam();
  2374.       return;
  2375.     }//if
  2376.   }//for
  2377.   tcConnectptr.p->noOfNodes = 0;
  2378.   tcConnectptr.p->tcConnectstate = OS_ABORTING;
  2379.   setApiConTimer(apiConnectptr.i, ctcTimer, __LINE__);
  2380.   apiConnectptr.p->counter--;
  2381.   if (apiConnectptr.p->counter > 0) {
  2382.     jam();
  2383.     /*----------------------------------------------------------------------
  2384.      *       WE ARE STILL WAITING FOR MORE PARTICIPANTS TO SEND ABORTED.    
  2385.      *----------------------------------------------------------------------*/
  2386.     return;
  2387.   }//if
  2388.   /*------------------------------------------------------------------------*/
  2389.   /*                                                                        */
  2390.   /*     WE HAVE NOW COMPLETED THE ABORT PROCESS. WE HAVE RECEIVED ABORTED  */
  2391.   /*     FROM ALL PARTICIPANTS IN THE TRANSACTION. WE CAN NOW RELEASE ALL   */
  2392.   /*     RESOURCES CONNECTED TO THE TRANSACTION AND SEND THE ABORT RESPONSE */
  2393.   /*------------------------------------------------------------------------*/
  2394.   releaseAbortResources(signal);
  2395. }//Dbtc::execABORTED()
  2396. void Dbtc::clearTcNodeData(Signal* signal, 
  2397.                            UintR TLastLqhIndicator,
  2398.                            UintR Tstart) 
  2399. {
  2400.   UintR Ti;
  2401.   if (TLastLqhIndicator == ZTRUE) {
  2402.     for (Ti = Tstart ; Ti < tcConnectptr.p->noOfNodes; Ti++) {
  2403.       jam();
  2404.       tcConnectptr.p->tcNodedata[Ti] = 0;
  2405.     }//for
  2406.   } else {
  2407.     jam();
  2408.     tcConnectptr.p->tcNodedata[Tstart] = 0;
  2409.   }//for
  2410. }//clearTcNodeData()
  2411. void Dbtc::abortErrorLab(Signal* signal) 
  2412. {
  2413.   ptrGuard(apiConnectptr);
  2414.   ApiConnectRecord * transP = apiConnectptr.p;
  2415.   if (transP->apiConnectstate == CS_ABORTING && transP->abortState != AS_IDLE){
  2416.     jam();
  2417.     return;
  2418.   }
  2419.   transP->returnsignal = RS_TCROLLBACKREP;
  2420.   if(transP->returncode == 0){
  2421.     jam();
  2422.     transP->returncode = terrorCode;
  2423.   }
  2424.   abort010Lab(signal);
  2425. }//Dbtc::abortErrorLab()
  2426. void Dbtc::abort010Lab(Signal* signal) 
  2427. {
  2428.   ApiConnectRecord * transP = apiConnectptr.p;
  2429.   if (transP->apiConnectstate == CS_ABORTING && transP->abortState != AS_IDLE){
  2430.     jam();
  2431.     return;
  2432.   }
  2433.   transP->apiConnectstate = CS_ABORTING;
  2434.   /*------------------------------------------------------------------------*/
  2435.   /*     AN ABORT DECISION HAS BEEN TAKEN FOR SOME REASON. WE NEED TO ABORT */
  2436.   /*     ALL PARTICIPANTS IN THE TRANSACTION.                               */
  2437.   /*------------------------------------------------------------------------*/
  2438.   transP->abortState = AS_ACTIVE;
  2439.   transP->counter = 0;
  2440.   if (transP->firstTcConnect == RNIL) {
  2441.     jam();
  2442.     /*-----------------------------------------------------------------------*/
  2443.     /*    WE HAVE NO PARTICIPANTS IN THE TRANSACTION.                        */
  2444.     /*-----------------------------------------------------------------------*/
  2445.     releaseAbortResources(signal);
  2446.     return;
  2447.   }//if
  2448.   tcConnectptr.i = transP->firstTcConnect;
  2449.   abort015Lab(signal);
  2450. }//Dbtc::abort010Lab()
  2451. /*--------------------------------------------------------------------------*/
  2452. /*                                                                          */
  2453. /*       WE WILL ABORT ONE NODE PER OPERATION AT A TIME. THIS IS TO KEEP    */
  2454. /*       ERROR HANDLING OF THIS PROCESS FAIRLY SIMPLE AND TRACTABLE.        */
  2455. /*       EVEN IF NO NODE OF THIS PARTICULAR NODE NUMBER NEEDS ABORTION WE   */
  2456. /*       MUST ENSURE THAT ALL NODES ARE CHECKED. THUS A FAULTY NODE DOES    */
  2457. /*       NOT MEAN THAT ALL NODES IN AN OPERATION IS ABORTED. FOR THIS REASON*/
  2458. /*       WE SET THE TCONTINUE_ABORT TO TRUE WHEN A FAULTY NODE IS DETECTED. */
  2459. /*--------------------------------------------------------------------------*/
  2460. void Dbtc::abort015Lab(Signal* signal) 
  2461. {
  2462.   Uint32 TloopCount = 0;
  2463. ABORT020:
  2464.   jam();
  2465.   TloopCount++;
  2466.   ptrCheckGuard(tcConnectptr, ctcConnectFilesize, tcConnectRecord);
  2467.   switch (tcConnectptr.p->tcConnectstate) {
  2468.   case OS_WAIT_DIH:
  2469.   case OS_WAIT_KEYINFO:
  2470.   case OS_WAIT_ATTR:
  2471.     jam();
  2472.     /*----------------------------------------------------------------------*/
  2473.     /* WE ARE STILL WAITING FOR MORE KEYINFO/ATTRINFO. WE HAVE NOT CONTACTED*/
  2474.     /* ANY LQH YET AND SO WE CAN SIMPLY SET STATE TO ABORTING.              */
  2475.     /*----------------------------------------------------------------------*/
  2476.     tcConnectptr.p->noOfNodes = 0; // == releaseAbort(signal)
  2477.     tcConnectptr.p->tcConnectstate = OS_ABORTING;
  2478.     break;
  2479.   case OS_CONNECTED:
  2480.     jam();
  2481.     /*-----------------------------------------------------------------------
  2482.      *   WE ARE STILL IN THE INITIAL PHASE OF THIS OPERATION. 
  2483.      *   NEED NOT BOTHER ABOUT ANY LQH ABORTS.
  2484.      *-----------------------------------------------------------------------*/
  2485.     tcConnectptr.p->noOfNodes = 0; // == releaseAbort(signal)
  2486.     tcConnectptr.p->tcConnectstate = OS_ABORTING;
  2487.     break;
  2488.   case OS_PREPARED:
  2489.     jam();
  2490.   case OS_OPERATING:
  2491.     jam();
  2492.     /*----------------------------------------------------------------------
  2493.      * WE HAVE SENT LQHKEYREQ AND ARE IN SOME STATE OF EITHER STILL       
  2494.      * SENDING THE OPERATION, WAITING FOR REPLIES, WAITING FOR MORE       
  2495.      * ATTRINFO OR OPERATION IS PREPARED. WE NEED TO ABORT ALL LQH'S.     
  2496.      *----------------------------------------------------------------------*/
  2497.     releaseAndAbort(signal);
  2498.     tcConnectptr.p->tcConnectstate = OS_ABORT_SENT;
  2499.     TloopCount += 127;
  2500.     break;
  2501.   case OS_ABORTING:
  2502.     jam();
  2503.     break;
  2504.   case OS_ABORT_SENT:
  2505.     jam();
  2506.     DEBUG("ABORT_SENT state in abort015Lab(), not expected");
  2507.     systemErrorLab(signal);
  2508.     return;
  2509.   default:
  2510.     jam();
  2511.     DEBUG("tcConnectstate = " << tcConnectptr.p->tcConnectstate);
  2512.     systemErrorLab(signal);
  2513.     return;
  2514.   }//switch
  2515.   if (tcConnectptr.p->nextTcConnect != RNIL) {
  2516.     jam();
  2517.     tcConnectptr.i = tcConnectptr.p->nextTcConnect;
  2518.     if (TloopCount < 1024) {
  2519.       goto ABORT020;
  2520.     } else {
  2521.       jam();
  2522.       /*---------------------------------------------------------------------
  2523.        * Reset timer to avoid time-out in real-time break.
  2524.        * Increase counter to ensure that we don't think that all ABORTED have
  2525.        * been received before all have been sent.
  2526.        *---------------------------------------------------------------------*/
  2527.       apiConnectptr.p->counter++;
  2528.       setApiConTimer(apiConnectptr.i, ctcTimer, __LINE__);
  2529.       signal->theData[0] = TcContinueB::ZABORT_BREAK;
  2530.       signal->theData[1] = tcConnectptr.i;
  2531.       signal->theData[2] = apiConnectptr.i;
  2532.       sendSignal(cownref, GSN_CONTINUEB, signal, 3, JBB);
  2533.       return;
  2534.     }//if
  2535.   }//if
  2536.   if (apiConnectptr.p->counter > 0) {
  2537.     jam();
  2538.     setApiConTimer(apiConnectptr.i, ctcTimer, __LINE__);
  2539.     return;
  2540.   }//if
  2541.   /*-----------------------------------------------------------------------
  2542.    *    WE HAVE NOW COMPLETED THE ABORT PROCESS. WE HAVE RECEIVED ABORTED 
  2543.    *    FROM ALL PARTICIPANTS IN THE TRANSACTION. WE CAN NOW RELEASE ALL  
  2544.    *    RESOURCES CONNECTED TO THE TRANSACTION AND SEND THE ABORT RESPONSE
  2545.    *------------------------------------------------------------------------*/
  2546.   releaseAbortResources(signal);
  2547. }//Dbtc::abort015Lab()
  2548. /*--------------------------------------------------------------------------*/
  2549. /*       RELEASE KEY AND ATTRINFO OBJECTS AND SEND ABORT TO THE LQH BLOCK.  */
  2550. /*--------------------------------------------------------------------------*/
  2551. int Dbtc::releaseAndAbort(Signal* signal) 
  2552. {
  2553.   HostRecordPtr localHostptr;
  2554.   UintR TnoLoops = tcConnectptr.p->noOfNodes;
  2555.   
  2556.   apiConnectptr.p->counter++;
  2557.   bool prevAlive = false;
  2558.   for (Uint32 Ti = 0; Ti < TnoLoops ; Ti++) {
  2559.     localHostptr.i = tcConnectptr.p->tcNodedata[Ti];
  2560.     ptrCheckGuard(localHostptr, chostFilesize, hostRecord);
  2561.     if (localHostptr.p->hostStatus == HS_ALIVE) {
  2562.       jam();
  2563.       if (prevAlive) {
  2564.         // if previous is alive, its LQH forwards abort to this node
  2565.         jam();
  2566.         continue;
  2567.       }
  2568.       /* ************< */
  2569.       /*    ABORT    < */
  2570.       /* ************< */
  2571.       tblockref = calcLqhBlockRef(localHostptr.i);
  2572.       signal->theData[0] = tcConnectptr.i;
  2573.       signal->theData[1] = cownref;
  2574.       signal->theData[2] = apiConnectptr.p->transid[0];
  2575.       signal->theData[3] = apiConnectptr.p->transid[1];
  2576.       sendSignal(tblockref, GSN_ABORT, signal, 4, JBB);
  2577.       prevAlive = true;
  2578.     } else {
  2579.       jam();
  2580.       signal->theData[0] = tcConnectptr.i;
  2581.       signal->theData[1] = apiConnectptr.p->transid[0];
  2582.       signal->theData[2] = apiConnectptr.p->transid[1];
  2583.       signal->theData[3] = localHostptr.i;
  2584.       signal->theData[4] = ZFALSE;
  2585.       sendSignal(cownref, GSN_ABORTED, signal, 5, JBB);
  2586.       prevAlive = false;
  2587.     }//if
  2588.   }//for
  2589.   return 1;
  2590. }//Dbtc::releaseAndAbort()
  2591. /* ------------------------------------------------------------------------- */
  2592. /* -------                       ENTER TIME_SIGNAL                   ------- */
  2593. /*                                                                           */
  2594. /* ------------------------------------------------------------------------- */
  2595. void Dbtc::execTIME_SIGNAL(Signal* signal) 
  2596. {
  2597.   
  2598.   jamEntry();
  2599.   ctcTimer++;
  2600.   if (csystemStart != SSS_TRUE) {
  2601.     jam();
  2602.     return;
  2603.   }//if
  2604.   checkStartTimeout(signal);
  2605.   checkStartFragTimeout(signal);
  2606. }//Dbtc::execTIME_SIGNAL()
  2607. /*------------------------------------------------*/
  2608. /* Start timeout handling if not already going on */
  2609. /*------------------------------------------------*/
  2610. void Dbtc::checkStartTimeout(Signal* signal)
  2611. {
  2612.   ctimeOutCheckCounter++;
  2613.   if (ctimeOutCheckActive == TOCS_TRUE) {
  2614.     jam();
  2615.     // Check heartbeat of timeout loop
  2616.     if(ctimeOutCheckHeartbeat > ctimeOutCheckLastHeartbeat){
  2617.       jam();
  2618.       ctimeOutMissedHeartbeats = 0;      
  2619.     }else{
  2620.       jam();
  2621.       ctimeOutMissedHeartbeats++;
  2622.       if (ctimeOutMissedHeartbeats > 100){
  2623. jam();
  2624. systemErrorLab(signal);
  2625.       }
  2626.     }
  2627.     ctimeOutCheckLastHeartbeat = ctimeOutCheckHeartbeat;
  2628.     return;
  2629.   }//if
  2630.   if (ctimeOutCheckCounter < ctimeOutCheckDelay) {
  2631.     jam();
  2632.     /*------------------------------------------------------------------*/
  2633.     /*                                                                  */
  2634.     /*       NO TIME-OUT CHECKED THIS TIME. WAIT MORE.                  */
  2635.     /*------------------------------------------------------------------*/
  2636.     return;
  2637.   }//if
  2638.   ctimeOutCheckActive = TOCS_TRUE;
  2639.   ctimeOutCheckCounter = 0;
  2640.   timeOutLoopStartLab(signal, 0); // 0 is first api connect record
  2641.   return;
  2642. }//Dbtc::execTIME_SIGNAL()
  2643. /*----------------------------------------------------------------*/
  2644. /* Start fragment (scan) timeout handling if not already going on */
  2645. /*----------------------------------------------------------------*/
  2646. void Dbtc::checkStartFragTimeout(Signal* signal)
  2647. {
  2648.   ctimeOutCheckFragCounter++;
  2649.   if (ctimeOutCheckFragActive == TOCS_TRUE) {
  2650.     jam();
  2651.     return;
  2652.   }//if
  2653.   if (ctimeOutCheckFragCounter < ctimeOutCheckDelay) {
  2654.     jam();
  2655.     /*------------------------------------------------------------------*/
  2656.     /*       NO TIME-OUT CHECKED THIS TIME. WAIT MORE.                  */
  2657.     /*------------------------------------------------------------------*/
  2658.     return;
  2659.   }//if
  2660.   // Go through the fragment records and look for timeout in a scan.
  2661.   ctimeOutCheckFragActive = TOCS_TRUE;
  2662.   ctimeOutCheckFragCounter = 0;
  2663.   timeOutLoopStartFragLab(signal, 0); // 0 means first scan record
  2664. }//checkStartFragTimeout()
  2665. /*------------------------------------------------------------------*/
  2666. /*       IT IS NOW TIME TO CHECK WHETHER ANY TRANSACTIONS HAVE      */
  2667. /*       BEEN DELAYED FOR SO LONG THAT WE ARE FORCED TO PERFORM     */
  2668. /*       SOME ACTION, EITHER ABORT OR RESEND OR REMOVE A NODE FROM  */
  2669. /*       THE WAITING PART OF A PROTOCOL.                            */
  2670. /*
  2671. The algorithm used here is to check 1024 transactions at a time before
  2672. doing a real-time break.
  2673. To avoid aborting both transactions in a deadlock detected by time-out
  2674. we insert a random extra time-out of upto 630 ms by using the lowest
  2675. six bits of the api connect reference.
  2676. We spread it out from 0 to 630 ms if base time-out is larger than 3 sec,
  2677. we spread it out from 0 to 70 ms if base time-out is smaller than 300 msec,
  2678. and otherwise we spread it out 310 ms.
  2679. */
  2680. /*------------------------------------------------------------------*/
  2681. void Dbtc::timeOutLoopStartLab(Signal* signal, Uint32 api_con_ptr) 
  2682. {
  2683.   Uint32 end_ptr, time_passed, time_out_value, mask_value;
  2684.   const Uint32 api_con_sz= capiConnectFilesize;
  2685.   const Uint32 tc_timer= ctcTimer;
  2686.   const Uint32 time_out_param= ctimeOutValue;
  2687.   ctimeOutCheckHeartbeat = tc_timer;
  2688.   if (api_con_ptr + 1024 < api_con_sz) {
  2689.     jam();
  2690.     end_ptr= api_con_ptr + 1024;
  2691.   } else {
  2692.     jam();
  2693.     end_ptr= api_con_sz;
  2694.   }
  2695.   if (time_out_param > 300) {
  2696.     jam();
  2697.     mask_value= 63;
  2698.   } else if (time_out_param < 30) {
  2699.     jam();
  2700.     mask_value= 7;
  2701.   } else {
  2702.     jam();
  2703.     mask_value= 31;
  2704.   }
  2705.   for ( ; api_con_ptr < end_ptr; api_con_ptr++) {
  2706.     Uint32 api_timer= getApiConTimer(api_con_ptr);
  2707.     jam();
  2708.     if (api_timer != 0) {
  2709.       time_out_value= time_out_param + (api_con_ptr & mask_value);
  2710.       time_passed= tc_timer - api_timer;
  2711.       if (time_passed > time_out_value) {
  2712.         jam();
  2713.         timeOutFoundLab(signal, api_con_ptr);
  2714.         return;
  2715.       }
  2716.     }
  2717.   }
  2718.   if (api_con_ptr == api_con_sz) {
  2719.     jam();
  2720.     /*------------------------------------------------------------------*/
  2721.     /*                                                                  */
  2722.     /*       WE HAVE NOW CHECKED ALL TRANSACTIONS FOR TIME-OUT AND ALSO */
  2723.     /*       STARTED TIME-OUT HANDLING OF THOSE WE FOUND. WE ARE NOW    */
  2724.     /*       READY AND CAN WAIT FOR THE NEXT TIME-OUT CHECK.            */
  2725.     /*------------------------------------------------------------------*/
  2726.     ctimeOutCheckActive = TOCS_FALSE;
  2727.   } else {
  2728.     jam();
  2729.     sendContinueTimeOutControl(signal, api_con_ptr);
  2730.   }
  2731.   return;
  2732. }//Dbtc::timeOutLoopStartLab()
  2733. void Dbtc::timeOutFoundLab(Signal* signal, Uint32 TapiConPtr) 
  2734. {
  2735.   sendContinueTimeOutControl(signal, TapiConPtr + 1);
  2736.   
  2737.   apiConnectptr.i = TapiConPtr;
  2738.   ptrCheckGuard(apiConnectptr, capiConnectFilesize, apiConnectRecord);
  2739.   /*------------------------------------------------------------------*/
  2740.   /*                                                                  */
  2741.   /*       THIS TRANSACTION HAVE EXPERIENCED A TIME-OUT AND WE NEED TO*/
  2742.   /*       FIND OUT WHAT WE NEED TO DO BASED ON THE STATE INFORMATION.*/
  2743.   /*------------------------------------------------------------------*/
  2744.   DEBUG("[ H'" << hex << apiConnectptr.p->transid[0] 
  2745. << " H'" << apiConnectptr.p->transid[1] << "] " << dec 
  2746. << "Time-out in state = " << apiConnectptr.p->apiConnectstate
  2747. << " apiConnectptr.i = " << apiConnectptr.i 
  2748. << " - exec: " << apiConnectptr.p->m_exec_flag
  2749. << " - place: " << c_apiConTimer_line[apiConnectptr.i]);
  2750.   switch (apiConnectptr.p->apiConnectstate) {
  2751.   case CS_STARTED:
  2752.     ndbrequire(c_apiConTimer_line[apiConnectptr.i] != 3615);
  2753.     if(apiConnectptr.p->lqhkeyreqrec == apiConnectptr.p->lqhkeyconfrec){
  2754.       jam();
  2755.       /*
  2756.       We are waiting for application to continue the transaction. In this
  2757.       particular state we will use the application timeout parameter rather
  2758.       than the shorter Deadlock detection timeout.
  2759.       */
  2760.       if (c_appl_timeout_value == 0 ||
  2761.           (ctcTimer - getApiConTimer(apiConnectptr.i)) <= c_appl_timeout_value) {
  2762.         jam();
  2763.         return;
  2764.       }//if
  2765.     }
  2766.     apiConnectptr.p->returnsignal = RS_TCROLLBACKREP;      
  2767.     apiConnectptr.p->returncode = ZTIME_OUT_ERROR;
  2768.     abort010Lab(signal);
  2769.     return;
  2770.   case CS_RECEIVING:
  2771.   case CS_REC_COMMITTING:
  2772.   case CS_START_COMMITTING:
  2773.     jam();
  2774.     /*------------------------------------------------------------------*/
  2775.     /*       WE ARE STILL IN THE PREPARE PHASE AND THE TRANSACTION HAS  */
  2776.     /*       NOT YET REACHED ITS COMMIT POINT. THUS IT IS NOW OK TO     */
  2777.     /*       START ABORTING THE TRANSACTION. ALSO START CHECKING THE    */
  2778.     /*       REMAINING TRANSACTIONS.                                    */
  2779.     /*------------------------------------------------------------------*/
  2780.     terrorCode = ZTIME_OUT_ERROR;
  2781.     abortErrorLab(signal);
  2782.     return;
  2783.   case CS_COMMITTING:
  2784.     jam();
  2785.     /*------------------------------------------------------------------*/
  2786.     // We are simply waiting for a signal in the job buffer. Only extreme
  2787.     // conditions should get us here. We ignore it.
  2788.     /*------------------------------------------------------------------*/
  2789.   case CS_COMPLETING:
  2790.     jam();
  2791.     /*------------------------------------------------------------------*/
  2792.     // We are simply waiting for a signal in the job buffer. Only extreme
  2793.     // conditions should get us here. We ignore it.
  2794.     /*------------------------------------------------------------------*/
  2795.   case CS_PREPARE_TO_COMMIT:
  2796.     jam();
  2797.     /*------------------------------------------------------------------*/
  2798.     /*       WE ARE WAITING FOR DIH TO COMMIT THE TRANSACTION. WE SIMPLY*/
  2799.     /*       KEEP WAITING SINCE THERE IS NO BETTER IDEA ON WHAT TO DO.  */
  2800.     /*       IF IT IS BLOCKED THEN NO TRANSACTION WILL PASS THIS GATE.  */
  2801.     // To ensure against strange bugs we crash the system if we have passed
  2802.     // time-out period by a factor of 10 and it is also at least 5 seconds.
  2803.     /*------------------------------------------------------------------*/
  2804.     if (((ctcTimer - getApiConTimer(apiConnectptr.i)) > (10 * ctimeOutValue)) &&
  2805.         ((ctcTimer - getApiConTimer(apiConnectptr.i)) > 500)) {
  2806.         jam();
  2807.         systemErrorLab(signal);
  2808.     }//if
  2809.     break;
  2810.   case CS_COMMIT_SENT:
  2811.     jam();
  2812.     /*------------------------------------------------------------------*/
  2813.     /*       WE HAVE SENT COMMIT TO A NUMBER OF NODES. WE ARE CURRENTLY */
  2814.     /*       WAITING FOR THEIR REPLY. WITH NODE RECOVERY SUPPORTED WE   */
  2815.     /*       WILL CHECK FOR CRASHED NODES AND RESEND THE COMMIT SIGNAL  */
  2816.     /*       TO THOSE NODES THAT HAVE MISSED THE COMMIT SIGNAL DUE TO   */
  2817.     /*       A NODE FAILURE.                                            */
  2818.     /*------------------------------------------------------------------*/
  2819.     tabortInd = ZCOMMIT_SETUP;
  2820.     setupFailData(signal);
  2821.     toCommitHandlingLab(signal);
  2822.     return;
  2823.   case CS_COMPLETE_SENT:
  2824.     jam();
  2825.     /*--------------------------------------------------------------------*/
  2826.     /*       WE HAVE SENT COMPLETE TO A NUMBER OF NODES. WE ARE CURRENTLY */
  2827.     /*       WAITING FOR THEIR REPLY. WITH NODE RECOVERY SUPPORTED WE     */
  2828.     /*       WILL CHECK FOR CRASHED NODES AND RESEND THE COMPLETE SIGNAL  */
  2829.     /*       TO THOSE NODES THAT HAVE MISSED THE COMPLETE SIGNAL DUE TO   */
  2830.     /*       A NODE FAILURE.                                              */
  2831.     /*--------------------------------------------------------------------*/
  2832.     tabortInd = ZCOMMIT_SETUP;
  2833.     setupFailData(signal);
  2834.     toCompleteHandlingLab(signal);
  2835.     return;
  2836.   case CS_ABORTING:
  2837.     jam();
  2838.     /*------------------------------------------------------------------*/
  2839.     /*       TIME-OUT DURING ABORT. WE NEED TO SEND ABORTED FOR ALL     */
  2840.     /*       NODES THAT HAVE FAILED BEFORE SENDING ABORTED.             */
  2841.     /*------------------------------------------------------------------*/
  2842.     tcConnectptr.i = apiConnectptr.p->firstTcConnect;
  2843.     sendAbortedAfterTimeout(signal, 0);
  2844.     break;
  2845.   case CS_START_SCAN:{
  2846.     jam();
  2847.     ScanRecordPtr scanPtr;
  2848.     scanPtr.i = apiConnectptr.p->apiScanRec;
  2849.     ptrCheckGuard(scanPtr, cscanrecFileSize, scanRecord);
  2850.     scanError(signal, scanPtr, ZSCANTIME_OUT_ERROR);
  2851.     break;
  2852.   }
  2853.   case CS_WAIT_ABORT_CONF:
  2854.     jam();
  2855.     tcConnectptr.i = apiConnectptr.p->currentTcConnect;
  2856.     ptrCheckGuard(tcConnectptr, ctcConnectFilesize, tcConnectRecord);
  2857.     arrGuard(apiConnectptr.p->currentReplicaNo, 4);
  2858.     hostptr.i = tcConnectptr.p->tcNodedata[apiConnectptr.p->currentReplicaNo];
  2859.     ptrCheckGuard(hostptr, chostFilesize, hostRecord);
  2860.     if (hostptr.p->hostStatus == HS_ALIVE) {
  2861.       /*------------------------------------------------------------------*/
  2862.       // Time-out waiting for ABORTCONF. We will resend the ABORTREQ just in
  2863.       // case.
  2864.       /*------------------------------------------------------------------*/
  2865.       warningReport(signal, 20);
  2866.       apiConnectptr.p->timeOutCounter++;
  2867.       if (apiConnectptr.p->timeOutCounter > 3) {
  2868. /*------------------------------------------------------------------*/
  2869. // 100 time-outs are not acceptable. We will shoot down the node
  2870. // not responding.
  2871. /*------------------------------------------------------------------*/
  2872.         reportNodeFailed(signal, hostptr.i);
  2873.       }//if
  2874.       apiConnectptr.p->currentReplicaNo++;
  2875.     }//if
  2876.     tcurrentReplicaNo = (Uint8)Z8NIL;
  2877.     toAbortHandlingLab(signal);
  2878.     return;
  2879.   case CS_WAIT_COMMIT_CONF:
  2880.     jam();
  2881.     tcConnectptr.i = apiConnectptr.p->currentTcConnect;
  2882.     ptrCheckGuard(tcConnectptr, ctcConnectFilesize, tcConnectRecord);
  2883.     arrGuard(apiConnectptr.p->currentReplicaNo, 4);
  2884.     hostptr.i = tcConnectptr.p->tcNodedata[apiConnectptr.p->currentReplicaNo];
  2885.     ptrCheckGuard(hostptr, chostFilesize, hostRecord);
  2886.     if (hostptr.p->hostStatus == HS_ALIVE) {
  2887.       /*------------------------------------------------------------------*/
  2888.       // Time-out waiting for COMMITCONF. We will resend the COMMITREQ just in
  2889.       // case.
  2890.       /*------------------------------------------------------------------*/
  2891.       warningReport(signal, 21);
  2892.       apiConnectptr.p->timeOutCounter++;
  2893.       if (apiConnectptr.p->timeOutCounter > 3) {
  2894. /*------------------------------------------------------------------*/
  2895. // 100 time-outs are not acceptable. We will shoot down the node
  2896. // not responding.
  2897. /*------------------------------------------------------------------*/
  2898.         reportNodeFailed(signal, hostptr.i);
  2899.       }//if
  2900.       apiConnectptr.p->currentReplicaNo++;
  2901.     }//if
  2902.     tcurrentReplicaNo = (Uint8)Z8NIL;
  2903.     toCommitHandlingLab(signal);
  2904.     return;
  2905.   case CS_WAIT_COMPLETE_CONF:
  2906.     jam();
  2907.     tcConnectptr.i = apiConnectptr.p->currentTcConnect;
  2908.     ptrCheckGuard(tcConnectptr, ctcConnectFilesize, tcConnectRecord);
  2909.     arrGuard(apiConnectptr.p->currentReplicaNo, 4);
  2910.     hostptr.i = tcConnectptr.p->tcNodedata[apiConnectptr.p->currentReplicaNo];
  2911.     ptrCheckGuard(hostptr, chostFilesize, hostRecord);
  2912.     if (hostptr.p->hostStatus == HS_ALIVE) {
  2913.       /*------------------------------------------------------------------*/
  2914.       // Time-out waiting for COMPLETECONF. We will resend the COMPLETEREQ
  2915.       // just in case.
  2916.       /*------------------------------------------------------------------*/
  2917.       warningReport(signal, 22);
  2918.       apiConnectptr.p->timeOutCounter++;
  2919.       if (apiConnectptr.p->timeOutCounter > 100) {
  2920. /*------------------------------------------------------------------*/
  2921. // 100 time-outs are not acceptable. We will shoot down the node
  2922. // not responding.
  2923. /*------------------------------------------------------------------*/
  2924.         reportNodeFailed(signal, hostptr.i);
  2925.       }//if
  2926.       apiConnectptr.p->currentReplicaNo++;
  2927.     }//if
  2928.     tcurrentReplicaNo = (Uint8)Z8NIL;
  2929.     toCompleteHandlingLab(signal);
  2930.     return;
  2931.   case CS_FAIL_PREPARED:
  2932.     jam();
  2933.   case CS_FAIL_COMMITTING:
  2934.     jam();
  2935.   case CS_FAIL_COMMITTED:
  2936.     jam();
  2937.   case CS_REC_PREPARING:
  2938.     jam();
  2939.   case CS_START_PREPARING:
  2940.     jam();
  2941.   case CS_PREPARED:
  2942.     jam();
  2943.   case CS_RESTART:
  2944.     jam();
  2945.   case CS_FAIL_ABORTED:
  2946.     jam();
  2947.   case CS_DISCONNECTED:
  2948.     jam();
  2949.   default:
  2950.     jam();
  2951.     /*------------------------------------------------------------------*/
  2952.     /*       AN IMPOSSIBLE STATE IS SET. CRASH THE SYSTEM.              */
  2953.     /*------------------------------------------------------------------*/
  2954.     DEBUG("State = " << apiConnectptr.p->apiConnectstate);
  2955.     systemErrorLab(signal);
  2956.     return;
  2957.   }//switch
  2958.   return;
  2959. }//Dbtc::timeOutFoundLab()
  2960. void Dbtc::sendAbortedAfterTimeout(Signal* signal, int Tcheck)
  2961. {
  2962.   ApiConnectRecord * transP = apiConnectptr.p;
  2963.   if(transP->abortState == AS_IDLE){
  2964.     jam();
  2965.     warningEvent("TC: %d: %d state=%d abort==IDLE place: %d fop=%d t: %d", 
  2966.  __LINE__,
  2967.  apiConnectptr.i, 
  2968.  transP->apiConnectstate,
  2969.  c_apiConTimer_line[apiConnectptr.i],
  2970.  transP->firstTcConnect,
  2971.  c_apiConTimer[apiConnectptr.i]
  2972.  );
  2973.     ndbout_c("TC: %d: %d state=%d abort==IDLE place: %d fop=%d t: %d", 
  2974.      __LINE__,
  2975.      apiConnectptr.i, 
  2976.      transP->apiConnectstate,
  2977.      c_apiConTimer_line[apiConnectptr.i],
  2978.      transP->firstTcConnect,
  2979.      c_apiConTimer[apiConnectptr.i]
  2980.      );
  2981.     ndbrequire(false);
  2982.     setApiConTimer(apiConnectptr.i, 0, __LINE__);
  2983.     return;
  2984.   }
  2985.   
  2986.   OperationState tmp[16];
  2987.   
  2988.   Uint32 TloopCount = 0;
  2989.   do {
  2990.     jam();
  2991.     if (tcConnectptr.i == RNIL) {
  2992.       jam();
  2993.       if (Tcheck == 0) {
  2994.         jam();
  2995. /*------------------------------------------------------------------
  2996.  * All nodes had already reported ABORTED for all tcConnect records.
  2997.  * Crash since it is an error situation that we then received a 
  2998.  * time-out.
  2999.  *------------------------------------------------------------------*/
  3000. char buf[96]; buf[0] = 0;
  3001. char buf2[96];
  3002. BaseString::snprintf(buf, sizeof(buf), "TC %d: %d ops:",
  3003.  __LINE__, apiConnectptr.i);
  3004. for(Uint32 i = 0; i<TloopCount; i++){
  3005.   BaseString::snprintf(buf2, sizeof(buf2), "%s %d", buf, tmp[i]);
  3006.   BaseString::snprintf(buf, sizeof(buf), buf2);
  3007. }
  3008. warningEvent(buf);
  3009. ndbout_c(buf);
  3010. ndbrequire(false);
  3011.       }
  3012.       releaseAbortResources(signal);
  3013.       return;
  3014.     }//if
  3015.     TloopCount++;
  3016.     if (TloopCount >= 1024) {
  3017.       jam();
  3018.       /*------------------------------------------------------------------*/
  3019.       // Insert a real-time break for large transactions to avoid blowing
  3020.       // away the job buffer.
  3021.       /*------------------------------------------------------------------*/
  3022.       setApiConTimer(apiConnectptr.i, ctcTimer, __LINE__);
  3023.       apiConnectptr.p->counter++;
  3024.       signal->theData[0] = TcContinueB::ZABORT_TIMEOUT_BREAK;
  3025.       signal->theData[1] = tcConnectptr.i;
  3026.       signal->theData[2] = apiConnectptr.i;      
  3027.       sendSignal(cownref, GSN_CONTINUEB, signal, 3, JBB);
  3028.       return;
  3029.     }//if
  3030.     ptrCheckGuard(tcConnectptr, ctcConnectFilesize, tcConnectRecord);
  3031.     if(TloopCount < 16){
  3032.       jam();
  3033.       tmp[TloopCount-1] = tcConnectptr.p->tcConnectstate;
  3034.     }
  3035.     if (tcConnectptr.p->tcConnectstate == OS_ABORT_SENT) {
  3036.       jam();
  3037.       /*------------------------------------------------------------------*/
  3038.       // We have sent an ABORT signal to this node but not yet received any
  3039.       // reply. We have to send an ABORTED signal on our own in some cases.
  3040.       // If the node is declared as up and running and still do not respond
  3041.       // in time to the ABORT signal we will declare it as dead.
  3042.       /*------------------------------------------------------------------*/
  3043.       UintR Ti = 0;
  3044.       arrGuard(tcConnectptr.p->noOfNodes, 4);
  3045.       for (Ti = 0; Ti < tcConnectptr.p->noOfNodes; Ti++) {
  3046.         jam();
  3047.         if (tcConnectptr.p->tcNodedata[Ti] != 0) {
  3048.           TloopCount += 31;
  3049.           Tcheck = 1;
  3050.           hostptr.i = tcConnectptr.p->tcNodedata[Ti];
  3051.           ptrCheckGuard(hostptr, chostFilesize, hostRecord);
  3052.           if (hostptr.p->hostStatus == HS_ALIVE) {
  3053.             jam();
  3054.     /*---------------------------------------------------------------
  3055.      * A backup replica has not sent ABORTED. 
  3056.      * Could be that a node before him has crashed. 
  3057.      * Send an ABORT signal specifically to this node.
  3058.      * We will not send to any more nodes after this 
  3059.      * to avoid race problems.
  3060.      * To also ensure that we use this message also as a heartbeat 
  3061.      * we will move this node to the primary replica seat. 
  3062.      * The primary replica and any failed node after it will 
  3063.      * be removed from the node list. Update also number of nodes. 
  3064.      * Finally break the loop to ensure we don't mess
  3065.      * things up by executing another loop. 
  3066.      * We also update the timer to ensure we don't get time-out 
  3067.      * too early.
  3068.      *--------------------------------------------------------------*/
  3069.             BlockReference TBRef = calcLqhBlockRef(hostptr.i);
  3070.             signal->theData[0] = tcConnectptr.i;
  3071.             signal->theData[1] = cownref;
  3072.             signal->theData[2] = apiConnectptr.p->transid[0];
  3073.             signal->theData[3] = apiConnectptr.p->transid[1];
  3074.             sendSignal(TBRef, GSN_ABORT, signal, 4, JBB);
  3075.             setApiConTimer(apiConnectptr.i, ctcTimer, __LINE__);
  3076.             break;
  3077.           } else {
  3078.             jam();
  3079.     /*--------------------------------------------------------------
  3080.      * The node we are waiting for is dead. We will send ABORTED to