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

MySQL数据库

开发平台:

Visual C++

  1. /* Copyright (C) 2003 MySQL AB
  2.    This program is free software; you can redistribute it and/or modify
  3.    it under the terms of the GNU General Public License as published by
  4.    the Free Software Foundation; either version 2 of the License, or
  5.    (at your option) any later version.
  6.    This program is distributed in the hope that it will be useful,
  7.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  8.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  9.    GNU General Public License for more details.
  10.    You should have received a copy of the GNU General Public License
  11.    along with this program; if not, write to the Free Software
  12.    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
  13. #define DBTC_C
  14. #include "Dbtc.hpp"
  15. #include "md5_hash.hpp"
  16. #include <RefConvert.hpp>
  17. #include <ndb_limits.h>
  18. #include <signaldata/EventReport.hpp>
  19. #include <signaldata/TcKeyReq.hpp>
  20. #include <signaldata/TcKeyConf.hpp>
  21. #include <signaldata/TcKeyRef.hpp>
  22. #include <signaldata/KeyInfo.hpp>
  23. #include <signaldata/AttrInfo.hpp>
  24. #include <signaldata/TransIdAI.hpp>
  25. #include <signaldata/TcRollbackRep.hpp>
  26. #include <signaldata/NodeFailRep.hpp>
  27. #include <signaldata/ReadNodesConf.hpp>
  28. #include <signaldata/NFCompleteRep.hpp>
  29. #include <signaldata/LqhKey.hpp>
  30. #include <signaldata/TcCommit.hpp>
  31. #include <signaldata/TcContinueB.hpp>
  32. #include <signaldata/TcKeyFailConf.hpp>
  33. #include <signaldata/AbortAll.hpp>
  34. #include <signaldata/ScanFrag.hpp>
  35. #include <signaldata/ScanTab.hpp>
  36. #include <signaldata/PrepDropTab.hpp>
  37. #include <signaldata/DropTab.hpp>
  38. #include <signaldata/AlterTab.hpp>
  39. #include <signaldata/CreateTrig.hpp>
  40. #include <signaldata/DropTrig.hpp>
  41. #include <signaldata/FireTrigOrd.hpp>
  42. #include <signaldata/TrigAttrInfo.hpp>
  43. #include <signaldata/CreateIndx.hpp>
  44. #include <signaldata/DropIndx.hpp>
  45. #include <signaldata/AlterIndx.hpp>
  46. #include <signaldata/ScanTab.hpp>
  47. #include <signaldata/SystemError.hpp>
  48. #include <signaldata/DumpStateOrd.hpp>
  49. #include <signaldata/DisconnectRep.hpp>
  50. #include <signaldata/TcHbRep.hpp>
  51. #include <signaldata/PrepDropTab.hpp>
  52. #include <signaldata/DropTab.hpp>
  53. #include <signaldata/TcIndx.hpp>
  54. #include <signaldata/IndxKeyInfo.hpp>
  55. #include <signaldata/IndxAttrInfo.hpp>
  56. #include <signaldata/PackedSignal.hpp>
  57. #include <AttributeHeader.hpp>
  58. #include <signaldata/DictTabInfo.hpp>
  59. #include <NdbOut.hpp>
  60. #include <DebuggerNames.hpp>
  61. // Use DEBUG to print messages that should be
  62. // seen only when we debug the product
  63. #ifdef VM_TRACE
  64. #define DEBUG(x) ndbout << "DBTC: "<< x << endl;
  65. #else
  66. #define DEBUG(x)
  67. #endif
  68.   
  69. #define INTERNAL_TRIGGER_TCKEYREQ_JBA 0
  70. #ifdef VM_TRACE
  71. NdbOut &
  72. operator<<(NdbOut& out, Dbtc::ConnectionState state){
  73.   switch(state){
  74.   case Dbtc::CS_CONNECTED: out << "CS_CONNECTED"; break;
  75.   case Dbtc::CS_DISCONNECTED: out << "CS_DISCONNECTED"; break;
  76.   case Dbtc::CS_STARTED: out << "CS_STARTED"; break;
  77.   case Dbtc::CS_RECEIVING: out << "CS_RECEIVING"; break;
  78.   case Dbtc::CS_PREPARED: out << "CS_PREPARED"; break;
  79.   case Dbtc::CS_START_PREPARING: out << "CS_START_PREPARING"; break;
  80.   case Dbtc::CS_REC_PREPARING: out << "CS_REC_PREPARING"; break;
  81.   case Dbtc::CS_RESTART: out << "CS_RESTART"; break;
  82.   case Dbtc::CS_ABORTING: out << "CS_ABORTING"; break;
  83.   case Dbtc::CS_COMPLETING: out << "CS_COMPLETING"; break;
  84.   case Dbtc::CS_COMPLETE_SENT: out << "CS_COMPLETE_SENT"; break;
  85.   case Dbtc::CS_PREPARE_TO_COMMIT: out << "CS_PREPARE_TO_COMMIT"; break;
  86.   case Dbtc::CS_COMMIT_SENT: out << "CS_COMMIT_SENT"; break;
  87.   case Dbtc::CS_START_COMMITTING: out << "CS_START_COMMITTING"; break;
  88.   case Dbtc::CS_COMMITTING: out << "CS_COMMITTING"; break;
  89.   case Dbtc::CS_REC_COMMITTING: out << "CS_REC_COMMITTING"; break;
  90.   case Dbtc::CS_WAIT_ABORT_CONF: out << "CS_WAIT_ABORT_CONF"; break;
  91.   case Dbtc::CS_WAIT_COMPLETE_CONF: out << "CS_WAIT_COMPLETE_CONF"; break;
  92.   case Dbtc::CS_WAIT_COMMIT_CONF: out << "CS_WAIT_COMMIT_CONF"; break;
  93.   case Dbtc::CS_FAIL_ABORTING: out << "CS_FAIL_ABORTING"; break;
  94.   case Dbtc::CS_FAIL_ABORTED: out << "CS_FAIL_ABORTED"; break;
  95.   case Dbtc::CS_FAIL_PREPARED: out << "CS_FAIL_PREPARED"; break;
  96.   case Dbtc::CS_FAIL_COMMITTING: out << "CS_FAIL_COMMITTING"; break;
  97.   case Dbtc::CS_FAIL_COMMITTED: out << "CS_FAIL_COMMITTED"; break;
  98.   case Dbtc::CS_FAIL_COMPLETED: out << "CS_FAIL_COMPLETED"; break;
  99.   case Dbtc::CS_START_SCAN: out << "CS_START_SCAN"; break;
  100.   default:
  101.     out << "Unknown: " << (int)state; break;
  102.   }
  103.   return out;
  104. }
  105. NdbOut &
  106. operator<<(NdbOut& out, Dbtc::OperationState state){
  107.   out << (int)state;
  108.   return out;
  109. }
  110. NdbOut &
  111. operator<<(NdbOut& out, Dbtc::AbortState state){
  112.   out << (int)state;
  113.   return out;
  114. }
  115. NdbOut &
  116. operator<<(NdbOut& out, Dbtc::ReturnSignal state){
  117.   out << (int)state;
  118.   return out;
  119. }
  120. NdbOut &
  121. operator<<(NdbOut& out, Dbtc::ScanRecord::ScanState state){
  122.   out << (int)state;
  123.   return out;
  124. }
  125. NdbOut &
  126. operator<<(NdbOut& out, Dbtc::ScanFragRec::ScanFragState state){
  127.   out << (int)state;
  128.   return out;
  129. }
  130. #endif
  131. void
  132. Dbtc::updateBuddyTimer(ApiConnectRecordPtr apiPtr)
  133. {
  134.   if (apiPtr.p->buddyPtr != RNIL) {
  135.     jam();
  136.     ApiConnectRecordPtr buddyApiPtr;
  137.     buddyApiPtr.i = apiPtr.p->buddyPtr;
  138.     ptrCheckGuard(buddyApiPtr, capiConnectFilesize, apiConnectRecord);
  139.     if (getApiConTimer(buddyApiPtr.i) != 0) {
  140.       if ((apiPtr.p->transid[0] == buddyApiPtr.p->transid[0]) &&
  141.           (apiPtr.p->transid[1] == buddyApiPtr.p->transid[1])) {
  142.         jam();
  143.         setApiConTimer(buddyApiPtr.i, ctcTimer, __LINE__);
  144.       } else {
  145.         jam();
  146.         // Not a buddy anymore since not the same transid
  147.         apiPtr.p->buddyPtr = RNIL;
  148.       }//if
  149.     }//if
  150.   }//if
  151. }
  152. void Dbtc::execCONTINUEB(Signal* signal) 
  153. {
  154.   UintR tcase;
  155.   jamEntry();
  156.   tcase = signal->theData[0];
  157.   UintR Tdata0 = signal->theData[1];
  158.   UintR Tdata1 = signal->theData[2];
  159.   UintR Tdata2 = signal->theData[3];
  160.   switch (tcase) {
  161.   case TcContinueB::ZRETURN_FROM_QUEUED_DELIVERY:
  162.     jam();
  163.     ndbrequire(false);
  164.     return;
  165.   case TcContinueB::ZCOMPLETE_TRANS_AT_TAKE_OVER:
  166.     jam();
  167.     tcNodeFailptr.i = Tdata0;
  168.     ptrCheckGuard(tcNodeFailptr, 1, tcFailRecord);
  169.     completeTransAtTakeOverLab(signal, Tdata1);
  170.     return;
  171.   case TcContinueB::ZCONTINUE_TIME_OUT_CONTROL:
  172.     jam();
  173.     timeOutLoopStartLab(signal, Tdata0);
  174.     return;
  175.   case TcContinueB::ZNODE_TAKE_OVER_COMPLETED:
  176.     jam();
  177.     tnodeid = Tdata0;
  178.     tcNodeFailptr.i = 0;
  179.     ptrAss(tcNodeFailptr, tcFailRecord);
  180.     nodeTakeOverCompletedLab(signal);
  181.     return;
  182.   case TcContinueB::ZINITIALISE_RECORDS:
  183.     jam();
  184.     initialiseRecordsLab(signal, Tdata0, Tdata2, signal->theData[4]);
  185.     return;
  186.   case TcContinueB::ZSEND_COMMIT_LOOP:
  187.     jam();
  188.     apiConnectptr.i = Tdata0;
  189.     ptrCheckGuard(apiConnectptr, capiConnectFilesize, apiConnectRecord);
  190.     tcConnectptr.i = Tdata1;
  191.     ptrCheckGuard(tcConnectptr, ctcConnectFilesize, tcConnectRecord);
  192.     commit020Lab(signal);
  193.     return;
  194.   case TcContinueB::ZSEND_COMPLETE_LOOP:
  195.     jam();
  196.     apiConnectptr.i = Tdata0;
  197.     ptrCheckGuard(apiConnectptr, capiConnectFilesize, apiConnectRecord);
  198.     tcConnectptr.i = Tdata1;
  199.     ptrCheckGuard(tcConnectptr, ctcConnectFilesize, tcConnectRecord);
  200.     complete010Lab(signal);
  201.     return;
  202.   case TcContinueB::ZHANDLE_FAILED_API_NODE:
  203.     jam();
  204.     handleFailedApiNode(signal, Tdata0, Tdata1);
  205.     return;
  206.   case TcContinueB::ZTRANS_EVENT_REP:
  207.     jam();
  208.     /* -------------------------------------------------------------------- */
  209.     // Report information about transaction activity once per second.
  210.     /* -------------------------------------------------------------------- */
  211.     if (c_counters.c_trans_status == TransCounters::Timer){
  212.       Uint32 len = c_counters.report(signal);
  213.       sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, len, JBB);
  214.       
  215.       c_counters.reset();
  216.       signal->theData[0] = TcContinueB::ZTRANS_EVENT_REP;
  217.       sendSignalWithDelay(cownref, GSN_CONTINUEB, signal, 5000, 1);
  218.     }
  219.     return;
  220.   case TcContinueB::ZCONTINUE_TIME_OUT_FRAG_CONTROL:
  221.     jam();
  222.     timeOutLoopStartFragLab(signal, Tdata0);
  223.     return;
  224.   case TcContinueB::ZABORT_BREAK:
  225.     jam();
  226.     tcConnectptr.i = Tdata0;
  227.     apiConnectptr.i = Tdata1;
  228.     ptrCheckGuard(apiConnectptr, capiConnectFilesize, apiConnectRecord);
  229.     apiConnectptr.p->counter--;
  230.     abort015Lab(signal);
  231.     return;
  232.   case TcContinueB::ZABORT_TIMEOUT_BREAK:
  233.     jam();
  234.     tcConnectptr.i = Tdata0;
  235.     apiConnectptr.i = Tdata1;
  236.     ptrCheckGuard(apiConnectptr, capiConnectFilesize, apiConnectRecord);
  237.     apiConnectptr.p->counter--;
  238.     sendAbortedAfterTimeout(signal, 1);
  239.     return;
  240.   case TcContinueB::ZHANDLE_FAILED_API_NODE_REMOVE_MARKERS:
  241.     jam();
  242.     removeMarkerForFailedAPI(signal, Tdata0, Tdata1);
  243.     return;
  244.   case TcContinueB::ZWAIT_ABORT_ALL:
  245.     jam();
  246.     checkAbortAllTimeout(signal, Tdata0);
  247.     return;
  248.   case TcContinueB::ZCHECK_SCAN_ACTIVE_FAILED_LQH:
  249.     jam();
  250.     checkScanActiveInFailedLqh(signal, Tdata0, Tdata1);
  251.     return;
  252.   case TcContinueB::CHECK_WAIT_DROP_TAB_FAILED_LQH:
  253.     jam();
  254.     checkWaitDropTabFailedLqh(signal, Tdata0, Tdata1);
  255.     return;
  256.   case TcContinueB::TRIGGER_PENDING:
  257.     jam();
  258.     ApiConnectRecordPtr transPtr;
  259.     transPtr.i = Tdata0;
  260.     ptrCheckGuard(transPtr, capiConnectFilesize, apiConnectRecord);
  261.     transPtr.p->triggerPending = false;
  262.     executeTriggers(signal, &transPtr);
  263.     return;
  264.   case TcContinueB::DelayTCKEYCONF:
  265.     jam();
  266.     apiConnectptr.i = Tdata0;
  267.     ptrCheckGuard(apiConnectptr, capiConnectFilesize, apiConnectRecord);
  268.     sendtckeyconf(signal, Tdata1);
  269.     return;
  270.   default:
  271.     ndbrequire(false);
  272.   }//switch
  273. }
  274. void Dbtc::execDIGETNODESREF(Signal* signal) 
  275. {
  276.   jamEntry();
  277.   terrorCode = signal->theData[1];
  278.   releaseAtErrorLab(signal);
  279. }
  280. void Dbtc::execINCL_NODEREQ(Signal* signal) 
  281. {
  282.   jamEntry();
  283.   tblockref = signal->theData[0];
  284.   hostptr.i = signal->theData[1];
  285.   ptrCheckGuard(hostptr, chostFilesize, hostRecord);
  286.   hostptr.p->hostStatus = HS_ALIVE;
  287.   hostptr.p->takeOverStatus = TOS_IDLE;
  288.   signal->theData[0] = cownref;
  289.   sendSignal(tblockref, GSN_INCL_NODECONF, signal, 1, JBB);
  290. }
  291. void Dbtc::execREAD_NODESREF(Signal* signal) 
  292. {
  293.   jamEntry();
  294.   ndbrequire(false);
  295. }
  296. void Dbtc::execTC_SCHVERREQ(Signal* signal) 
  297. {
  298.   jamEntry();
  299.   tabptr.i = signal->theData[0];
  300.   ptrCheckGuard(tabptr, ctabrecFilesize, tableRecord);
  301.   tabptr.p->currentSchemaVersion = signal->theData[1];
  302.   tabptr.p->storedTable = (bool)signal->theData[2];
  303.   BlockReference retRef = signal->theData[3];
  304.   tabptr.p->tableType = (Uint8)signal->theData[4];
  305.   BlockReference retPtr = signal->theData[5];
  306.   ndbrequire(tabptr.p->enabled == false);
  307.   tabptr.p->enabled = true;
  308.   tabptr.p->dropping = false;
  309.   
  310.   signal->theData[0] = tabptr.i;
  311.   signal->theData[1] = retPtr;
  312.   sendSignal(retRef, GSN_TC_SCHVERCONF, signal, 2, JBB);
  313. }//Dbtc::execTC_SCHVERREQ()
  314. void
  315. Dbtc::execPREP_DROP_TAB_REQ(Signal* signal)
  316. {
  317.   jamEntry();
  318.   
  319.   PrepDropTabReq* req = (PrepDropTabReq*)signal->getDataPtr();
  320.   
  321.   TableRecordPtr tabPtr;
  322.   tabPtr.i = req->tableId;
  323.   ptrCheckGuard(tabPtr, ctabrecFilesize, tableRecord);
  324.   
  325.   Uint32 senderRef = req->senderRef;
  326.   Uint32 senderData = req->senderData;
  327.   
  328.   if(!tabPtr.p->enabled){
  329.     jam();
  330.     PrepDropTabRef* ref = (PrepDropTabRef*)signal->getDataPtrSend();
  331.     ref->senderRef = reference();
  332.     ref->senderData = senderData;
  333.     ref->tableId = tabPtr.i;
  334.     ref->errorCode = PrepDropTabRef::NoSuchTable;
  335.     sendSignal(senderRef, GSN_PREP_DROP_TAB_REF, signal,
  336.        PrepDropTabRef::SignalLength, JBB);
  337.     return;
  338.   }
  339.   if(tabPtr.p->dropping){
  340.     jam();
  341.     PrepDropTabRef* ref = (PrepDropTabRef*)signal->getDataPtrSend();
  342.     ref->senderRef = reference();
  343.     ref->senderData = senderData;
  344.     ref->tableId = tabPtr.i;
  345.     ref->errorCode = PrepDropTabRef::DropInProgress;
  346.     sendSignal(senderRef, GSN_PREP_DROP_TAB_REF, signal,
  347.        PrepDropTabRef::SignalLength, JBB);
  348.     return;
  349.   }
  350.   
  351.   tabPtr.p->dropping = true;
  352.   tabPtr.p->dropTable.senderRef = senderRef;
  353.   tabPtr.p->dropTable.senderData = senderData;
  354.   {
  355.     WaitDropTabReq * req = (WaitDropTabReq*)signal->getDataPtrSend();
  356.     req->tableId = tabPtr.i;
  357.     req->senderRef = reference();
  358.     
  359.     HostRecordPtr hostPtr;
  360.     tabPtr.p->dropTable.waitDropTabCount.clearWaitingFor();
  361.     for (hostPtr.i = 1; hostPtr.i < MAX_NDB_NODES; hostPtr.i++) {
  362.       jam();
  363.       ptrAss(hostPtr, hostRecord);
  364.       if (hostPtr.p->hostStatus == HS_ALIVE) {
  365. jam();
  366. tabPtr.p->dropTable.waitDropTabCount.setWaitingFor(hostPtr.i);
  367. sendSignal(calcLqhBlockRef(hostPtr.i), GSN_WAIT_DROP_TAB_REQ,
  368.    signal, WaitDropTabReq::SignalLength, JBB);
  369.       }//for
  370.     }//if
  371.     
  372.     ndbrequire(tabPtr.p->dropTable.waitDropTabCount.done() != true);
  373.   }
  374. }
  375. void
  376. Dbtc::execWAIT_DROP_TAB_CONF(Signal* signal)
  377. {
  378.   jamEntry();
  379.   WaitDropTabConf * conf = (WaitDropTabConf*)signal->getDataPtr();
  380.   TableRecordPtr tabPtr;
  381.   tabPtr.i = conf->tableId;
  382.   ptrCheckGuard(tabPtr, ctabrecFilesize, tableRecord);
  383.   
  384.   ndbrequire(tabPtr.p->dropping == true);
  385.   Uint32 nodeId = refToNode(conf->senderRef);
  386.   tabPtr.p->dropTable.waitDropTabCount.clearWaitingFor(nodeId);
  387.   
  388.   if(!tabPtr.p->dropTable.waitDropTabCount.done()){
  389.     jam();
  390.     return;
  391.   }
  392.   
  393.   {
  394.     PrepDropTabConf* conf = (PrepDropTabConf*)signal->getDataPtrSend();
  395.     conf->tableId = tabPtr.i;
  396.     conf->senderRef = reference();
  397.     conf->senderData = tabPtr.p->dropTable.senderData;
  398.     sendSignal(tabPtr.p->dropTable.senderRef, GSN_PREP_DROP_TAB_CONF, signal,
  399.        PrepDropTabConf::SignalLength, JBB);
  400.     tabPtr.p->dropTable.senderRef = 0;
  401.   }
  402. }
  403. void
  404. Dbtc::execWAIT_DROP_TAB_REF(Signal* signal)
  405. {
  406.   jamEntry();
  407.   WaitDropTabRef * ref = (WaitDropTabRef*)signal->getDataPtr();
  408.   TableRecordPtr tabPtr;
  409.   tabPtr.i = ref->tableId;
  410.   ptrCheckGuard(tabPtr, ctabrecFilesize, tableRecord);
  411.   
  412.   ndbrequire(tabPtr.p->dropping == true);
  413.   Uint32 nodeId = refToNode(ref->senderRef);
  414.   tabPtr.p->dropTable.waitDropTabCount.clearWaitingFor(nodeId);
  415.   
  416.   ndbrequire(ref->errorCode == WaitDropTabRef::NoSuchTable ||
  417.      ref->errorCode == WaitDropTabRef::NF_FakeErrorREF);
  418.   
  419.   if(!tabPtr.p->dropTable.waitDropTabCount.done()){
  420.     jam();
  421.     return;
  422.   }
  423.   
  424.   {
  425.     PrepDropTabConf* conf = (PrepDropTabConf*)signal->getDataPtrSend();
  426.     conf->tableId = tabPtr.i;
  427.     conf->senderRef = reference();
  428.     conf->senderData = tabPtr.p->dropTable.senderData;
  429.     sendSignal(tabPtr.p->dropTable.senderRef, GSN_PREP_DROP_TAB_CONF, signal,
  430.        PrepDropTabConf::SignalLength, JBB);
  431.     tabPtr.p->dropTable.senderRef = 0;
  432.   }
  433. }  
  434. void
  435. Dbtc::checkWaitDropTabFailedLqh(Signal* signal, Uint32 nodeId, Uint32 tableId)
  436. {
  437.   
  438.   TableRecordPtr tabPtr;
  439.   tabPtr.i = tableId;
  440.   WaitDropTabConf * conf = (WaitDropTabConf*)signal->getDataPtr();
  441.   conf->tableId = tableId;
  442.   const Uint32 RT_BREAK = 16;
  443.   for(Uint32 i = 0; i<RT_BREAK && tabPtr.i < ctabrecFilesize; i++, tabPtr.i++){
  444.     jam();
  445.     ptrAss(tabPtr, tableRecord);
  446.     if(tabPtr.p->enabled && tabPtr.p->dropping){
  447.       if(tabPtr.p->dropTable.waitDropTabCount.isWaitingFor(nodeId)){
  448.         jam();
  449. conf->senderRef = calcLqhBlockRef(nodeId);
  450. execWAIT_DROP_TAB_CONF(signal);
  451. tabPtr.i++;
  452. break;
  453.       }
  454.     }
  455.   }
  456.   
  457.   if(tabPtr.i == ctabrecFilesize){
  458.     /**
  459.      * Finished
  460.      */
  461.     jam();
  462.     return;
  463.   }
  464.   
  465.   signal->theData[0] = TcContinueB::CHECK_WAIT_DROP_TAB_FAILED_LQH;
  466.   signal->theData[1] = nodeId;
  467.   signal->theData[2] = tabPtr.i;
  468.   sendSignal(reference(), GSN_CONTINUEB, signal, 3, JBB);
  469. }
  470. void
  471. Dbtc::execDROP_TAB_REQ(Signal* signal)
  472. {
  473.   jamEntry();
  474.   DropTabReq* req = (DropTabReq*)signal->getDataPtr();
  475.   
  476.   TableRecordPtr tabPtr;
  477.   tabPtr.i = req->tableId;
  478.   ptrCheckGuard(tabPtr, ctabrecFilesize, tableRecord);
  479.   
  480.   Uint32 senderRef = req->senderRef;
  481.   Uint32 senderData = req->senderData;
  482.   DropTabReq::RequestType rt = (DropTabReq::RequestType)req->requestType;
  483.   
  484.   if(!tabPtr.p->enabled && rt == DropTabReq::OnlineDropTab){
  485.     jam();
  486.     DropTabRef* ref = (DropTabRef*)signal->getDataPtrSend();
  487.     ref->senderRef = reference();
  488.     ref->senderData = senderData;
  489.     ref->tableId = tabPtr.i;
  490.     ref->errorCode = DropTabRef::NoSuchTable;
  491.     sendSignal(senderRef, GSN_DROP_TAB_REF, signal,
  492.        DropTabRef::SignalLength, JBB);
  493.     return;
  494.   }
  495.   if(!tabPtr.p->dropping && rt == DropTabReq::OnlineDropTab){
  496.     jam();
  497.     DropTabRef* ref = (DropTabRef*)signal->getDataPtrSend();
  498.     ref->senderRef = reference();
  499.     ref->senderData = senderData;
  500.     ref->tableId = tabPtr.i;
  501.     ref->errorCode = DropTabRef::DropWoPrep;
  502.     sendSignal(senderRef, GSN_DROP_TAB_REF, signal,
  503.        DropTabRef::SignalLength, JBB);
  504.     return;
  505.   }
  506.   
  507.   tabPtr.p->enabled = false;
  508.   tabPtr.p->dropping = false;
  509.   
  510.   DropTabConf * conf = (DropTabConf*)signal->getDataPtrSend();
  511.   conf->tableId = tabPtr.i;
  512.   conf->senderRef = reference();
  513.   conf->senderData = senderData;
  514.   sendSignal(senderRef, GSN_DROP_TAB_CONF, signal,
  515.      PrepDropTabConf::SignalLength, JBB);
  516. }
  517. void Dbtc::execALTER_TAB_REQ(Signal * signal)
  518. {
  519.   AlterTabReq* const req = (AlterTabReq*)signal->getDataPtr();
  520.   const Uint32 senderRef = req->senderRef;
  521.   const Uint32 senderData = req->senderData;
  522.   const Uint32 changeMask = req->changeMask;
  523.   const Uint32 tableId = req->tableId;
  524.   const Uint32 tableVersion = req->tableVersion;
  525.   const Uint32 gci = req->gci;
  526.   AlterTabReq::RequestType requestType = 
  527.     (AlterTabReq::RequestType) req->requestType;
  528.   TableRecordPtr tabPtr;
  529.   tabPtr.i = req->tableId;
  530.   ptrCheckGuard(tabPtr, ctabrecFilesize, tableRecord);
  531.   tabPtr.p->currentSchemaVersion = tableVersion;
  532.   // Request handled successfully 
  533.   AlterTabConf * conf = (AlterTabConf*)signal->getDataPtrSend();
  534.   conf->senderRef = reference();
  535.   conf->senderData = senderData;
  536.   conf->changeMask = changeMask;
  537.   conf->tableId = tableId;
  538.   conf->tableVersion = tableVersion;
  539.   conf->gci = gci;
  540.   conf->requestType = requestType;
  541.   sendSignal(senderRef, GSN_ALTER_TAB_CONF, signal, 
  542.      AlterTabConf::SignalLength, JBB);
  543. }
  544. /* ***************************************************************************/
  545. /*                                START / RESTART                            */
  546. /* ***************************************************************************/
  547. void Dbtc::execREAD_CONFIG_REQ(Signal* signal) 
  548. {
  549.   const ReadConfigReq * req = (ReadConfigReq*)signal->getDataPtr();
  550.   Uint32 ref = req->senderRef;
  551.   Uint32 senderData = req->senderData;
  552.   ndbrequire(req->noOfParameters == 0);
  553.   
  554.   jamEntry();
  555.   
  556.   const ndb_mgm_configuration_iterator * p = 
  557.     theConfiguration.getOwnConfigIterator();
  558.   ndbrequire(p != 0);
  559.   
  560.   UintR apiConnect;
  561.   UintR tcConnect;
  562.   UintR tables;
  563.   UintR localScan;
  564.   UintR tcScan;
  565.   ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_TC_API_CONNECT, &apiConnect));
  566.   ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_TC_TC_CONNECT, &tcConnect));
  567.   ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_TC_TABLE, &tables));
  568.   ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_TC_LOCAL_SCAN, &localScan));
  569.   ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_TC_SCAN, &tcScan));
  570.   ccacheFilesize = (apiConnect/3) + 1;
  571.   capiConnectFilesize = apiConnect;
  572.   ctcConnectFilesize  = tcConnect;
  573.   ctabrecFilesize     = tables;
  574.   cscanrecFileSize = tcScan;
  575.   cscanFragrecFileSize = localScan;
  576.   initRecords();
  577.   initialiseRecordsLab(signal, 0, ref, senderData);
  578.   Uint32 val = 3000;
  579.   ndb_mgm_get_int_parameter(p, CFG_DB_TRANSACTION_DEADLOCK_TIMEOUT, &val);
  580.   set_timeout_value(val);
  581.   val = 3000;
  582.   ndb_mgm_get_int_parameter(p, CFG_DB_TRANSACTION_INACTIVE_TIMEOUT, &val);
  583.   set_appl_timeout_value(val);
  584.   val = 1;
  585.   //ndb_mgm_get_int_parameter(p, CFG_DB_PARALLEL_TRANSACTION_TAKEOVER, &val);
  586.   set_no_parallel_takeover(val);
  587.   ctimeOutCheckDelay = 50; // 500ms
  588. }//Dbtc::execSIZEALT_REP()
  589. void Dbtc::execSTTOR(Signal* signal) 
  590. {
  591.   Uint16 tphase;
  592.   jamEntry();
  593.                                                      /* START CASE */
  594.   tphase = signal->theData[1];
  595.   csignalKey = signal->theData[6];
  596.   switch (tphase) {
  597.   case ZSPH1:
  598.     jam();
  599.     startphase1x010Lab(signal);
  600.     return;
  601.   default:
  602.     jam();
  603.     sttorryLab(signal); /* START PHASE 255 */
  604.     return;
  605.   }//switch
  606. }//Dbtc::execSTTOR()
  607. void Dbtc::sttorryLab(Signal* signal) 
  608. {
  609.   signal->theData[0] = csignalKey;
  610.   signal->theData[1] = 3;    /* BLOCK CATEGORY */
  611.   signal->theData[2] = 2;    /* SIGNAL VERSION NUMBER */
  612.   signal->theData[3] = ZSPH1;
  613.   signal->theData[4] = 255;
  614.   sendSignal(NDBCNTR_REF, GSN_STTORRY, signal, 5, JBB);
  615. }//Dbtc::sttorryLab()
  616. /* ***************************************************************************/
  617. /*                          INTERNAL  START / RESTART                        */
  618. /*****************************************************************************/
  619. void Dbtc::execNDB_STTOR(Signal* signal) 
  620. {
  621.   Uint16 tndbstartphase;
  622.   Uint16 tstarttype;
  623.   jamEntry();
  624.   tusersblkref = signal->theData[0];
  625.   tnodeid = signal->theData[1];
  626.   tndbstartphase = signal->theData[2];   /* START PHASE      */
  627.   tstarttype = signal->theData[3];       /* START TYPE       */
  628.   switch (tndbstartphase) {
  629.   case ZINTSPH1:
  630.     jam();
  631.     intstartphase1x010Lab(signal);
  632.     return;
  633.   case ZINTSPH2:
  634.     jam();
  635.     intstartphase2x010Lab(signal);
  636.     return;
  637.   case ZINTSPH3:
  638.     jam();
  639.     intstartphase3x010Lab(signal);      /* SEIZE CONNECT RECORD IN EACH LQH*/
  640. // Start transaction event reporting.
  641.     c_counters.c_trans_status = TransCounters::Timer;
  642.     c_counters.reset();
  643.     signal->theData[0] = TcContinueB::ZTRANS_EVENT_REP;
  644.     sendSignalWithDelay(cownref, GSN_CONTINUEB, signal, 10, 1);
  645.     return;
  646.   case ZINTSPH6:
  647.     jam();
  648.     csystemStart = SSS_TRUE;
  649.     break;
  650.   default:
  651.     jam();
  652.     break;
  653.   }//switch
  654.   ndbsttorry010Lab(signal);
  655.   return;
  656. }//Dbtc::execNDB_STTOR()
  657. void Dbtc::ndbsttorry010Lab(Signal* signal) 
  658. {
  659.   signal->theData[0] = cownref;
  660.   sendSignal(cndbcntrblockref, GSN_NDB_STTORRY, signal, 1, JBB);
  661. }//Dbtc::ndbsttorry010Lab()
  662. void
  663. Dbtc::set_timeout_value(Uint32 timeOut)
  664. {
  665.   timeOut = timeOut / 10;
  666.   if (timeOut < 2) {
  667.     jam();
  668.     timeOut = 100;
  669.   }//if
  670.   ctimeOutValue = timeOut;
  671. }
  672. void
  673. Dbtc::set_appl_timeout_value(Uint32 timeOut)
  674. {
  675.   if (timeOut)
  676.   {
  677.     timeOut /= 10;
  678.     if (timeOut < ctimeOutValue) {
  679.       jam();
  680.       c_appl_timeout_value = ctimeOutValue;
  681.     }//if
  682.   }
  683.   c_appl_timeout_value = timeOut;
  684. }
  685. void
  686. Dbtc::set_no_parallel_takeover(Uint32 noParallelTakeOver)
  687. {
  688.   if (noParallelTakeOver == 0) {
  689.     jam();
  690.     noParallelTakeOver = 1;
  691.   } else if (noParallelTakeOver > MAX_NDB_NODES) {
  692.     jam();
  693.     noParallelTakeOver = MAX_NDB_NODES;
  694.   }//if
  695.   cnoParallelTakeOver = noParallelTakeOver;
  696. }
  697. /* ***************************************************************************/
  698. /*                        S T A R T P H A S E 1 X                            */
  699. /*                     INITIALISE BLOCKREF AND BLOCKNUMBERS                  */
  700. /* ***************************************************************************/
  701. void Dbtc::startphase1x010Lab(Signal* signal) 
  702. {
  703.   csystemStart = SSS_FALSE;
  704.   ctimeOutCheckCounter = 0;
  705.   ctimeOutCheckFragCounter = 0;
  706.   ctimeOutMissedHeartbeats = 0;
  707.   ctimeOutCheckHeartbeat = 0;
  708.   ctimeOutCheckLastHeartbeat = 0;
  709.   ctimeOutCheckActive = TOCS_FALSE;
  710.   ctimeOutCheckFragActive = TOCS_FALSE;
  711.   sttorryLab(signal);
  712. }//Dbtc::startphase1x010Lab()
  713. /*****************************************************************************/
  714. /*                        I N T S T A R T P H A S E 1 X                      */
  715. /*                         INITIALISE ALL RECORDS.                           */
  716. /*****************************************************************************/
  717. void Dbtc::intstartphase1x010Lab(Signal* signal) 
  718. {
  719.   cownNodeid = tnodeid;
  720.   cownref =          calcTcBlockRef(cownNodeid);
  721.   clqhblockref =     calcLqhBlockRef(cownNodeid);
  722.   cdihblockref =     calcDihBlockRef(cownNodeid);
  723.   cdictblockref =    calcDictBlockRef(cownNodeid);
  724.   cndbcntrblockref = calcNdbCntrBlockRef(cownNodeid);
  725.   cerrorBlockref   = calcNdbCntrBlockRef(cownNodeid);
  726.   coperationsize = 0;
  727.   cfailure_nr = 0;
  728.   ndbsttorry010Lab(signal);
  729. }//Dbtc::intstartphase1x010Lab()
  730. /*****************************************************************************/
  731. /*                         I N T S T A R T P H A S E 2 X                     */
  732. /*                          SET-UP LOCAL CONNECTIONS.                        */
  733. /*****************************************************************************/
  734. void Dbtc::intstartphase2x010Lab(Signal* signal) 
  735. {
  736.   tcConnectptr.i = cfirstfreeTcConnect;
  737.   intstartphase2x020Lab(signal);
  738. }//Dbtc::intstartphase2x010Lab()
  739. void Dbtc::intstartphase2x020Lab(Signal* signal) 
  740. {
  741.   if (tcConnectptr.i == RNIL) {
  742.     jam();
  743.     ndbsttorry010Lab(signal);
  744.     return;
  745.   }//if
  746.   ptrCheckGuard(tcConnectptr, ctcConnectFilesize, tcConnectRecord);
  747.   tcConnectptr.p->tcConnectstate = OS_CONNECTING_DICT;
  748. /* ****************** */
  749. /*     DISEIZEREQ   < */
  750. /* ****************** */
  751.   signal->theData[0] = tcConnectptr.i;
  752.   signal->theData[1] = cownref;
  753.   sendSignal(cdihblockref, GSN_DISEIZEREQ, signal, 2, JBB);
  754. }//Dbtc::intstartphase2x020Lab()
  755. void Dbtc::execDISEIZECONF(Signal* signal) 
  756. {
  757.   jamEntry();
  758.   tcConnectptr.i = signal->theData[0];
  759.   ptrCheckGuard(tcConnectptr, ctcConnectFilesize, tcConnectRecord);
  760.   tcConnectptr.p->dihConnectptr = signal->theData[1];
  761.   tcConnectptr.i = tcConnectptr.p->nextTcConnect;
  762.   intstartphase2x020Lab(signal);
  763. }//Dbtc::execDISEIZECONF()
  764. /*****************************************************************************/
  765. /*                         I N T S T A R T P H A S E 3 X                     */
  766. /*                        PREPARE DISTRIBUTED CONNECTIONS                    */
  767. /*****************************************************************************/
  768. void Dbtc::intstartphase3x010Lab(Signal* signal) 
  769. {
  770.   signal->theData[0] = cownref;
  771.   sendSignal(cndbcntrblockref, GSN_READ_NODESREQ, signal, 1, JBB);
  772. }//Dbtc::intstartphase3x010Lab()
  773. void Dbtc::execREAD_NODESCONF(Signal* signal) 
  774. {
  775.   UintR guard0;
  776.   jamEntry();
  777.   ReadNodesConf * const readNodes = (ReadNodesConf *)&signal->theData[0];
  778.   csystemnodes  = readNodes->noOfNodes;
  779.   cmasterNodeId = readNodes->masterNodeId;
  780.   con_lineNodes = 0;
  781.   arrGuard(csystemnodes, MAX_NDB_NODES);
  782.   guard0 = csystemnodes - 1;
  783.   arrGuard(guard0, MAX_NDB_NODES);       // Check not zero nodes
  784.   for (unsigned i = 1; i < MAX_NDB_NODES; i++) {
  785.     jam();
  786.     if (NodeBitmask::get(readNodes->allNodes, i)) {
  787.       hostptr.i = i;
  788.       ptrCheckGuard(hostptr, chostFilesize, hostRecord);
  789.       hostptr.p->takeOverStatus = TOS_IDLE;
  790.       
  791.       if (NodeBitmask::get(readNodes->inactiveNodes, i)) {
  792.         jam();
  793.         hostptr.p->hostStatus = HS_DEAD;
  794.       } else {
  795.         jam();
  796.         con_lineNodes++;
  797.         hostptr.p->hostStatus = HS_ALIVE;
  798.       }//if
  799.     }//if
  800.   }//for
  801.   ndbsttorry010Lab(signal);
  802. }//Dbtc::execREAD_NODESCONF()
  803. /*****************************************************************************/
  804. /*                     A P I _ F A I L R E Q                                 */
  805. // An API node has failed for some reason. We need to disconnect all API 
  806. // connections to the API node. This also includes 
  807. /*****************************************************************************/
  808. void Dbtc::execAPI_FAILREQ(Signal* signal)
  809. {
  810.   /***************************************************************************
  811.    * Set the block reference to return API_FAILCONF to. Set the number of api 
  812.    * connects currently closing to one to indicate that we are still in the 
  813.    * process of going through the api connect records. Thus checking for zero 
  814.    * can only be true after all api connect records have been checked.
  815.    **************************************************************************/
  816.   jamEntry();  
  817.   capiFailRef = signal->theData[1];
  818.   arrGuard(signal->theData[0], MAX_NODES);
  819.   capiConnectClosing[signal->theData[0]] = 1;
  820.   handleFailedApiNode(signal, signal->theData[0], (UintR)0);
  821. }
  822. void
  823. Dbtc::handleFailedApiNode(Signal* signal, 
  824.                           UintR TapiFailedNode, 
  825.                           UintR TapiConnectPtr)
  826. {
  827.   UintR TloopCount = 0;
  828.   arrGuard(TapiFailedNode, MAX_NODES);
  829.   apiConnectptr.i = TapiConnectPtr;
  830.   do {
  831.     ptrCheckGuard(apiConnectptr, capiConnectFilesize, apiConnectRecord);
  832.     const UintR TapiNode = refToNode(apiConnectptr.p->ndbapiBlockref);
  833.     if (TapiNode == TapiFailedNode) {
  834. #ifdef VM_TRACE
  835.       if (apiConnectptr.p->apiFailState != ZFALSE) {
  836.         ndbout << "Error in previous API fail handling discovered" << endl
  837.        << "  apiConnectptr.i = " << apiConnectptr.i << endl
  838.        << "  apiConnectstate = " << apiConnectptr.p->apiConnectstate 
  839.        << endl
  840.        << "  ndbapiBlockref = " << hex
  841.        << apiConnectptr.p->ndbapiBlockref << endl
  842.        << "  apiNode = " << refToNode(apiConnectptr.p->ndbapiBlockref) 
  843.        << endl;
  844. if (apiConnectptr.p->lastTcConnect != RNIL){   
  845.   jam();
  846.   tcConnectptr.i = apiConnectptr.p->lastTcConnect;
  847.   ptrCheckGuard(tcConnectptr, ctcConnectFilesize, tcConnectRecord);
  848.   ndbout << "  tcConnectptr.i = " << tcConnectptr.i << endl
  849.  << "  tcConnectstate = " << tcConnectptr.p->tcConnectstate 
  850.  << endl;
  851. }
  852.       }//if
  853. #endif
  854.       
  855.       apiConnectptr.p->returnsignal = RS_NO_RETURN;
  856.       /***********************************************************************/
  857.       // The connected node is the failed node.
  858.       /**********************************************************************/
  859.       switch(apiConnectptr.p->apiConnectstate) {
  860.       case CS_DISCONNECTED:
  861.         /*********************************************************************/
  862.         // These states do not need any special handling. 
  863.         // Simply continue with the next.
  864.         /*********************************************************************/
  865.         jam();
  866.         break;
  867.       case CS_ABORTING:
  868.         /*********************************************************************/
  869.         // This could actually mean that the API connection is already 
  870.         // ready to release if the abortState is IDLE.
  871.         /*********************************************************************/
  872.         if (apiConnectptr.p->abortState == AS_IDLE) {
  873.           jam();
  874.           releaseApiCon(signal, apiConnectptr.i);
  875.         } else {
  876.           jam();
  877.           capiConnectClosing[TapiFailedNode]++;
  878.           apiConnectptr.p->apiFailState = ZTRUE;
  879.         }//if
  880.         break;
  881.       case CS_WAIT_ABORT_CONF:
  882.       case CS_WAIT_COMMIT_CONF:
  883.       case CS_START_COMMITTING:
  884.       case CS_PREPARE_TO_COMMIT:
  885.       case CS_COMMITTING:
  886.       case CS_COMMIT_SENT:
  887.         /*********************************************************************/
  888.         // These states indicate that an abort process or commit process is 
  889.         // already ongoing. We will set a state in the api record indicating 
  890.         // that the API node has failed.
  891.         // Also we will increase the number of outstanding api records to 
  892.         // wait for before we can respond with API_FAILCONF.
  893.         /*********************************************************************/
  894.         jam();
  895.         capiConnectClosing[TapiFailedNode]++;
  896.         apiConnectptr.p->apiFailState = ZTRUE;
  897.         break;
  898.       case CS_START_SCAN:
  899.         /*********************************************************************/
  900.         // The api record was performing a scan operation. We need to check 
  901.         // on the scan state. Since completing a scan process might involve
  902.         // sending several signals we will increase the loop count by 64.
  903.         /*********************************************************************/
  904.         jam();
  905. apiConnectptr.p->apiFailState = ZTRUE;
  906. capiConnectClosing[TapiFailedNode]++;
  907. ScanRecordPtr scanPtr;
  908. scanPtr.i = apiConnectptr.p->apiScanRec;
  909. ptrCheckGuard(scanPtr, cscanrecFileSize, scanRecord);
  910. close_scan_req(signal, scanPtr, true);
  911.         TloopCount += 64;
  912.         break;
  913.       case CS_CONNECTED:
  914.         /*********************************************************************/
  915.         // The api record is connected to failed node. We need to release the 
  916.         // connection and set it in a disconnected state.
  917.         /*********************************************************************/
  918.         jam();
  919.         releaseApiCon(signal, apiConnectptr.i);
  920.         break;
  921.       case CS_REC_COMMITTING:
  922.       case CS_RECEIVING:
  923.       case CS_STARTED:
  924.         /*********************************************************************/
  925.         // The api record was in the process of performing a transaction but 
  926.         // had not yet sent all information. 
  927.         // We need to initiate an ABORT since the API will not provide any 
  928.         // more information. 
  929.         // Since the abort can send many signals we will insert a real-time
  930.         // break after checking this record.
  931.         /*********************************************************************/
  932.         jam();
  933.         apiConnectptr.p->apiFailState = ZTRUE;
  934.         capiConnectClosing[TapiFailedNode]++;
  935.         abort010Lab(signal);
  936.         TloopCount = 256;
  937.         break;
  938.       case CS_PREPARED:
  939.         jam();
  940.       case CS_REC_PREPARING:
  941.         jam();
  942.       case CS_START_PREPARING:
  943.         jam();
  944.         /*********************************************************************/
  945.         // Not implemented yet.
  946.         /*********************************************************************/
  947.         systemErrorLab(signal);
  948.         break;
  949.       case CS_RESTART:
  950.         jam();
  951.       case CS_COMPLETING:
  952.         jam();
  953.       case CS_COMPLETE_SENT:
  954.         jam();
  955.       case CS_WAIT_COMPLETE_CONF:
  956.         jam();
  957.       case CS_FAIL_ABORTING:
  958.         jam();
  959.       case CS_FAIL_ABORTED:
  960.         jam();
  961.       case CS_FAIL_PREPARED:
  962.         jam();
  963.       case CS_FAIL_COMMITTING:
  964.         jam();
  965.       case CS_FAIL_COMMITTED:
  966.         /*********************************************************************/
  967.         // These states are only valid on copy and fail API connections.
  968.         /*********************************************************************/
  969.       default:
  970.         jam();
  971.         systemErrorLab(signal);
  972.         break;
  973.       }//switch
  974.     } else {
  975.       jam();
  976.     }//if
  977.     apiConnectptr.i++;
  978.     if (apiConnectptr.i > ((capiConnectFilesize / 3) - 1)) {
  979.       jam();
  980.       /**
  981.        * Finished with scanning connection record
  982.        *
  983.        * Now scan markers
  984.        */
  985.       removeMarkerForFailedAPI(signal, TapiFailedNode, 0);
  986.       return;
  987.     }//if
  988.   } while (TloopCount++ < 256);
  989.   signal->theData[0] = TcContinueB::ZHANDLE_FAILED_API_NODE;
  990.   signal->theData[1] = TapiFailedNode;
  991.   signal->theData[2] = apiConnectptr.i;
  992.   sendSignal(cownref, GSN_CONTINUEB, signal, 3, JBB);
  993. }//Dbtc::handleFailedApiNode()
  994. void
  995. Dbtc::removeMarkerForFailedAPI(Signal* signal, 
  996.                                Uint32 nodeId, 
  997.                                Uint32 startBucket)
  998. {
  999.   TcFailRecordPtr node_fail_ptr;
  1000.   node_fail_ptr.i = 0;
  1001.   ptrAss(node_fail_ptr, tcFailRecord);
  1002.   if(node_fail_ptr.p->failStatus != FS_IDLE) {
  1003.     jam();
  1004.     DEBUG("Restarting removeMarkerForFailedAPI");
  1005.     /**
  1006.      * TC take-over in progress
  1007.      *   needs to restart as this
  1008.      *   creates new markers
  1009.      */
  1010.     signal->theData[0] = TcContinueB::ZHANDLE_FAILED_API_NODE_REMOVE_MARKERS;
  1011.     signal->theData[1] = nodeId;
  1012.     signal->theData[2] = 0;
  1013.     sendSignalWithDelay(cownref, GSN_CONTINUEB, signal, 500, 3);
  1014.     return;
  1015.   }
  1016.   CommitAckMarkerIterator iter;
  1017.   m_commitAckMarkerHash.next(startBucket, iter);
  1018.   
  1019.   const Uint32 RT_BREAK = 256;
  1020.   for(Uint32 i = 0; i<RT_BREAK || iter.bucket == startBucket; i++){ 
  1021.     jam();
  1022.     
  1023.     if(iter.curr.i == RNIL){
  1024.       jam();
  1025.       /**
  1026.        * Done with iteration
  1027.        */
  1028.       capiConnectClosing[nodeId]--;
  1029.       if (capiConnectClosing[nodeId] == 0) {
  1030.         jam();
  1031.         /********************************************************************/
  1032.         // No outstanding ABORT or COMMIT's of this failed API node. 
  1033.         // We can respond with API_FAILCONF
  1034.         /********************************************************************/
  1035.         signal->theData[0] = nodeId;
  1036.         signal->theData[1] = cownref;
  1037.         sendSignal(capiFailRef, GSN_API_FAILCONF, signal, 2, JBB);
  1038.       }
  1039.       return;
  1040.     }
  1041.     
  1042.     if(iter.curr.p->apiNodeId == nodeId){
  1043.       jam();
  1044.       
  1045.       /**
  1046.        * Check so that the record is not still in use
  1047.        *
  1048.        */
  1049.       ApiConnectRecordPtr apiConnectPtr;
  1050.       apiConnectPtr.i = iter.curr.p->apiConnectPtr;
  1051.       ptrCheckGuard(apiConnectPtr, capiConnectFilesize, apiConnectRecord);
  1052.       if(apiConnectPtr.p->commitAckMarker == iter.curr.i){
  1053. jam();
  1054.         /**
  1055.          * The record is still active
  1056.          *
  1057.          * Don't remove it, but continueb instead
  1058.          */
  1059. break;
  1060.       }
  1061.       sendRemoveMarkers(signal, iter.curr.p);
  1062.       m_commitAckMarkerHash.release(iter.curr);
  1063.       
  1064.       break;
  1065.     } 
  1066.     m_commitAckMarkerHash.next(iter);
  1067.   }
  1068.   
  1069.   signal->theData[0] = TcContinueB::ZHANDLE_FAILED_API_NODE_REMOVE_MARKERS;
  1070.   signal->theData[1] = nodeId;
  1071.   signal->theData[2] = iter.bucket;
  1072.   sendSignal(cownref, GSN_CONTINUEB, signal, 3, JBB);
  1073. }
  1074. void Dbtc::handleApiFailState(Signal* signal, UintR TapiConnectptr)
  1075. {
  1076.   ApiConnectRecordPtr TlocalApiConnectptr;
  1077.   UintR TfailedApiNode;
  1078.   TlocalApiConnectptr.i = TapiConnectptr;
  1079.   ptrCheckGuard(TlocalApiConnectptr, capiConnectFilesize, apiConnectRecord);
  1080.   TfailedApiNode = refToNode(TlocalApiConnectptr.p->ndbapiBlockref);
  1081.   arrGuard(TfailedApiNode, MAX_NODES);
  1082.   capiConnectClosing[TfailedApiNode]--;
  1083.   releaseApiCon(signal, TapiConnectptr);
  1084.   TlocalApiConnectptr.p->apiFailState = ZFALSE;
  1085.   if (capiConnectClosing[TfailedApiNode] == 0) {
  1086.     jam();
  1087.     signal->theData[0] = TfailedApiNode;
  1088.     signal->theData[1] = cownref;
  1089.     sendSignal(capiFailRef, GSN_API_FAILCONF, signal, 2, JBB);
  1090.   }//if
  1091. }//Dbtc::handleApiFailState()
  1092. /****************************************************************************
  1093.  *                                T C S E I Z E R E Q
  1094.  * THE APPLICATION SENDS A REQUEST TO SEIZE A CONNECT RECORD TO CARRY OUT A 
  1095.  * TRANSACTION
  1096.  * TC BLOCK TAKE OUT A CONNECT RECORD FROM THE FREE LIST AND ESTABLISHES ALL 
  1097.  * NECESSARY CONNECTION BEFORE REPLYING TO THE APPLICATION BLOCK   
  1098.  ****************************************************************************/
  1099. void Dbtc::execTCSEIZEREQ(Signal* signal) 
  1100. {
  1101.   UintR tapiPointer;
  1102.   BlockReference tapiBlockref;       /* SENDER BLOCK REFERENCE*/
  1103.   
  1104.   jamEntry();
  1105.   tapiPointer = signal->theData[0]; /* REQUEST SENDERS CONNECT RECORD POINTER*/
  1106.   tapiBlockref = signal->theData[1]; /* SENDERS BLOCK REFERENCE*/
  1107.   
  1108.   const NodeState::StartLevel sl = 
  1109.     (NodeState::StartLevel)getNodeState().startLevel;
  1110.   const NodeId senderNodeId = refToNode(tapiBlockref);
  1111.   const bool local = senderNodeId == getOwnNodeId() || senderNodeId == 0;
  1112.   
  1113.   if(!(senderNodeId == getNodeState().getSingleUserApi()) &&
  1114.       !getNodeState().getSingleUserMode()) {
  1115.     if(!(sl==NodeState::SL_SINGLEUSER && 
  1116.  senderNodeId == getNodeState().getSingleUserApi())) {
  1117.       if (!(sl == NodeState::SL_STARTED ||
  1118.     (sl == NodeState::SL_STARTING && local == true))) {
  1119. jam();
  1120. Uint32 errCode;
  1121. if(!(sl == NodeState::SL_SINGLEUSER && local))
  1122.   {
  1123.     switch(sl){
  1124.     case NodeState::SL_STARTING:
  1125.       errCode = ZSYSTEM_NOT_STARTED_ERROR;
  1126.       break;
  1127.     case NodeState::SL_STOPPING_1:
  1128.     case NodeState::SL_STOPPING_2:
  1129.     case NodeState::SL_STOPPING_3:
  1130.     case NodeState::SL_STOPPING_4:
  1131.       if(getNodeState().stopping.systemShutdown)
  1132. errCode = ZCLUSTER_SHUTDOWN_IN_PROGRESS;
  1133.       else
  1134. errCode = ZNODE_SHUTDOWN_IN_PROGRESS;
  1135.       break;
  1136.     case NodeState::SL_SINGLEUSER:
  1137.       errCode = ZCLUSTER_IN_SINGLEUSER_MODE;
  1138.       break;
  1139.     default:
  1140.       errCode = ZWRONG_STATE;
  1141.       break;
  1142.     }
  1143.     signal->theData[0] = tapiPointer;
  1144.     signal->theData[1] = errCode;
  1145.     sendSignal(tapiBlockref, GSN_TCSEIZEREF, signal, 2, JBB);
  1146.     return;
  1147.   }//if (!(sl == SL_SINGLEUSER))
  1148.       } //if
  1149.     }
  1150.   } 
  1151.   
  1152.   seizeApiConnect(signal);
  1153.   if (terrorCode == ZOK) {
  1154.     jam();
  1155.     apiConnectptr.p->ndbapiConnect = tapiPointer;
  1156.     apiConnectptr.p->ndbapiBlockref = tapiBlockref;
  1157.     signal->theData[0] = apiConnectptr.p->ndbapiConnect;
  1158.     signal->theData[1] = apiConnectptr.i;
  1159.     sendSignal(tapiBlockref, GSN_TCSEIZECONF, signal, 2, JBB);
  1160.     return;
  1161.   }
  1162.   signal->theData[0] = tapiPointer;
  1163.   signal->theData[1] = terrorCode;
  1164.   sendSignal(tapiBlockref, GSN_TCSEIZEREF, signal, 2, JBB);
  1165. }//Dbtc::execTCSEIZEREQ()
  1166. /****************************************************************************/
  1167. /*                    T C R E L E A S E Q                                   */
  1168. /*                  REQUEST TO RELEASE A CONNECT RECORD                     */
  1169. /****************************************************************************/
  1170. void Dbtc::execTCRELEASEREQ(Signal* signal) 
  1171. {
  1172.   UintR tapiPointer;
  1173.   BlockReference tapiBlockref;     /* SENDER BLOCK REFERENCE*/
  1174.   jamEntry();
  1175.   tapiPointer = signal->theData[0]; /* REQUEST SENDERS CONNECT RECORD POINTER*/
  1176.   tapiBlockref = signal->theData[1];/* SENDERS BLOCK REFERENCE*/
  1177.   tuserpointer = signal->theData[2];
  1178.   if (tapiPointer >= capiConnectFilesize) {
  1179.     jam();
  1180.     signal->theData[0] = tuserpointer;
  1181.     signal->theData[1] = ZINVALID_CONNECTION;
  1182.     signal->theData[2] = __LINE__;
  1183.     sendSignal(tapiBlockref, GSN_TCRELEASEREF, signal, 3, JBB);
  1184.     return;
  1185.   } else {
  1186.     jam();
  1187.     apiConnectptr.i = tapiPointer;
  1188.   }//if
  1189.   ptrAss(apiConnectptr, apiConnectRecord);
  1190.   if (apiConnectptr.p->apiConnectstate == CS_DISCONNECTED) {
  1191.     jam();
  1192.     signal->theData[0] = tuserpointer;
  1193.     sendSignal(tapiBlockref, GSN_TCRELEASECONF, signal, 1, JBB);
  1194.   } else {
  1195.     if (tapiBlockref == apiConnectptr.p->ndbapiBlockref) {
  1196.       if (apiConnectptr.p->apiConnectstate == CS_CONNECTED ||
  1197.   (apiConnectptr.p->apiConnectstate == CS_ABORTING &&
  1198.    apiConnectptr.p->abortState == AS_IDLE) ||
  1199.   (apiConnectptr.p->apiConnectstate == CS_STARTED &&
  1200.    apiConnectptr.p->firstTcConnect == RNIL))
  1201.       {
  1202.         jam();                                   /* JUST REPLY OK */
  1203.         releaseApiCon(signal, apiConnectptr.i);
  1204.         signal->theData[0] = tuserpointer;
  1205.         sendSignal(tapiBlockref,
  1206.                    GSN_TCRELEASECONF, signal, 1, JBB);
  1207.       } else {
  1208.         jam();
  1209.         signal->theData[0] = tuserpointer;
  1210.         signal->theData[1] = ZINVALID_CONNECTION;
  1211. signal->theData[2] = __LINE__;
  1212. signal->theData[3] = apiConnectptr.p->apiConnectstate;
  1213.         sendSignal(tapiBlockref,
  1214.                    GSN_TCRELEASEREF, signal, 4, JBB);
  1215.       }
  1216.     } else {
  1217.       jam();
  1218.       signal->theData[0] = tuserpointer;
  1219.       signal->theData[1] = ZINVALID_CONNECTION;
  1220.       signal->theData[2] = __LINE__;
  1221.       signal->theData[3] = tapiBlockref;      
  1222.       signal->theData[4] = apiConnectptr.p->ndbapiBlockref;      
  1223.       sendSignal(tapiBlockref, GSN_TCRELEASEREF, signal, 5, JBB);
  1224.     }//if
  1225.   }//if
  1226. }//Dbtc::execTCRELEASEREQ()
  1227. /****************************************************************************/
  1228. // Error Handling for TCKEYREQ messages
  1229. /****************************************************************************/
  1230. void Dbtc::signalErrorRefuseLab(Signal* signal) 
  1231. {
  1232.   ptrGuard(apiConnectptr);
  1233.   if (apiConnectptr.p->apiConnectstate != CS_DISCONNECTED) {
  1234.     jam();
  1235.     apiConnectptr.p->abortState = AS_IDLE;
  1236.     apiConnectptr.p->apiConnectstate = CS_ABORTING;
  1237.   }//if
  1238.   sendSignalErrorRefuseLab(signal);
  1239. }//Dbtc::signalErrorRefuseLab()
  1240. void Dbtc::sendSignalErrorRefuseLab(Signal* signal) 
  1241. {
  1242.   ndbassert(false);
  1243.   ptrGuard(apiConnectptr);
  1244.   if (apiConnectptr.p->apiConnectstate != CS_DISCONNECTED) {
  1245.     jam();
  1246.     ndbrequire(false);
  1247.     signal->theData[0] = apiConnectptr.p->ndbapiConnect;
  1248.     signal->theData[1] = signal->theData[ttransid_ptr];
  1249.     signal->theData[2] = signal->theData[ttransid_ptr + 1];
  1250.     signal->theData[3] = ZSIGNAL_ERROR;
  1251.     sendSignal(apiConnectptr.p->ndbapiBlockref, GSN_TCROLLBACKREP, 
  1252.        signal, 4, JBB);
  1253.   }
  1254. }//Dbtc::sendSignalErrorRefuseLab()
  1255. void Dbtc::abortBeginErrorLab(Signal* signal) 
  1256. {
  1257.   apiConnectptr.p->transid[0] = signal->theData[ttransid_ptr];
  1258.   apiConnectptr.p->transid[1] = signal->theData[ttransid_ptr + 1];
  1259.   abortErrorLab(signal);
  1260. }//Dbtc::abortBeginErrorLab()
  1261. void Dbtc::printState(Signal* signal, int place) 
  1262. {
  1263. #ifdef VM_TRACE // Change to if 0 to disable these printouts
  1264.   ndbout << "-- Dbtc::printState -- " << endl;
  1265.   ndbout << "Received from place = " << place
  1266.  << " apiConnectptr.i = " << apiConnectptr.i
  1267.  << " apiConnectstate = " << apiConnectptr.p->apiConnectstate << endl;
  1268.   ndbout << "ctcTimer = " << ctcTimer
  1269.  << " ndbapiBlockref = " << hex <<apiConnectptr.p->ndbapiBlockref
  1270.  << " Transid = " << apiConnectptr.p->transid[0]
  1271.  << " " << apiConnectptr.p->transid[1] << endl;
  1272.   ndbout << " apiTimer = " << getApiConTimer(apiConnectptr.i)
  1273.  << " counter = " << apiConnectptr.p->counter
  1274.  << " lqhkeyconfrec = " << apiConnectptr.p->lqhkeyconfrec
  1275.  << " lqhkeyreqrec = " << apiConnectptr.p->lqhkeyreqrec << endl;
  1276.   ndbout << "abortState = " << apiConnectptr.p->abortState 
  1277.  << " apiScanRec = " << apiConnectptr.p->apiScanRec
  1278.  << " returncode = " << apiConnectptr.p->returncode << endl;
  1279.   ndbout << "tckeyrec = " << apiConnectptr.p->tckeyrec
  1280.  << " returnsignal = " << apiConnectptr.p->returnsignal
  1281.  << " apiFailState = " << apiConnectptr.p->apiFailState << endl;
  1282.   if (apiConnectptr.p->cachePtr != RNIL) {
  1283.     jam();
  1284.     CacheRecord *localCacheRecord = cacheRecord;
  1285.     UintR TcacheFilesize = ccacheFilesize;
  1286.     UintR TcachePtr = apiConnectptr.p->cachePtr;
  1287.     if (TcachePtr < TcacheFilesize) {
  1288.       jam();
  1289.       CacheRecord * const regCachePtr = &localCacheRecord[TcachePtr];
  1290.       ndbout << "currReclenAi = " << regCachePtr->currReclenAi
  1291.      << " attrlength = " << regCachePtr->attrlength
  1292.      << " tableref = " << regCachePtr->tableref
  1293.      << " keylen = " << regCachePtr->keylen << endl;
  1294.     } else {
  1295.       jam();
  1296.       systemErrorLab(signal);
  1297.     }//if
  1298.   }//if
  1299. #endif
  1300.   return;
  1301. }//Dbtc::printState()
  1302. void
  1303. Dbtc::TCKEY_abort(Signal* signal, int place)
  1304. {
  1305.   switch (place) {
  1306.   case 0:
  1307.     jam();
  1308.     terrorCode = ZSTATE_ERROR;
  1309.     apiConnectptr.p->firstTcConnect = RNIL;
  1310.     printState(signal, 4);
  1311.     abortBeginErrorLab(signal);
  1312.     return;
  1313.   case 1:
  1314.     jam();
  1315.     printState(signal, 3);
  1316.     sendSignalErrorRefuseLab(signal);
  1317.     return;
  1318.   case 2:{
  1319.     printState(signal, 6);
  1320.     const TcKeyReq * const tcKeyReq = (TcKeyReq *)&signal->theData[0];
  1321.     const Uint32 t1 = tcKeyReq->transId1;
  1322.     const Uint32 t2 = tcKeyReq->transId2;
  1323.     signal->theData[0] = apiConnectptr.p->ndbapiConnect;
  1324.     signal->theData[1] = t1;
  1325.     signal->theData[2] = t2;
  1326.     signal->theData[3] = ZABORT_ERROR;
  1327.     ndbrequire(false);
  1328.     sendSignal(apiConnectptr.p->ndbapiBlockref, GSN_TCROLLBACKREP, 
  1329.        signal, 4, JBB);
  1330.     return;
  1331.   }
  1332.   case 3:
  1333.     jam();
  1334.     printState(signal, 7);
  1335.     noFreeConnectionErrorLab(signal);
  1336.     return;
  1337.   case 4:
  1338.     jam();
  1339.     terrorCode = ZERO_KEYLEN_ERROR;
  1340.     releaseAtErrorLab(signal);
  1341.     return;
  1342.   case 5:
  1343.     jam();
  1344.     terrorCode = ZNO_AI_WITH_UPDATE;
  1345.     releaseAtErrorLab(signal);
  1346.     return;
  1347.   case 6:
  1348.     jam();
  1349.     warningHandlerLab(signal);
  1350.     return;
  1351.   case 7:
  1352.     jam();
  1353.     tabStateErrorLab(signal);
  1354.     return;
  1355.   case 8:
  1356.     jam();
  1357.     wrongSchemaVersionErrorLab(signal);
  1358.     return;
  1359.   case 9:
  1360.     jam();
  1361.     terrorCode = ZSTATE_ERROR;
  1362.     releaseAtErrorLab(signal);
  1363.     return;
  1364.   case 10:
  1365.     jam();
  1366.     systemErrorLab(signal);
  1367.     return;
  1368.   case 11:
  1369.     jam();
  1370.     terrorCode = ZMORE_AI_IN_TCKEYREQ_ERROR;
  1371.     releaseAtErrorLab(signal);
  1372.     return;
  1373.   case 12:
  1374.     jam();
  1375.     terrorCode = ZSIMPLE_READ_WITHOUT_AI;
  1376.     releaseAtErrorLab(signal);
  1377.     return;
  1378.   case 13:
  1379.     jam();
  1380.     switch (tcConnectptr.p->tcConnectstate) {
  1381.     case OS_WAIT_KEYINFO:
  1382.       jam();
  1383.       printState(signal, 8);
  1384.       terrorCode = ZSTATE_ERROR;
  1385.       abortErrorLab(signal);
  1386.       return;
  1387.     default:
  1388.       jam();
  1389.       /********************************************************************/
  1390.       /*       MISMATCH BETWEEN STATE ON API CONNECTION AND THIS          */
  1391.       /*       PARTICULAR TC CONNECT RECORD. THIS MUST BE CAUSED BY NDB   */
  1392.       /*       INTERNAL ERROR.                                            */
  1393.       /********************************************************************/
  1394.       systemErrorLab(signal);
  1395.       return;
  1396.     }//switch
  1397.     return;
  1398.   case 15:
  1399.     jam();
  1400.     terrorCode = ZSCAN_NODE_ERROR;
  1401.     releaseAtErrorLab(signal);
  1402.     return;
  1403.   case 16:
  1404.     jam();
  1405.     systemErrorLab(signal);
  1406.     return;
  1407.   case 17:
  1408.     jam();
  1409.     systemErrorLab(signal);
  1410.     return;
  1411.   case 18:
  1412.     jam();
  1413.     warningHandlerLab(signal);
  1414.     return;
  1415.   case 19:
  1416.     jam();
  1417.     return;
  1418.   case 20:
  1419.     jam();
  1420.     warningHandlerLab(signal);
  1421.     return;
  1422.   case 21:
  1423.     jam();
  1424.     systemErrorLab(signal);
  1425.     return;
  1426.   case 22:
  1427.     jam();
  1428.     systemErrorLab(signal);
  1429.     return;
  1430.   case 23:
  1431.     jam();
  1432.     systemErrorLab(signal);
  1433.     return;
  1434.   case 24:
  1435.     jam();
  1436.     seizeAttrbuferrorLab(signal);
  1437.     return;
  1438.   case 25:
  1439.     jam();
  1440.     warningHandlerLab(signal);
  1441.     return;
  1442.   case 26:
  1443.     jam();
  1444.     return;
  1445.   case 27:
  1446.     systemErrorLab(signal);
  1447.     jam();
  1448.     return;
  1449.   case 28:
  1450.     jam();
  1451.     // NOT USED
  1452.     return;
  1453.   case 29:
  1454.     jam();
  1455.     systemErrorLab(signal);
  1456.     return;
  1457.   case 30:
  1458.     jam();
  1459.     systemErrorLab(signal);
  1460.     return;
  1461.   case 31:
  1462.     jam();
  1463.     systemErrorLab(signal);
  1464.     return;
  1465.   case 32:
  1466.     jam();
  1467.     systemErrorLab(signal);
  1468.     return;
  1469.   case 33:
  1470.     jam();
  1471.     systemErrorLab(signal);
  1472.     return;
  1473.   case 34:
  1474.     jam();
  1475.     systemErrorLab(signal);
  1476.     return;
  1477.   case 35:
  1478.     jam();
  1479.     systemErrorLab(signal);
  1480.     return;
  1481.   case 36:
  1482.     jam();
  1483.     systemErrorLab(signal);
  1484.     return;
  1485.   case 37:
  1486.     jam();
  1487.     systemErrorLab(signal);
  1488.     return;
  1489.   case 38:
  1490.     jam();
  1491.     systemErrorLab(signal);
  1492.     return;
  1493.   case 39:
  1494.     jam();
  1495.     systemErrorLab(signal);
  1496.     return;
  1497.   case 40:
  1498.     jam();
  1499.     systemErrorLab(signal);
  1500.     return;
  1501.   case 41:
  1502.     jam();
  1503.     systemErrorLab(signal);
  1504.     return;
  1505.   case 42:
  1506.     jam();
  1507.     systemErrorLab(signal);
  1508.     return;
  1509.   case 43:
  1510.     jam();
  1511.     systemErrorLab(signal);
  1512.     return;
  1513.   case 44:
  1514.     jam();
  1515.     systemErrorLab(signal);
  1516.     return;
  1517.   case 45:
  1518.     jam();
  1519.     systemErrorLab(signal);
  1520.     return;
  1521.   case 46:
  1522.     jam();
  1523.     systemErrorLab(signal);
  1524.     return;
  1525.   case 47:
  1526.     jam();
  1527.     terrorCode = apiConnectptr.p->returncode;
  1528.     releaseAtErrorLab(signal);
  1529.     return;
  1530.   case 48:
  1531.     jam();
  1532.     terrorCode = ZCOMMIT_TYPE_ERROR;
  1533.     releaseAtErrorLab(signal);
  1534.     return;
  1535.   case 49:
  1536.     jam();
  1537.     abortErrorLab(signal);
  1538.     return;
  1539.   case 50:
  1540.     jam();
  1541.     systemErrorLab(signal);
  1542.     return;
  1543.   case 51:
  1544.     jam();
  1545.     abortErrorLab(signal);
  1546.     return;
  1547.   case 52:
  1548.     jam();
  1549.     abortErrorLab(signal);
  1550.     return;
  1551.   case 53:
  1552.     jam();
  1553.     abortErrorLab(signal);
  1554.     return;
  1555.   case 54:
  1556.     jam();
  1557.     abortErrorLab(signal);
  1558.     return;
  1559.   case 55:
  1560.     jam();
  1561.     printState(signal, 5);
  1562.     sendSignalErrorRefuseLab(signal);
  1563.     return;
  1564.     
  1565.   case 56:{
  1566.     jam();
  1567.     terrorCode = ZNO_FREE_TC_MARKER;
  1568.     abortErrorLab(signal);
  1569.     return;
  1570.   }
  1571.   case 57:{
  1572.     jam();
  1573.     /**
  1574.      * Initialize object before starting error handling
  1575.      */
  1576.     initApiConnectRec(signal, apiConnectptr.p, true);
  1577.     switch(getNodeState().startLevel){
  1578.     case NodeState::SL_STOPPING_2:
  1579.     case NodeState::SL_STOPPING_3:
  1580.     case NodeState::SL_STOPPING_4:
  1581.       if(getNodeState().stopping.systemShutdown)
  1582. terrorCode  = ZCLUSTER_SHUTDOWN_IN_PROGRESS;
  1583.       else
  1584. terrorCode = ZNODE_SHUTDOWN_IN_PROGRESS;
  1585.       break;
  1586.     case NodeState::SL_SINGLEUSER:
  1587.       terrorCode  = ZCLUSTER_IN_SINGLEUSER_MODE;
  1588.       break;
  1589.     default:
  1590.       terrorCode = ZWRONG_STATE;
  1591.       break;
  1592.     }
  1593.     abortErrorLab(signal);
  1594.     return;
  1595.   }
  1596.   case 58:{
  1597.     jam();
  1598.     releaseAtErrorLab(signal);
  1599.     return;
  1600.   }
  1601.   case 59:{
  1602.     jam();
  1603.     terrorCode = ZABORTINPROGRESS;
  1604.     abortErrorLab(signal);
  1605.     return;
  1606.   }
  1607.     
  1608.   default:
  1609.     jam();
  1610.     systemErrorLab(signal);
  1611.     return;
  1612.   }//switch
  1613. }
  1614. void Dbtc::execKEYINFO(Signal* signal) 
  1615. {
  1616.   UintR compare_transid1, compare_transid2;
  1617.   jamEntry();
  1618.   apiConnectptr.i = signal->theData[0];
  1619.   tmaxData = 20;
  1620.   if (apiConnectptr.i >= capiConnectFilesize) {
  1621.     jam();
  1622.     warningHandlerLab(signal);
  1623.     return;
  1624.   }//if
  1625.   ptrAss(apiConnectptr, apiConnectRecord);
  1626.   ttransid_ptr = 1;
  1627.   compare_transid1 = apiConnectptr.p->transid[0] ^ signal->theData[1];
  1628.   compare_transid2 = apiConnectptr.p->transid[1] ^ signal->theData[2];
  1629.   compare_transid1 = compare_transid1 | compare_transid2;
  1630.   if (compare_transid1 != 0) {
  1631.     jam();
  1632.     printState(signal, 10);
  1633.     sendSignalErrorRefuseLab(signal);
  1634.     return;
  1635.   }//if
  1636.   switch (apiConnectptr.p->apiConnectstate) {
  1637.   case CS_RECEIVING:
  1638.   case CS_REC_COMMITTING:
  1639.   case CS_START_SCAN:
  1640.     jam();
  1641.     /*empty*/;
  1642.     break;
  1643.                 /* OK */
  1644.   case CS_ABORTING:
  1645.     jam();
  1646.     return;     /* IGNORE */
  1647.   case CS_CONNECTED:
  1648.     jam();
  1649.     /****************************************************************>*/
  1650.     /*       MOST LIKELY CAUSED BY A MISSED SIGNAL. SEND REFUSE AND   */
  1651.     /*       SET STATE TO ABORTING.                                   */
  1652.     /****************************************************************>*/
  1653.     printState(signal, 11);
  1654.     signalErrorRefuseLab(signal);
  1655.     return;
  1656.   case CS_STARTED:
  1657.     jam();
  1658.     /****************************************************************>*/
  1659.     /*       MOST LIKELY CAUSED BY A MISSED SIGNAL. SEND REFUSE AND   */
  1660.     /*       SET STATE TO ABORTING. SINCE A TRANSACTION WAS STARTED   */
  1661.     /*       WE ALSO NEED TO ABORT THIS TRANSACTION.                  */
  1662.     /****************************************************************>*/
  1663.     terrorCode = ZSIGNAL_ERROR;
  1664.     printState(signal, 2);
  1665.     abortErrorLab(signal);
  1666.     return;
  1667.   default:
  1668.     jam();
  1669.     warningHandlerLab(signal);
  1670.     return;
  1671.   }//switch
  1672.   CacheRecord *localCacheRecord = cacheRecord;
  1673.   UintR TcacheFilesize = ccacheFilesize;
  1674.   UintR TcachePtr = apiConnectptr.p->cachePtr;
  1675.   UintR TtcTimer = ctcTimer;
  1676.   CacheRecord * const regCachePtr = &localCacheRecord[TcachePtr];
  1677.   if (TcachePtr >= TcacheFilesize) {
  1678.     TCKEY_abort(signal, 42);
  1679.     return;
  1680.   }//if
  1681.   setApiConTimer(apiConnectptr.i, TtcTimer, __LINE__);
  1682.   cachePtr.i = TcachePtr;
  1683.   cachePtr.p = regCachePtr;
  1684.   tcConnectptr.i = apiConnectptr.p->lastTcConnect;
  1685.   ptrCheckGuard(tcConnectptr, ctcConnectFilesize, tcConnectRecord);
  1686.   switch (tcConnectptr.p->tcConnectstate) {
  1687.   case OS_WAIT_KEYINFO:
  1688.     jam();
  1689.     tckeyreq020Lab(signal);
  1690.     return;
  1691.   case OS_WAIT_SCAN:
  1692.     break;
  1693.   default:
  1694.     jam();
  1695.     terrorCode = ZSTATE_ERROR;
  1696.     abortErrorLab(signal);
  1697.     return;
  1698.   }//switch
  1699.   UintR TdataPos = 0;
  1700.   UintR TkeyLen = regCachePtr->keylen;
  1701.   UintR Tlen = regCachePtr->save1;
  1702.   do {
  1703.     if (cfirstfreeDatabuf == RNIL) {
  1704.       jam();
  1705.       seizeDatabuferrorLab(signal);
  1706.       return;
  1707.     }//if
  1708.     linkKeybuf(signal);
  1709.     arrGuard(TdataPos, 19);
  1710.     databufptr.p->data[0] = signal->theData[TdataPos + 3];
  1711.     databufptr.p->data[1] = signal->theData[TdataPos + 4];
  1712.     databufptr.p->data[2] = signal->theData[TdataPos + 5];
  1713.     databufptr.p->data[3] = signal->theData[TdataPos + 6];
  1714.     Tlen = Tlen + 4;
  1715.     TdataPos = TdataPos + 4;
  1716.     if (Tlen < TkeyLen) {
  1717.       jam();
  1718.       if (TdataPos >= tmaxData) {
  1719.         jam();
  1720. /*----------------------------------------------------*/
  1721. /** EXIT AND WAIT FOR SIGNAL KEYINFO OR KEYINFO9     **/
  1722. /** WHEN EITHER OF THE SIGNALS IS RECEIVED A JUMP    **/
  1723. /** TO LABEL "KEYINFO_LABEL" IS DONE. THEN THE       **/
  1724. /** PROGRAM RETURNS TO LABEL TCKEYREQ020             **/
  1725. /*----------------------------------------------------*/
  1726.         setApiConTimer(apiConnectptr.i, ctcTimer, __LINE__);
  1727.         regCachePtr->save1 = Tlen;
  1728.         return;
  1729.       }//if
  1730.     } else {
  1731.       jam();
  1732.       return;
  1733.     }//if
  1734.   } while (1);
  1735.   return;
  1736. }//Dbtc::execKEYINFO()
  1737. /*---------------------------------------------------------------------------*/
  1738. /*                                                                           */
  1739. /* MORE THAN FOUR WORDS OF KEY DATA. WE NEED TO PACK THIS IN KEYINFO SIGNALS.*/
  1740. /* WE WILL ALWAYS PACK 4 WORDS AT A TIME.                                    */
  1741. /*---------------------------------------------------------------------------*/
  1742. void Dbtc::packKeyData000Lab(Signal* signal,
  1743.                              BlockReference TBRef,
  1744.      Uint32 totalLen) 
  1745. {
  1746.   CacheRecord * const regCachePtr = cachePtr.p;
  1747.   jam();
  1748.   Uint32 len = 0;
  1749.   databufptr.i = regCachePtr->firstKeybuf;
  1750.   signal->theData[0] = tcConnectptr.i;
  1751.   signal->theData[1] = apiConnectptr.p->transid[0];
  1752.   signal->theData[2] = apiConnectptr.p->transid[1];
  1753.   Uint32 * dst = signal->theData+3;
  1754.   ptrCheckGuard(databufptr, cdatabufFilesize, databufRecord);
  1755.   
  1756.   do {
  1757.     jam();
  1758.     databufptr.i = databufptr.p->nextDatabuf;
  1759.     dst[len + 0] = databufptr.p->data[0];
  1760.     dst[len + 1] = databufptr.p->data[1];
  1761.     dst[len + 2] = databufptr.p->data[2];
  1762.     dst[len + 3] = databufptr.p->data[3];
  1763.     len += 4;
  1764.     if (totalLen <= 4) {
  1765.       jam();
  1766.       /*---------------------------------------------------------------------*/
  1767.       /*       LAST PACK OF KEY DATA HAVE BEEN SENT                          */
  1768.       /*---------------------------------------------------------------------*/
  1769.       /*       THERE WERE UNSENT INFORMATION, SEND IT.                       */
  1770.       /*---------------------------------------------------------------------*/
  1771.       sendSignal(TBRef, GSN_KEYINFO, signal, 3 + len, JBB);
  1772.       return;
  1773.     } else if(len == KeyInfo::DataLength){
  1774.       jam();
  1775.       len = 0;
  1776.       sendSignal(TBRef, GSN_KEYINFO, signal, 3 + KeyInfo::DataLength, JBB);
  1777.     }
  1778.     totalLen -= 4;
  1779.     ptrCheckGuard(databufptr, cdatabufFilesize, databufRecord);
  1780.   } while (1);
  1781. }//Dbtc::packKeyData000Lab()
  1782. void Dbtc::tckeyreq020Lab(Signal* signal) 
  1783. {
  1784.   CacheRecord * const regCachePtr = cachePtr.p;
  1785.   UintR TdataPos = 0;
  1786.   UintR TkeyLen = regCachePtr->keylen;
  1787.   UintR Tlen = regCachePtr->save1;
  1788.   do {
  1789.     if (cfirstfreeDatabuf == RNIL) {
  1790.       jam();
  1791.       seizeDatabuferrorLab(signal);
  1792.       return;
  1793.     }//if
  1794.     linkKeybuf(signal);
  1795.     arrGuard(TdataPos, 19);
  1796.     databufptr.p->data[0] = signal->theData[TdataPos + 3];
  1797.     databufptr.p->data[1] = signal->theData[TdataPos + 4];
  1798.     databufptr.p->data[2] = signal->theData[TdataPos + 5];
  1799.     databufptr.p->data[3] = signal->theData[TdataPos + 6];
  1800.     Tlen = Tlen + 4;
  1801.     TdataPos = TdataPos + 4;
  1802.     if (Tlen < TkeyLen) {
  1803.       jam();
  1804.       if (TdataPos >= tmaxData) {
  1805.         jam();
  1806. /*----------------------------------------------------*/
  1807. /** EXIT AND WAIT FOR SIGNAL KEYINFO OR KEYINFO9     **/
  1808. /** WHEN EITHER OF THE SIGNALS IS RECEIVED A JUMP    **/
  1809. /** TO LABEL "KEYINFO_LABEL" IS DONE. THEN THE       **/
  1810. /** PROGRAM RETURNS TO LABEL TCKEYREQ020             **/
  1811. /*----------------------------------------------------*/
  1812.         setApiConTimer(apiConnectptr.i, ctcTimer, __LINE__);
  1813.         regCachePtr->save1 = Tlen;
  1814.         tcConnectptr.p->tcConnectstate = OS_WAIT_KEYINFO;
  1815.         return;
  1816.       }//if
  1817.     } else {
  1818.       jam();
  1819.       tckeyreq050Lab(signal);
  1820.       return;
  1821.     }//if
  1822.   } while (1);
  1823.   return;
  1824. }//Dbtc::tckeyreq020Lab()
  1825. /* ------------------------------------------------------------------------- */
  1826. /* -------        SAVE ATTRIBUTE INFORMATION IN OPERATION RECORD     ------- */
  1827. /* ------------------------------------------------------------------------- */
  1828. void Dbtc::saveAttrbuf(Signal* signal) 
  1829. {
  1830.   CacheRecord * const regCachePtr = cachePtr.p;
  1831.   UintR TfirstfreeAttrbuf = cfirstfreeAttrbuf;
  1832.   UintR TattrbufFilesize = cattrbufFilesize;
  1833.   UintR TTcfirstAttrbuf = regCachePtr->firstAttrbuf;
  1834.   UintR Tlen = signal->length() - 3;
  1835.   AttrbufRecord *localAttrbufRecord = attrbufRecord;
  1836.   AttrbufRecord * const regAttrPtr = &localAttrbufRecord[TfirstfreeAttrbuf];
  1837.   if (TfirstfreeAttrbuf >= TattrbufFilesize) {
  1838.     TCKEY_abort(signal, 21);
  1839.     return;
  1840.   }//if
  1841.   UintR Tnext = regAttrPtr->attrbuf[ZINBUF_NEXT];
  1842.   if (TTcfirstAttrbuf == RNIL) {
  1843.     jam();
  1844.     regCachePtr->firstAttrbuf = TfirstfreeAttrbuf;
  1845.   } else {
  1846.     AttrbufRecordPtr saAttrbufptr;
  1847.     saAttrbufptr.i = regCachePtr->lastAttrbuf;
  1848.     jam();
  1849.     if (saAttrbufptr.i >= TattrbufFilesize) {
  1850.       TCKEY_abort(signal, 22);
  1851.       return;
  1852.     }//if
  1853.     saAttrbufptr.p = &localAttrbufRecord[saAttrbufptr.i];
  1854.     saAttrbufptr.p->attrbuf[ZINBUF_NEXT] = TfirstfreeAttrbuf;
  1855.   }//if
  1856.   cfirstfreeAttrbuf = Tnext;
  1857.   regAttrPtr->attrbuf[ZINBUF_NEXT] = RNIL;
  1858.   regCachePtr->lastAttrbuf = TfirstfreeAttrbuf;
  1859.   regAttrPtr->attrbuf[ZINBUF_DATA_LEN] = Tlen;
  1860.   UintR Tdata1 = signal->theData[3];
  1861.   UintR Tdata2 = signal->theData[4];
  1862.   UintR Tdata3 = signal->theData[5];
  1863.   UintR Tdata4 = signal->theData[6];
  1864.   UintR Tdata5 = signal->theData[7];
  1865.   UintR Tdata6 = signal->theData[8];
  1866.   UintR Tdata7 = signal->theData[9];
  1867.   UintR Tdata8 = signal->theData[10];
  1868.   regAttrPtr->attrbuf[0] = Tdata1;
  1869.   regAttrPtr->attrbuf[1] = Tdata2;
  1870.   regAttrPtr->attrbuf[2] = Tdata3;
  1871.   regAttrPtr->attrbuf[3] = Tdata4;
  1872.   regAttrPtr->attrbuf[4] = Tdata5;
  1873.   regAttrPtr->attrbuf[5] = Tdata6;
  1874.   regAttrPtr->attrbuf[6] = Tdata7;
  1875.   regAttrPtr->attrbuf[7] = Tdata8;
  1876.   if (Tlen > 8) {
  1877.     Tdata1 = signal->theData[11];
  1878.     Tdata2 = signal->theData[12];
  1879.     Tdata3 = signal->theData[13];
  1880.     Tdata4 = signal->theData[14];
  1881.     Tdata5 = signal->theData[15];
  1882.     Tdata6 = signal->theData[16];
  1883.     Tdata7 = signal->theData[17];
  1884.     regAttrPtr->attrbuf[8] = Tdata1;
  1885.     regAttrPtr->attrbuf[9] = Tdata2;
  1886.     regAttrPtr->attrbuf[10] = Tdata3;
  1887.     regAttrPtr->attrbuf[11] = Tdata4;
  1888.     regAttrPtr->attrbuf[12] = Tdata5;
  1889.     regAttrPtr->attrbuf[13] = Tdata6;
  1890.     regAttrPtr->attrbuf[14] = Tdata7;
  1891.     jam();
  1892.     if (Tlen > 15) {
  1893.       Tdata1 = signal->theData[18];
  1894.       Tdata2 = signal->theData[19];
  1895.       Tdata3 = signal->theData[20];
  1896.       Tdata4 = signal->theData[21];
  1897.       Tdata5 = signal->theData[22];
  1898.       Tdata6 = signal->theData[23];
  1899.       Tdata7 = signal->theData[24];
  1900.       jam();
  1901.       regAttrPtr->attrbuf[15] = Tdata1;
  1902.       regAttrPtr->attrbuf[16] = Tdata2;
  1903.       regAttrPtr->attrbuf[17] = Tdata3;
  1904.       regAttrPtr->attrbuf[18] = Tdata4;
  1905.       regAttrPtr->attrbuf[19] = Tdata5;
  1906.       regAttrPtr->attrbuf[20] = Tdata6;
  1907.       regAttrPtr->attrbuf[21] = Tdata7;
  1908.     }//if
  1909.   }//if
  1910. }//Dbtc::saveAttrbuf()
  1911. void Dbtc::execATTRINFO(Signal* signal) 
  1912. {
  1913.   UintR compare_transid1, compare_transid2;
  1914.   UintR Tdata1 = signal->theData[0];
  1915.   UintR Tlength = signal->length();
  1916.   UintR TapiConnectFilesize = capiConnectFilesize;
  1917.   ApiConnectRecord *localApiConnectRecord = apiConnectRecord;
  1918.   jamEntry();
  1919.   apiConnectptr.i = Tdata1;
  1920.   ttransid_ptr = 1;
  1921.   if (Tdata1 >= TapiConnectFilesize) {
  1922.     DEBUG("Drop ATTRINFO, wrong apiConnectptr");
  1923.     TCKEY_abort(signal, 18);
  1924.     return;
  1925.   }//if
  1926.   UintR Tdata2 = signal->theData[1];
  1927.   UintR Tdata3 = signal->theData[2];
  1928.   ApiConnectRecord * const regApiPtr = &localApiConnectRecord[Tdata1];
  1929.   compare_transid1 = regApiPtr->transid[0] ^ Tdata2;
  1930.   compare_transid2 = regApiPtr->transid[1] ^ Tdata3;
  1931.   apiConnectptr.p = regApiPtr;
  1932.   compare_transid1 = compare_transid1 | compare_transid2;
  1933.   if (compare_transid1 != 0) {
  1934.     DEBUG("Drop ATTRINFO, wrong transid, lenght="<<Tlength
  1935.   << " transid("<<hex<<Tdata2<<", "<<Tdata3);
  1936.     TCKEY_abort(signal, 19);
  1937.     return;
  1938.   }//if
  1939.   if (Tlength < 4) {
  1940.     DEBUG("Drop ATTRINFO, wrong length = " << Tlength);
  1941.     TCKEY_abort(signal, 20);
  1942.     return;
  1943.   }
  1944.   Tlength -= 3;
  1945.   UintR TcompREC_COMMIT = (regApiPtr->apiConnectstate == CS_REC_COMMITTING);
  1946.   UintR TcompRECEIVING = (regApiPtr->apiConnectstate == CS_RECEIVING);
  1947.   UintR TcompBOTH = TcompREC_COMMIT | TcompRECEIVING;
  1948.   if (TcompBOTH) {
  1949.     jam();
  1950.     if (ERROR_INSERTED(8015)) {
  1951.       CLEAR_ERROR_INSERT_VALUE;
  1952.       return;
  1953.     }//if
  1954.     if (ERROR_INSERTED(8016)) {
  1955.       CLEAR_ERROR_INSERT_VALUE;
  1956.       return;
  1957.     }//if
  1958.     CacheRecord *localCacheRecord = cacheRecord;
  1959.     UintR TcacheFilesize = ccacheFilesize;
  1960.     UintR TcachePtr = regApiPtr->cachePtr;
  1961.     UintR TtcTimer = ctcTimer;
  1962.     CacheRecord * const regCachePtr = &localCacheRecord[TcachePtr];
  1963.     if (TcachePtr >= TcacheFilesize) {
  1964.       TCKEY_abort(signal, 43);
  1965.       return;
  1966.     }//if
  1967.     UintR TfirstfreeAttrbuf = cfirstfreeAttrbuf;
  1968.     UintR TcurrReclenAi = regCachePtr->currReclenAi;
  1969.     UintR TattrLen = regCachePtr->attrlength;
  1970.     setApiConTimer(apiConnectptr.i, TtcTimer, __LINE__);
  1971.     cachePtr.i = TcachePtr;
  1972.     cachePtr.p = regCachePtr;
  1973.     TcurrReclenAi = TcurrReclenAi + Tlength;
  1974.     regCachePtr->currReclenAi = TcurrReclenAi;
  1975.     int TattrlengthRemain = TattrLen - TcurrReclenAi;
  1976.     if (TfirstfreeAttrbuf == RNIL) {
  1977.       DEBUG("No more attrinfo buffers");
  1978.       TCKEY_abort(signal, 24);
  1979.       return;
  1980.     }//if
  1981.     saveAttrbuf(signal);
  1982.     if (TattrlengthRemain == 0) {
  1983.       /****************************************************************>*/
  1984.       /* HERE WE HAVE FOUND THAT THE LAST SIGNAL BELONGING TO THIS       */
  1985.       /* OPERATION HAVE BEEN RECEIVED. THIS MEANS THAT WE CAN NOW REUSE */
  1986.       /* THE API CONNECT RECORD. HOWEVER IF PREPARE OR COMMIT HAVE BEEN */
  1987.       /* RECEIVED THEN IT IS NOT ALLOWED TO RECEIVE ANY FURTHER          */
  1988.       /* OPERATIONS.                                                     */
  1989.       /****************************************************************>*/
  1990.       UintR TlastConnect = regApiPtr->lastTcConnect;
  1991.       if (TcompRECEIVING) {
  1992.         jam();
  1993.         regApiPtr->apiConnectstate = CS_STARTED;
  1994.       } else {
  1995.         jam();
  1996.         regApiPtr->apiConnectstate = CS_START_COMMITTING;
  1997.       }//if
  1998.       tcConnectptr.i = TlastConnect;
  1999.       ptrCheckGuard(tcConnectptr, ctcConnectFilesize, tcConnectRecord);
  2000.       attrinfoDihReceivedLab(signal);
  2001.     } else if (TattrlengthRemain < 0) {
  2002.       jam();
  2003.       DEBUG("ATTRINFO wrong total length="<<Tlength
  2004.     <<", TattrlengthRemain="<<TattrlengthRemain
  2005.     <<", TattrLen="<<TattrLen
  2006.     <<", TcurrReclenAi="<<TcurrReclenAi);
  2007.       tcConnectptr.i = regApiPtr->lastTcConnect;
  2008.       ptrCheckGuard(tcConnectptr, ctcConnectFilesize, tcConnectRecord);
  2009.       aiErrorLab(signal);
  2010.     }//if
  2011.     return;
  2012.   } else if (regApiPtr->apiConnectstate == CS_START_SCAN) {
  2013.     jam();
  2014.     scanAttrinfoLab(signal, Tlength);
  2015.     return;
  2016.   } else {
  2017.     switch (regApiPtr->apiConnectstate) {
  2018.     case CS_ABORTING:
  2019.       jam();
  2020.       /* JUST IGNORE THE SIGNAL*/
  2021.       // DEBUG("Drop ATTRINFO, CS_ABORTING"); 
  2022.       return;
  2023.     case CS_CONNECTED:
  2024.       jam();
  2025.       /* MOST LIKELY CAUSED BY A MISSED SIGNAL.*/
  2026.       // DEBUG("Drop ATTRINFO, CS_CONNECTED"); 
  2027.       return;
  2028.     case CS_STARTED:
  2029.       jam();
  2030.       /****************************************************************>*/
  2031.       /*       MOST LIKELY CAUSED BY A MISSED SIGNAL. SEND REFUSE AND   */
  2032.       /*       SET STATE TO ABORTING. SINCE A TRANSACTION WAS STARTED   */
  2033.       /*       WE ALSO NEED TO ABORT THIS TRANSACTION.                  */
  2034.       /****************************************************************>*/
  2035.       terrorCode = ZSIGNAL_ERROR;
  2036.       printState(signal, 1);
  2037.       abortErrorLab(signal);
  2038.       return;
  2039.     default:
  2040.       jam();
  2041.       /****************************************************************>*/
  2042.       /*       SIGNAL RECEIVED IN AN UNEXPECTED STATE. WE IGNORE SIGNAL */
  2043.       /*       SINCE WE DO NOT REALLY KNOW WHERE THE ERROR OCCURRED.    */
  2044.       /****************************************************************>*/
  2045.       DEBUG("Drop ATTRINFO, illegal state="<<regApiPtr->apiConnectstate); 
  2046.       printState(signal, 9);
  2047.       return;
  2048.     }//switch
  2049.   }//if
  2050. }//Dbtc::execATTRINFO()
  2051. /* *********************************************************************>> */
  2052. /*                                                                        */
  2053. /*       MODULE: HASH MODULE                                              */
  2054. /*       DESCRIPTION: CONTAINS THE HASH VALUE CALCULATION                 */
  2055. /* *********************************************************************> */
  2056. void Dbtc::hash(Signal* signal) 
  2057. {
  2058.   DatabufRecordPtr locDatabufptr;
  2059.   UintR ti;
  2060.   UintR  Tdata0;
  2061.   UintR  Tdata1;
  2062.   UintR  Tdata2;
  2063.   UintR  Tdata3;
  2064.   UintR*  Tdata32;
  2065.   Uint64 Tdata[512];
  2066.   CacheRecord * const regCachePtr = cachePtr.p;
  2067.   Tdata32 = (UintR*)&Tdata[0];
  2068.   Tdata0 = regCachePtr->keydata[0];
  2069.   Tdata1 = regCachePtr->keydata[1];
  2070.   Tdata2 = regCachePtr->keydata[2];
  2071.   Tdata3 = regCachePtr->keydata[3];
  2072.   Tdata32[0] = Tdata0;
  2073.   Tdata32[1] = Tdata1;
  2074.   Tdata32[2] = Tdata2;
  2075.   Tdata32[3] = Tdata3;
  2076.   if (regCachePtr->keylen > 4) {
  2077.     locDatabufptr.i = regCachePtr->firstKeybuf;
  2078.     ti = 4;
  2079.     while (locDatabufptr.i != RNIL) {
  2080.       ptrCheckGuard(locDatabufptr, cdatabufFilesize, databufRecord);
  2081.       Tdata0 = locDatabufptr.p->data[0];
  2082.       Tdata1 = locDatabufptr.p->data[1];
  2083.       Tdata2 = locDatabufptr.p->data[2];
  2084.       Tdata3 = locDatabufptr.p->data[3];
  2085.       Tdata32[ti    ] = Tdata0;
  2086.       Tdata32[ti + 1] = Tdata1;
  2087.       Tdata32[ti + 2] = Tdata2;
  2088.       Tdata32[ti + 3] = Tdata3;
  2089.       locDatabufptr.i = locDatabufptr.p->nextDatabuf;
  2090.       ti += 4;
  2091.     }//while
  2092.   }//if
  2093.   UintR ThashValue;
  2094.   UintR TdistrHashValue;
  2095.   ThashValue = md5_hash((Uint64*)&Tdata32[0], (UintR)regCachePtr->keylen);
  2096.   if (regCachePtr->distributionGroupIndicator == 1) {
  2097.     if (regCachePtr->distributionGroupType == 1) {
  2098.       jam();
  2099.       TdistrHashValue = (regCachePtr->distributionGroup << 6);
  2100.     } else {
  2101.       jam();
  2102.       Tdata32[0] = regCachePtr->distributionGroup;
  2103.       TdistrHashValue = md5_hash((Uint64*)&Tdata32[0], (UintR)1);
  2104.     }//if
  2105.   } else if (regCachePtr->distributionKeyIndicator == 1) {
  2106.     jam();
  2107.     TdistrHashValue = md5_hash((Uint64*)&Tdata32[0], 
  2108.                                (UintR)regCachePtr->distributionKeySize);
  2109.   } else {
  2110.     jam();
  2111.     TdistrHashValue = ThashValue;
  2112.   }//if
  2113.   thashValue = ThashValue;
  2114.   tdistrHashValue = TdistrHashValue;
  2115. }//Dbtc::hash()
  2116. /*
  2117. INIT_API_CONNECT_REC
  2118. ---------------------------
  2119. */
  2120. /* ========================================================================= */
  2121. /* =======                       INIT_API_CONNECT_REC                ======= */
  2122. /*                                                                           */
  2123. /* ========================================================================= */
  2124. void Dbtc::initApiConnectRec(Signal* signal,
  2125.                              ApiConnectRecord * const regApiPtr,
  2126.      bool releaseIndexOperations) 
  2127. {
  2128.   const TcKeyReq * const tcKeyReq = (TcKeyReq *)&signal->theData[0];
  2129.   UintR TfailureNr = cfailure_nr;
  2130.   UintR TtransCount = c_counters.ctransCount;
  2131.   UintR Ttransid0 = tcKeyReq->transId1;
  2132.   UintR Ttransid1 = tcKeyReq->transId2;
  2133.   regApiPtr->m_exec_flag = 0;
  2134.   regApiPtr->returncode = 0;
  2135.   regApiPtr->returnsignal = RS_TCKEYCONF;
  2136.   ndbassert(regApiPtr->firstTcConnect == RNIL);
  2137.   regApiPtr->firstTcConnect = RNIL;
  2138.   regApiPtr->lastTcConnect = RNIL;
  2139.   regApiPtr->globalcheckpointid = 0;
  2140.   regApiPtr->lqhkeyconfrec = 0;
  2141.   regApiPtr->lqhkeyreqrec = 0;
  2142.   regApiPtr->tckeyrec = 0;
  2143.   regApiPtr->tcindxrec = 0;
  2144.   regApiPtr->failureNr = TfailureNr;
  2145.   regApiPtr->transid[0] = Ttransid0;
  2146.   regApiPtr->transid[1] = Ttransid1;
  2147.   regApiPtr->commitAckMarker = RNIL;
  2148.   regApiPtr->buddyPtr = RNIL;
  2149.   regApiPtr->currSavePointId = 0;
  2150.   // Trigger data
  2151.   releaseFiredTriggerData(&regApiPtr->theFiredTriggers),
  2152.   // Index data
  2153.   regApiPtr->indexOpReturn = false;
  2154.   regApiPtr->noIndexOp = 0;
  2155.   if(releaseIndexOperations)
  2156.     releaseAllSeizedIndexOperations(regApiPtr);
  2157.   c_counters.ctransCount = TtransCount + 1;
  2158. }//Dbtc::initApiConnectRec()
  2159. int
  2160. Dbtc::seizeTcRecord(Signal* signal)
  2161. {
  2162.   ApiConnectRecord * const regApiPtr = apiConnectptr.p;
  2163.   TcConnectRecord *localTcConnectRecord = tcConnectRecord;
  2164.   UintR TfirstfreeTcConnect = cfirstfreeTcConnect;
  2165.   UintR TtcConnectFilesize = ctcConnectFilesize;
  2166.   tcConnectptr.i = TfirstfreeTcConnect;
  2167.   if (TfirstfreeTcConnect >= TtcConnectFilesize) {
  2168.     int place = 3;
  2169.     if (TfirstfreeTcConnect != RNIL) {
  2170.       place = 10;
  2171.     }//if
  2172.     TCKEY_abort(signal, place);
  2173.     return 1;
  2174.   }//if
  2175.   //--------------------------------------------------------------------------
  2176.   // Optimised version of ptrAss(tcConnectptr, tcConnectRecord)
  2177.   //--------------------------------------------------------------------------
  2178.   TcConnectRecord * const regTcPtr = 
  2179.                            &localTcConnectRecord[TfirstfreeTcConnect];
  2180.   UintR TconcurrentOp = c_counters.cconcurrentOp;
  2181.   UintR TlastTcConnect = regApiPtr->lastTcConnect;
  2182.   UintR TtcConnectptrIndex = tcConnectptr.i;
  2183.   TcConnectRecordPtr tmpTcConnectptr;
  2184.   cfirstfreeTcConnect = regTcPtr->nextTcConnect;
  2185.   tcConnectptr.p = regTcPtr;
  2186.   c_counters.cconcurrentOp = TconcurrentOp + 1;
  2187.   regTcPtr->prevTcConnect = TlastTcConnect;
  2188.   regTcPtr->nextTcConnect = RNIL;
  2189.   regTcPtr->accumulatingTriggerData.i = RNIL;  
  2190.   regTcPtr->accumulatingTriggerData.p = NULL;  
  2191.   regTcPtr->noFiredTriggers = 0;
  2192.   regTcPtr->noReceivedTriggers = 0;
  2193.   regTcPtr->triggerExecutionCount = 0;
  2194.   regTcPtr->triggeringOperation = RNIL;
  2195.   regTcPtr->isIndexOp = false;
  2196.   regTcPtr->indexOp = RNIL;
  2197.   regTcPtr->currentIndexId = RNIL;
  2198.   regApiPtr->lastTcConnect = TtcConnectptrIndex;
  2199.   if (TlastTcConnect == RNIL) {
  2200.     jam();
  2201.     regApiPtr->firstTcConnect = TtcConnectptrIndex;
  2202.   } else {
  2203.     tmpTcConnectptr.i = TlastTcConnect;
  2204.     jam();
  2205.     ptrCheckGuard(tmpTcConnectptr, TtcConnectFilesize, localTcConnectRecord);
  2206.     tmpTcConnectptr.p->nextTcConnect = TtcConnectptrIndex;
  2207.   }//if
  2208.   return 0;
  2209. }//Dbtc::seizeTcRecord()
  2210. int
  2211. Dbtc::seizeCacheRecord(Signal* signal)
  2212. {
  2213.   ApiConnectRecord * const regApiPtr = apiConnectptr.p;
  2214.   UintR TfirstfreeCacheRec = cfirstfreeCacheRec;
  2215.   UintR TcacheFilesize = ccacheFilesize;
  2216.   CacheRecord *localCacheRecord = cacheRecord;
  2217.   if (TfirstfreeCacheRec >= TcacheFilesize) {
  2218.     TCKEY_abort(signal, 41);
  2219.     return 1;
  2220.   }//if
  2221.   CacheRecord * const regCachePtr = &localCacheRecord[TfirstfreeCacheRec];
  2222.   regApiPtr->cachePtr = TfirstfreeCacheRec;
  2223.   cfirstfreeCacheRec = regCachePtr->nextCacheRec;
  2224.   cachePtr.i = TfirstfreeCacheRec;
  2225.   cachePtr.p = regCachePtr;
  2226. #ifdef VM_TRACE
  2227.   // This is a good place to check that resources have 
  2228.   // been properly released from CacheRecord
  2229.   ndbrequire(regCachePtr->firstKeybuf == RNIL);
  2230.   ndbrequire(regCachePtr->lastKeybuf == RNIL);
  2231. #endif
  2232.   regCachePtr->firstKeybuf = RNIL;
  2233.   regCachePtr->lastKeybuf = RNIL;
  2234.   regCachePtr->firstAttrbuf = RNIL;
  2235.   regCachePtr->lastAttrbuf = RNIL;
  2236.   regCachePtr->currReclenAi = 0;
  2237.   return 0;
  2238. }//Dbtc::seizeCacheRecord()  
  2239. /*****************************************************************************/
  2240. /*                               T C K E Y R E Q                             */
  2241. /* AFTER HAVING ESTABLISHED THE CONNECT, THE APPLICATION BLOCK SENDS AN      */
  2242. /* OPERATION REQUEST TO TC. ALL NECESSARY INFORMATION TO CARRY OUT REQUEST   */
  2243. /* IS FURNISHED IN PARAMETERS. TC STORES THIS INFORMATION AND ENQUIRES       */
  2244. /* FROM DIH ABOUT THE NODES WHICH MAY HAVE THE REQUESTED DATA                */
  2245. /*****************************************************************************/
  2246. void Dbtc::execTCKEYREQ(Signal* signal) 
  2247. {
  2248.   UintR compare_transid1, compare_transid2;
  2249.   UintR titcLenAiInTckeyreq;
  2250.   UintR TkeyLength;
  2251.   const TcKeyReq * const tcKeyReq = (TcKeyReq *)signal->getDataPtr();
  2252.   UintR Treqinfo;
  2253.   jamEntry();
  2254.   /*-------------------------------------------------------------------------
  2255.    * Common error routines are used for several signals, they need to know 
  2256.    * where to find the transaction identifier in the signal.
  2257.    *-------------------------------------------------------------------------*/
  2258.   const UintR TapiIndex = tcKeyReq->apiConnectPtr;
  2259.   const UintR TapiMaxIndex = capiConnectFilesize;
  2260.   const UintR TtabIndex = tcKeyReq->tableId;
  2261.   const UintR TtabMaxIndex = ctabrecFilesize;
  2262.   ApiConnectRecord *localApiConnectRecord = apiConnectRecord;
  2263.   ttransid_ptr = 6; 
  2264.   apiConnectptr.i = TapiIndex;
  2265.   if (TapiIndex >= TapiMaxIndex) {
  2266.     TCKEY_abort(signal, 6);
  2267.     return;
  2268.   }//if
  2269.   if (TtabIndex >= TtabMaxIndex) {
  2270.     TCKEY_abort(signal, 7);
  2271.     return;
  2272.   }//if
  2273.   Treqinfo = tcKeyReq->requestInfo;
  2274.   //--------------------------------------------------------------------------
  2275.   // Optimised version of ptrAss(tabptr, tableRecord)
  2276.   // Optimised version of ptrAss(apiConnectptr, apiConnectRecord)
  2277.   //--------------------------------------------------------------------------
  2278.   ApiConnectRecord * const regApiPtr = &localApiConnectRecord[TapiIndex];
  2279.   apiConnectptr.p = regApiPtr;
  2280.   Uint32 TstartFlag = tcKeyReq->getStartFlag(Treqinfo);
  2281.   Uint32 TexecFlag = TcKeyReq::getExecuteFlag(Treqinfo);
  2282.   bool isIndexOp = regApiPtr->isIndexOp;
  2283.   bool isIndexOpReturn = regApiPtr->indexOpReturn;
  2284.   regApiPtr->isIndexOp = false; // Reset marker
  2285.   regApiPtr->m_exec_flag |= TexecFlag;
  2286.   switch (regApiPtr->apiConnectstate) {
  2287.   case CS_CONNECTED:{
  2288.     if (TstartFlag == 1 && getAllowStartTransaction() == true){
  2289.       //---------------------------------------------------------------------
  2290.       // Initialise API connect record if transaction is started.
  2291.       //---------------------------------------------------------------------
  2292.       jam();
  2293.       initApiConnectRec(signal, regApiPtr);
  2294.       regApiPtr->m_exec_flag = TexecFlag;
  2295.     } else {
  2296.       if(getAllowStartTransaction() == true){
  2297. /*------------------------------------------------------------------
  2298.  * WE EXPECTED A START TRANSACTION. SINCE NO OPERATIONS HAVE BEEN 
  2299.  * RECEIVED WE INDICATE THIS BY SETTING FIRST_TC_CONNECT TO RNIL TO 
  2300.  * ENSURE PROPER OPERATION OF THE COMMON ABORT HANDLING.
  2301.  *-----------------------------------------------------------------*/
  2302. TCKEY_abort(signal, 0);
  2303. return;
  2304.       } else {
  2305. /**
  2306.  * getAllowStartTransaction() == false
  2307.  */
  2308. TCKEY_abort(signal, 57);
  2309. return;
  2310.       }//if
  2311.     }
  2312.   }
  2313.   break;
  2314.   case CS_STARTED:
  2315.     if(TstartFlag == 1 && regApiPtr->firstTcConnect == RNIL)
  2316.     {
  2317.       /**
  2318.        * If last operation in last transaction was a simple/dirty read
  2319.        *  it does not have to be committed or rollbacked hence,
  2320.        *  the state will be CS_STARTED
  2321.        */
  2322.       jam();
  2323.       initApiConnectRec(signal, regApiPtr);
  2324.       regApiPtr->m_exec_flag = TexecFlag;
  2325.     } else { 
  2326.       //----------------------------------------------------------------------
  2327.       // Transaction is started already. 
  2328.       // Check that the operation is on the same transaction.
  2329.       //-----------------------------------------------------------------------
  2330.       compare_transid1 = regApiPtr->transid[0] ^ tcKeyReq->transId1;
  2331.       compare_transid2 = regApiPtr->transid[1] ^ tcKeyReq->transId2;
  2332.       jam();
  2333.       compare_transid1 = compare_transid1 | compare_transid2;
  2334.       if (compare_transid1 != 0) {
  2335. TCKEY_abort(signal, 1);
  2336. return;
  2337.       }//if
  2338.     }
  2339.     break;
  2340.   case CS_ABORTING:
  2341.     if (regApiPtr->abortState == AS_IDLE) {
  2342.       if (TstartFlag == 1) {
  2343. //--------------------------------------------------------------------
  2344. // Previous transaction had been aborted and the abort was completed. 
  2345. // It is then OK to start a new transaction again.
  2346. //--------------------------------------------------------------------
  2347.         jam();
  2348.         initApiConnectRec(signal, regApiPtr);
  2349. regApiPtr->m_exec_flag = TexecFlag;
  2350.       } else if(TexecFlag) {
  2351. TCKEY_abort(signal, 59);
  2352. return;
  2353.       } else { 
  2354. //--------------------------------------------------------------------
  2355. // The current transaction was aborted successfully. 
  2356. // We will not do anything before we receive an operation 
  2357. // with a start indicator. We will ignore this signal.
  2358. //--------------------------------------------------------------------
  2359. jam();
  2360. DEBUG("Drop TCKEYREQ - apiConnectState=CS_ABORTING, ==AS_IDLE");
  2361.         return;
  2362.       }//if
  2363.     } else {
  2364.       //----------------------------------------------------------------------
  2365.       // Previous transaction is still aborting
  2366.       //----------------------------------------------------------------------
  2367.       jam();
  2368.       if (TstartFlag == 1) {
  2369. //--------------------------------------------------------------------
  2370. // If a new transaction tries to start while the old is 
  2371. // still aborting, we will report this to the starting API.
  2372. //--------------------------------------------------------------------
  2373.         TCKEY_abort(signal, 2);
  2374.         return;
  2375.       } else if(TexecFlag) {
  2376.         TCKEY_abort(signal, 59);
  2377.         return;
  2378.       }
  2379.       //----------------------------------------------------------------------
  2380.       // Ignore signals without start indicator set when aborting transaction.
  2381.       //----------------------------------------------------------------------
  2382.       DEBUG("Drop TCKEYREQ - apiConnectState=CS_ABORTING, !=AS_IDLE");
  2383.       return;
  2384.     }//if
  2385.     break;
  2386.   case CS_START_COMMITTING:
  2387.     jam();
  2388.     if(isIndexOpReturn || TcKeyReq::getExecutingTrigger(Treqinfo)){
  2389.       break;
  2390.     }
  2391.   default:
  2392.     jam();
  2393.     /*----------------------------------------------------------------------
  2394.      * IN THIS CASE THE NDBAPI IS AN UNTRUSTED ENTITY THAT HAS SENT A SIGNAL 
  2395.      * WHEN IT WAS NOT EXPECTED TO. 
  2396.      * WE MIGHT BE IN A PROCESS TO RECEIVE, PREPARE, 
  2397.      * COMMIT OR COMPLETE AND OBVIOUSLY THIS IS NOT A DESIRED EVENT.
  2398.      * WE WILL ALWAYS COMPLETE THE ABORT HANDLING BEFORE WE ALLOW 
  2399.      * ANYTHING TO HAPPEN ON THIS CONNECTION AGAIN. 
  2400.      * THUS THERE IS NO ACTION FROM THE API THAT CAN SPEED UP THIS PROCESS.
  2401.      *---------------------------------------------------------------------*/
  2402.     TCKEY_abort(signal, 55);
  2403.     return;
  2404.   }//switch
  2405.   
  2406.   TableRecordPtr localTabptr;
  2407.   localTabptr.i = TtabIndex;
  2408.   localTabptr.p = &tableRecord[TtabIndex];
  2409.   if (localTabptr.p->checkTable(tcKeyReq->tableSchemaVersion)) {
  2410.     ;
  2411.   } else {
  2412.     /*-----------------------------------------------------------------------*/
  2413.     /* THE API IS WORKING WITH AN OLD SCHEMA VERSION. IT NEEDS REPLACEMENT.  */
  2414.     /* COULD ALSO BE THAT THE TABLE IS NOT DEFINED.                          */
  2415.     /*-----------------------------------------------------------------------*/
  2416.     TCKEY_abort(signal, 8);
  2417.     return;
  2418.   }//if
  2419.   
  2420.   //-------------------------------------------------------------------------
  2421.   // Error Insertion for testing purposes. Test to see what happens when no
  2422.   // more TC records available.
  2423.   //-------------------------------------------------------------------------
  2424.   if (ERROR_INSERTED(8032)) {
  2425.     TCKEY_abort(signal, 3);
  2426.     return;
  2427.   }//if
  2428.   
  2429.   if (seizeTcRecord(signal) != 0) {
  2430.     return;
  2431.   }//if
  2432.   
  2433.   if (seizeCacheRecord(signal) != 0) {
  2434.     return;
  2435.   }//if
  2436.   
  2437.   TcConnectRecord * const regTcPtr = tcConnectptr.p;
  2438.   CacheRecord * const regCachePtr = cachePtr.p;
  2439.   /*
  2440.     INIT_TC_CONNECT_REC 
  2441.     -------------------------
  2442.   */
  2443.   /* ---------------------------------------------------------------------- */
  2444.   /* -------     INIT OPERATION RECORD WITH SIGNAL DATA AND RNILS   ------- */
  2445.   /*                                                                        */
  2446.   /* ---------------------------------------------------------------------- */
  2447.   UintR TapiVersionNo = tcKeyReq->getAPIVersion(tcKeyReq->attrLen);
  2448.   UintR Tlqhkeyreqrec = regApiPtr->lqhkeyreqrec;
  2449.   regApiPtr->lqhkeyreqrec = Tlqhkeyreqrec + 1;
  2450.   regCachePtr->apiVersionNo = TapiVersionNo;
  2451.   UintR TapiConnectptrIndex = apiConnectptr.i;
  2452.   UintR TsenderData = tcKeyReq->senderData;
  2453.   UintR TattrLen = tcKeyReq->getAttrinfoLen(tcKeyReq->attrLen);
  2454.   UintR TattrinfoCount = c_counters.cattrinfoCount;
  2455.   regTcPtr->apiConnect = TapiConnectptrIndex;
  2456.   regTcPtr->clientData = TsenderData;
  2457.   regTcPtr->commitAckMarker = RNIL;
  2458.   regTcPtr->isIndexOp = isIndexOp;
  2459.   regTcPtr->indexOp = regApiPtr->executingIndexOp;
  2460.   regTcPtr->savePointId = regApiPtr->currSavePointId;
  2461.   regApiPtr->executingIndexOp = RNIL;
  2462.   if (TcKeyReq::getExecutingTrigger(Treqinfo)) {
  2463.     // Save the TcOperationPtr for fireing operation
  2464.     regTcPtr->triggeringOperation = TsenderData;
  2465.   }
  2466.   if (TexecFlag){
  2467.     Uint32 currSPId = regApiPtr->currSavePointId;
  2468.     regApiPtr->currSavePointId = ++currSPId;
  2469.   }
  2470.   regCachePtr->attrlength = TattrLen;
  2471.   c_counters.cattrinfoCount = TattrinfoCount + TattrLen;
  2472.   UintR TtabptrIndex = localTabptr.i;
  2473.   UintR TtableSchemaVersion = tcKeyReq->tableSchemaVersion;
  2474.   Uint8 TOperationType = tcKeyReq->getOperationType(Treqinfo);
  2475.   regCachePtr->tableref = TtabptrIndex;
  2476.   regCachePtr->schemaVersion = TtableSchemaVersion;
  2477.   regTcPtr->operation = TOperationType;
  2478.   Uint8 TSimpleFlag         = tcKeyReq->getSimpleFlag(Treqinfo);
  2479.   Uint8 TDirtyFlag          = tcKeyReq->getDirtyFlag(Treqinfo);
  2480.   Uint8 TInterpretedFlag    = tcKeyReq->getInterpretedFlag(Treqinfo);
  2481.   Uint8 TDistrGroupFlag     = tcKeyReq->getDistributionGroupFlag(Treqinfo);
  2482.   Uint8 TDistrGroupTypeFlag = tcKeyReq->getDistributionGroupTypeFlag(Treqinfo);
  2483.   Uint8 TDistrKeyFlag       = tcKeyReq->getDistributionKeyFlag(Treqinfo);
  2484.   Uint8 TexecuteFlag        = TexecFlag;
  2485.   
  2486.   regCachePtr->opSimple = TSimpleFlag;
  2487.   regCachePtr->opExec   = TInterpretedFlag;
  2488.   regTcPtr->dirtyOp  = TDirtyFlag;
  2489.   regCachePtr->distributionGroupIndicator = TDistrGroupFlag;
  2490.   regCachePtr->distributionGroupType      = TDistrGroupTypeFlag;
  2491.   regCachePtr->distributionKeyIndicator   = TDistrKeyFlag;
  2492.   //-------------------------------------------------------------
  2493.   // The next step is to read the upto three conditional words.
  2494.   //-------------------------------------------------------------
  2495.   Uint32 TkeyIndex;
  2496.   Uint32* TOptionalDataPtr = (Uint32*)&tcKeyReq->scanInfo;
  2497.   {
  2498.     Uint32  TDistrGHIndex    = tcKeyReq->getScanIndFlag(Treqinfo);
  2499.     Uint32  TDistrKeyIndex   = TDistrGHIndex + TDistrGroupFlag;
  2500.     Uint32 TscanNode = tcKeyReq->getTakeOverScanNode(TOptionalDataPtr[0]);
  2501.     Uint32 TscanInfo = tcKeyReq->getTakeOverScanInfo(TOptionalDataPtr[0]);
  2502.     regCachePtr->scanTakeOverInd = TDistrGHIndex;
  2503.     regCachePtr->scanNode = TscanNode;
  2504.     regCachePtr->scanInfo = TscanInfo;
  2505.     regCachePtr->distributionGroup   = TOptionalDataPtr[TDistrGHIndex];
  2506.     regCachePtr->distributionKeySize = TOptionalDataPtr[TDistrKeyIndex];
  2507.     TkeyIndex = TDistrKeyIndex + TDistrKeyFlag;
  2508.   }
  2509.   Uint32* TkeyDataPtr = &TOptionalDataPtr[TkeyIndex];
  2510.   UintR Tdata1 = TkeyDataPtr[0];
  2511.   UintR Tdata2 = TkeyDataPtr[1];
  2512.   UintR Tdata3 = TkeyDataPtr[2];
  2513.   UintR Tdata4 = TkeyDataPtr[3];
  2514.   UintR Tdata5;
  2515.   regCachePtr->keydata[0] = Tdata1;
  2516.   regCachePtr->keydata[1] = Tdata2;
  2517.   regCachePtr->keydata[2] = Tdata3;
  2518.   regCachePtr->keydata[3] = Tdata4;
  2519.   TkeyLength = tcKeyReq->getKeyLength(Treqinfo);
  2520.   Uint32 TAIDataIndex;
  2521.   if (TkeyLength > 8) {
  2522.     TAIDataIndex = TkeyIndex + 8;
  2523.   } else {
  2524.     if (TkeyLength == 0) {
  2525.       TCKEY_abort(signal, 4);
  2526.       return;
  2527.     }//if
  2528.     TAIDataIndex = TkeyIndex + TkeyLength;
  2529.   }//if
  2530.   Uint32* TAIDataPtr = &TOptionalDataPtr[TAIDataIndex];
  2531.   titcLenAiInTckeyreq = tcKeyReq->getAIInTcKeyReq(Treqinfo);
  2532.   regCachePtr->keylen = TkeyLength;
  2533.   regCachePtr->lenAiInTckeyreq = titcLenAiInTckeyreq;
  2534.   regCachePtr->currReclenAi = titcLenAiInTckeyreq;
  2535.   Tdata1 = TAIDataPtr[0];
  2536.   Tdata2 = TAIDataPtr[1];
  2537.   Tdata3 = TAIDataPtr[2];
  2538.   Tdata4 = TAIDataPtr[3];
  2539.   Tdata5 = TAIDataPtr[4];
  2540.   regCachePtr->attrinfo0     = Tdata1;
  2541.   regCachePtr->attrinfo15[0] = Tdata2;
  2542.   regCachePtr->attrinfo15[1] = Tdata3;
  2543.   regCachePtr->attrinfo15[2] = Tdata4;
  2544.   regCachePtr->attrinfo15[3] = Tdata5;
  2545.   if (TOperationType == ZREAD) {
  2546.     Uint32 TreadCount = c_counters.creadCount;
  2547.     jam();
  2548.     regCachePtr->opLock = 0;
  2549.     c_counters.creadCount = TreadCount + 1;
  2550.   } else if(TOperationType == ZREAD_EX){
  2551.     Uint32 TreadCount = c_counters.creadCount;
  2552.     jam();
  2553.     TOperationType = ZREAD;
  2554.     regTcPtr->operation = ZREAD;
  2555.     regCachePtr->opLock = ZUPDATE;
  2556.     c_counters.creadCount = TreadCount + 1;
  2557.   } else {
  2558.     if(regApiPtr->commitAckMarker == RNIL){
  2559.       jam();
  2560.       CommitAckMarkerPtr tmp;
  2561.       if(!m_commitAckMarkerHash.seize(tmp)){
  2562.         TCKEY_abort(signal, 56);
  2563.         return;
  2564.       } else {
  2565.         regTcPtr->commitAckMarker = tmp.i;
  2566.         regApiPtr->commitAckMarker = tmp.i;
  2567.         tmp.p->transid1      = tcKeyReq->transId1;
  2568.         tmp.p->transid2      = tcKeyReq->transId2;
  2569.         tmp.p->apiNodeId     = refToNode(regApiPtr->ndbapiBlockref);
  2570.         tmp.p->apiConnectPtr = TapiIndex;
  2571.         tmp.p->noOfLqhs      = 0;
  2572.         m_commitAckMarkerHash.add(tmp);
  2573.       }
  2574.     }
  2575.     
  2576.     UintR TwriteCount = c_counters.cwriteCount;
  2577.     UintR Toperationsize = coperationsize;
  2578.     /* -------------------------------------------------------------------- 
  2579.      *   THIS IS A TEMPORARY TABLE, DON'T UPDATE coperationsize. 
  2580.      *   THIS VARIABLE CONTROLS THE INTERVAL BETWEEN LCP'S AND 
  2581.      *   TEMP TABLES DON'T PARTICIPATE.
  2582.      * -------------------------------------------------------------------- */
  2583.     if (localTabptr.p->storedTable) {
  2584.       coperationsize = ((Toperationsize + TattrLen) + TkeyLength) + 17;
  2585.     }
  2586.     c_counters.cwriteCount = TwriteCount + 1;
  2587.     switch (TOperationType) {
  2588.     case ZUPDATE:
  2589.       jam();
  2590.       if (TattrLen == 0) {
  2591.         //TCKEY_abort(signal, 5);
  2592.         //return;
  2593.       }//if
  2594.       /*---------------------------------------------------------------------*/
  2595.       // The missing break is intentional since we also want to set the opLock 
  2596.       // variable also for updates
  2597.       /*---------------------------------------------------------------------*/
  2598.     case ZINSERT:
  2599.     case ZDELETE:
  2600.       jam();      
  2601.       regCachePtr->opLock = TOperationType;
  2602.       break;
  2603.     case ZWRITE:
  2604.       jam();
  2605.       // A write operation is originally an insert operation.
  2606.       regCachePtr->opLock = ZINSERT;  
  2607.       break;
  2608.     default:
  2609.       TCKEY_abort(signal, 9);
  2610.       return;
  2611.     }//switch
  2612.   }//if
  2613.   
  2614.   Uint32 TabortOption = tcKeyReq->getAbortOption(Treqinfo);
  2615.   regTcPtr->m_execAbortOption = TabortOption;
  2616.   
  2617.   /*-------------------------------------------------------------------------
  2618.    * Check error handling per operation
  2619.    * If CommitFlag is set state accordingly and check for early abort
  2620.    *------------------------------------------------------------------------*/
  2621.   if (tcKeyReq->getCommitFlag(Treqinfo) == 1) {
  2622.     ndbrequire(TexecuteFlag);
  2623.     regApiPtr->apiConnectstate = CS_REC_COMMITTING;
  2624.   } else {
  2625.     /* ---------------------------------------------------------------------
  2626.      *       PREPARE TRANSACTION IS NOT IMPLEMENTED YET.
  2627.      * ---------------------------------------------------------------------
  2628.      *       ELSIF (TREQINFO => 3) (*) 1 = 1 THEN                
  2629.      * IF PREPARE TRANSACTION THEN
  2630.      *   API_CONNECTPTR:API_CONNECTSTATE = REC_PREPARING
  2631.      * SET STATE TO PREPARING
  2632.      * --------------------------------------------------------------------- */
  2633.     if (regApiPtr->apiConnectstate == CS_START_COMMITTING) {
  2634.       jam();
  2635.       // Trigger execution at commit
  2636.       regApiPtr->apiConnectstate = CS_REC_COMMITTING;
  2637.     } else {
  2638.       jam();
  2639.       regApiPtr->apiConnectstate = CS_RECEIVING;
  2640.     }//if
  2641.   }//if
  2642.   if (TkeyLength <= 4) {
  2643.     tckeyreq050Lab(signal);
  2644.     return;
  2645.   } else {
  2646.     if (cfirstfreeDatabuf != RNIL) {
  2647.       jam();
  2648.       linkKeybuf(signal);
  2649.       Tdata1 = TkeyDataPtr[4];
  2650.       Tdata2 = TkeyDataPtr[5];
  2651.       Tdata3 = TkeyDataPtr[6];
  2652.       Tdata4 = TkeyDataPtr[7];
  2653.       DatabufRecord * const regDataPtr = databufptr.p;
  2654.       regDataPtr->data[0] = Tdata1;
  2655.       regDataPtr->data[1] = Tdata2;
  2656.       regDataPtr->data[2] = Tdata3;
  2657.       regDataPtr->data[3] = Tdata4;
  2658.     } else {
  2659.       jam();
  2660.       seizeDatabuferrorLab(signal);
  2661.       return;
  2662.     }//if
  2663.     if (TkeyLength <= 8) {
  2664.       jam();
  2665.       tckeyreq050Lab(signal);
  2666.       return;
  2667.     } else {
  2668.       jam();
  2669.       /* --------------------------------------------------------------------
  2670.        * THE TCKEYREQ DIDN'T CONTAIN ALL KEY DATA, 
  2671.        * SAVE STATE AND WAIT FOR KEYINFO 
  2672.        * --------------------------------------------------------------------*/
  2673.       setApiConTimer(apiConnectptr.i, ctcTimer, __LINE__);
  2674.       regCachePtr->save1 = 8;
  2675.       regTcPtr->tcConnectstate = OS_WAIT_KEYINFO;
  2676.       return;
  2677.     }//if
  2678.   }//if
  2679.   return;
  2680. }//Dbtc::execTCKEYREQ()
  2681. void Dbtc::tckeyreq050Lab(Signal* signal) 
  2682. {
  2683.   UintR tnoOfBackup;
  2684.   UintR tnoOfStandby;
  2685.   UintR tnodeinfo;
  2686.   hash(signal); /* NOW IT IS TIME TO CALCULATE THE HASH VALUE*/
  2687.   CacheRecord * const regCachePtr = cachePtr.p;
  2688.   TcConnectRecord * const regTcPtr = tcConnectptr.p;
  2689.   ApiConnectRecord * const regApiPtr = apiConnectptr.p;
  2690.   UintR TtcTimer = ctcTimer;
  2691.   UintR ThashValue = thashValue;
  2692.   UintR TdistrHashValue = tdistrHashValue;
  2693.   UintR TdihConnectptr = regTcPtr->dihConnectptr;
  2694.   UintR Ttableref = regCachePtr->tableref;
  2695.   
  2696.   TableRecordPtr localTabptr;
  2697.   localTabptr.i = Ttableref;
  2698.   localTabptr.p = &tableRecord[localTabptr.i];
  2699.   Uint32 schemaVersion = regCachePtr->schemaVersion;
  2700.   if(localTabptr.p->checkTable(schemaVersion)){
  2701.     ;
  2702.   } else {
  2703.     terrorCode = localTabptr.p->getErrorCode(schemaVersion);
  2704.     TCKEY_abort(signal, 58);
  2705.     return;
  2706.   }
  2707.   
  2708.   setApiConTimer(apiConnectptr.i, TtcTimer, __LINE__);
  2709.   regCachePtr->hashValue = ThashValue;
  2710.   signal->theData[0] = TdihConnectptr;
  2711.   signal->theData[1] = Ttableref;
  2712.   signal->theData[2] = TdistrHashValue;
  2713.   /*-------------------------------------------------------------*/
  2714.   /* FOR EFFICIENCY REASONS WE AVOID THE SIGNAL SENDING HERE AND */
  2715.   /* PROCEED IMMEDIATELY TO DIH. IN MULTI-THREADED VERSIONS WE   */
  2716.   /* HAVE TO INSERT A MUTEX ON DIH TO ENSURE PROPER OPERATION.   */
  2717.   /* SINCE THIS SIGNAL AND DIVERIFYREQ ARE THE ONLY SIGNALS SENT */
  2718.   /* TO DIH IN TRAFFIC IT SHOULD BE OK (3% OF THE EXECUTION TIME */
  2719.   /* IS SPENT IN DIH AND EVEN LESS IN REPLICATED NDB.            */
  2720.   /*-------------------------------------------------------------*/
  2721.   EXECUTE_DIRECT(DBDIH, GSN_DIGETNODESREQ, signal, 3);
  2722.   UintR TerrorIndicator = signal->theData[0];
  2723.   jamEntry();
  2724.   if (TerrorIndicator != 0) {
  2725.     execDIGETNODESREF(signal);
  2726.     return;
  2727.   }
  2728.   /****************>>*/
  2729.   /* DIGETNODESCONF >*/
  2730.   /* ***************>*/
  2731.   UintR Tdata1 = signal->theData[1];
  2732.   UintR Tdata2 = signal->theData[2];
  2733.   UintR Tdata3 = signal->theData[3];
  2734.   UintR Tdata4 = signal->theData[4];
  2735.   UintR Tdata5 = signal->theData[5];
  2736.   UintR Tdata6 = signal->theData[6];
  2737.   regCachePtr->fragmentid = Tdata1;
  2738.   tnodeinfo = Tdata2;
  2739.   regTcPtr->tcNodedata[0] = Tdata3;
  2740.   regTcPtr->tcNodedata[1] = Tdata4;
  2741.   regTcPtr->tcNodedata[2] = Tdata5;
  2742.   regTcPtr->tcNodedata[3] = Tdata6;
  2743.   Uint8 Toperation = regTcPtr->operation;
  2744.   Uint8 Tdirty = regTcPtr->dirtyOp;
  2745.   tnoOfBackup = tnodeinfo & 3;
  2746.   tnoOfStandby = (tnodeinfo >> 8) & 3;
  2747.  
  2748.   regCachePtr->distributionKey = (tnodeinfo >> 16) & 255;
  2749.   if (Toperation == ZREAD) {
  2750.     if (Tdirty == 1) {
  2751.       jam();
  2752.       /*-------------------------------------------------------------*/
  2753.       /*       A SIMPLE READ CAN SELECT ANY OF THE PRIMARY AND       */
  2754.       /*       BACKUP NODES TO READ. WE WILL TRY TO SELECT THIS      */
  2755.       /*       NODE IF POSSIBLE TO AVOID UNNECESSARY COMMUNICATION   */
  2756.       /*       WITH SIMPLE READS.                                    */
  2757.       /*-------------------------------------------------------------*/
  2758.       arrGuard(tnoOfBackup, 4);
  2759.       UintR Tindex;
  2760.       UintR TownNode = cownNodeid;
  2761.       for (Tindex = 1; Tindex <= tnoOfBackup; Tindex++) {
  2762.         UintR Tnode = regTcPtr->tcNodedata[Tindex];
  2763.         jam();
  2764.         if (Tnode == TownNode) {
  2765.           jam();
  2766.           regTcPtr->tcNodedata[0] = Tnode;
  2767.         }//if
  2768.       }//for
  2769.       if(ERROR_INSERTED(8048) || ERROR_INSERTED(8049))
  2770.       {
  2771. for (Tindex = 0; Tindex <= tnoOfBackup; Tindex++) 
  2772. {
  2773.   UintR Tnode = regTcPtr->tcNodedata[Tindex];
  2774.   jam();
  2775.   if (Tnode != TownNode) {
  2776.     jam();
  2777.     regTcPtr->tcNodedata[0] = Tnode;
  2778.     ndbout_c("Choosing %d", Tnode);
  2779.   }//if
  2780. }//for
  2781.       }
  2782.     }//if
  2783.     jam();
  2784.     regTcPtr->lastReplicaNo = 0;
  2785.     regTcPtr->noOfNodes = 1;
  2786.   } else {
  2787.     UintR TlastReplicaNo;
  2788.     jam();
  2789.     TlastReplicaNo = tnoOfBackup + tnoOfStandby;
  2790.     regTcPtr->lastReplicaNo = (Uint8)TlastReplicaNo;
  2791.     regTcPtr->noOfNodes = (Uint8)(TlastReplicaNo + 1);
  2792.   }//if
  2793.   if (regCachePtr->lenAiInTckeyreq == regCachePtr->attrlength) {
  2794.     /****************************************************************>*/
  2795.     /* HERE WE HAVE FOUND THAT THE LAST SIGNAL BELONGING TO THIS      */
  2796.     /* OPERATION HAVE BEEN RECEIVED. THIS MEANS THAT WE CAN NOW REUSE */
  2797.     /* THE API CONNECT RECORD. HOWEVER IF PREPARE OR COMMIT HAVE BEEN */
  2798.     /* RECEIVED THEN IT IS NOT ALLOWED TO RECEIVE ANY FURTHER         */
  2799.     /* OPERATIONS. WE KNOW THAT WE WILL WAIT FOR DICT NEXT. IT IS NOT */
  2800.     /* POSSIBLE FOR THE TC CONNECTION TO BE READY YET.                */
  2801.     /****************************************************************>*/
  2802.     switch (regApiPtr->apiConnectstate) {
  2803.     case CS_RECEIVING:
  2804.       jam();
  2805.       regApiPtr->apiConnectstate = CS_STARTED;
  2806.       break;
  2807.     case CS_REC_COMMITTING:
  2808.       jam();
  2809.       regApiPtr->apiConnectstate = CS_START_COMMITTING;
  2810.       break;
  2811.     default:
  2812.       jam();
  2813.       systemErrorLab(signal);
  2814.       return;
  2815.     }//switch
  2816.     attrinfoDihReceivedLab(signal);
  2817.     return;
  2818.   } else {
  2819.     if (regCachePtr->lenAiInTckeyreq < regCachePtr->attrlength) {
  2820.       TtcTimer = ctcTimer;
  2821.       jam();
  2822.       setApiConTimer(apiConnectptr.i, TtcTimer, __LINE__);
  2823.       regTcPtr->tcConnectstate = OS_WAIT_ATTR;
  2824.       return;
  2825.     } else {
  2826.       TCKEY_abort(signal, 11);
  2827.       return;
  2828.     }//if
  2829.   }//if
  2830.   return;
  2831. }//Dbtc::tckeyreq050Lab()
  2832. void Dbtc::attrinfoDihReceivedLab(Signal* signal) 
  2833. {
  2834.   CacheRecord * const regCachePtr = cachePtr.p;
  2835.   TcConnectRecord * const regTcPtr = tcConnectptr.p;
  2836.   Uint16 Tnode = regTcPtr->tcNodedata[0];
  2837.   Uint16 TscanTakeOverInd = regCachePtr->scanTakeOverInd;
  2838.   Uint16 TscanNode = regCachePtr->scanNode;
  2839.   TableRecordPtr localTabptr;
  2840.   localTabptr.i = regCachePtr->tableref;
  2841.   localTabptr.p = &tableRecord[localTabptr.i];
  2842.   if(localTabptr.p->checkTable(regCachePtr->schemaVersion)){
  2843.     ;
  2844.   } else {
  2845.     terrorCode = localTabptr.p->getErrorCode(regCachePtr->schemaVersion);
  2846.     TCKEY_abort(signal, 58);
  2847.     return;
  2848.   }
  2849.   if ((TscanTakeOverInd == 1) &&
  2850.       (Tnode != TscanNode)) {
  2851.     TCKEY_abort(signal, 15);
  2852.     return;
  2853.   }//if
  2854.   arrGuard(Tnode, MAX_NDB_NODES);
  2855.   packLqhkeyreq(signal, calcLqhBlockRef(Tnode));
  2856. }//Dbtc::attrinfoDihReceivedLab()
  2857. void Dbtc::packLqhkeyreq(Signal* signal,
  2858.                          BlockReference TBRef) 
  2859. {
  2860.   CacheRecord * const regCachePtr = cachePtr.p;
  2861.   UintR Tkeylen = regCachePtr->keylen;
  2862.   UintR TfirstAttrbuf = regCachePtr->firstAttrbuf;
  2863.   sendlqhkeyreq(signal, TBRef);
  2864.   if (Tkeylen > 4) {
  2865.     packKeyData000Lab(signal, TBRef, Tkeylen - 4);
  2866.     releaseKeys();
  2867.   }//if
  2868.   packLqhkeyreq040Lab(signal,
  2869.                       TfirstAttrbuf,
  2870.                       TBRef);
  2871. }//Dbtc::packLqhkeyreq()
  2872. void Dbtc::sendlqhkeyreq(Signal* signal,
  2873.                          BlockReference TBRef) 
  2874. {
  2875.   UintR tslrAttrLen;
  2876.   UintR Tdata10;
  2877.   TcConnectRecord * const regTcPtr = tcConnectptr.p;
  2878.   ApiConnectRecord * const regApiPtr = apiConnectptr.p;
  2879.   CacheRecord * const regCachePtr = cachePtr.p;
  2880. #ifdef ERROR_INSERT
  2881.   if (ERROR_INSERTED(8002)) {
  2882.     systemErrorLab(signal);
  2883.   }//if
  2884.   if (ERROR_INSERTED(8007)) {
  2885.     if (apiConnectptr.p->apiConnectstate == CS_STARTED) {
  2886.       CLEAR_ERROR_INSERT_VALUE;
  2887.       return;
  2888.     }//if
  2889.   }//if
  2890.   if (ERROR_INSERTED(8008)) {
  2891.     if (apiConnectptr.p->apiConnectstate == CS_START_COMMITTING) {
  2892.       CLEAR_ERROR_INSERT_VALUE;
  2893.       return;
  2894.     }//if
  2895.   }//if
  2896.   if (ERROR_INSERTED(8009)) {
  2897.     if (apiConnectptr.p->apiConnectstate == CS_STARTED) {
  2898.       return;
  2899.     }//if
  2900.   }//if
  2901.   if (ERROR_INSERTED(8010)) {
  2902.     if (apiConnectptr.p->apiConnectstate == CS_START_COMMITTING) {
  2903.       return;
  2904.     }//if
  2905.   }//if
  2906. #endif
  2907.   tslrAttrLen = 0;
  2908.   LqhKeyReq::setAttrLen(tslrAttrLen, regCachePtr->attrlength);
  2909.   /* ---------------------------------------------------------------------- */
  2910.   // Bit16 == 0 since StoredProcedures are not yet supported.
  2911.   /* ---------------------------------------------------------------------- */
  2912.   LqhKeyReq::setDistributionKey(tslrAttrLen, regCachePtr->distributionKey);
  2913.   LqhKeyReq::setScanTakeOverFlag(tslrAttrLen, regCachePtr->scanTakeOverInd);
  2914.   Tdata10 = 0;
  2915.   LqhKeyReq::setKeyLen(Tdata10, regCachePtr->keylen);
  2916.   LqhKeyReq::setLastReplicaNo(Tdata10, regTcPtr->lastReplicaNo);
  2917.   LqhKeyReq::setLockType(Tdata10, regCachePtr->opLock);
  2918.   /* ---------------------------------------------------------------------- */
  2919.   // Indicate Application Reference is present in bit 15
  2920.   /* ---------------------------------------------------------------------- */
  2921.   LqhKeyReq::setApplicationAddressFlag(Tdata10, 1);
  2922.   LqhKeyReq::setDirtyFlag(Tdata10, regTcPtr->dirtyOp);
  2923.   LqhKeyReq::setInterpretedFlag(Tdata10, regCachePtr->opExec);
  2924.   LqhKeyReq::setSimpleFlag(Tdata10, regCachePtr->opSimple);
  2925.   LqhKeyReq::setOperation(Tdata10, regTcPtr->operation);
  2926.   /* ----------------------------------------------------------------------- 
  2927.    * Sequential Number of first LQH = 0, bit 22-23                           
  2928.    * IF ATTRIBUTE INFORMATION IS SENT IN TCKEYREQ,
  2929.    * IT IS ALSO SENT IN LQHKEYREQ
  2930.    * ----------------------------------------------------------------------- */
  2931.   LqhKeyReq::setAIInLqhKeyReq(Tdata10, regCachePtr->lenAiInTckeyreq);
  2932.   /* -----------------------------------------------------------------------
  2933.    * Bit 27 == 0 since TC record is the same as the client record.
  2934.    * Bit 28 == 0 since readLenAi can only be set after reading in LQH.
  2935.    * ----------------------------------------------------------------------- */
  2936.   //LqhKeyReq::setAPIVersion(Tdata10, regCachePtr->apiVersionNo);
  2937.   Uint32 commitAckMarker = regTcPtr->commitAckMarker;
  2938.   if(commitAckMarker != RNIL){
  2939.     jam();
  2940.     
  2941.     LqhKeyReq::setMarkerFlag(Tdata10, 1);
  2942.     CommitAckMarker * tmp;
  2943.     tmp = m_commitAckMarkerHash.getPtr(commitAckMarker);
  2944.     
  2945.     /**
  2946.      * Populate LQH array
  2947.      */
  2948.     const Uint32 noOfLqhs = regTcPtr->noOfNodes;
  2949.     tmp->noOfLqhs = noOfLqhs;
  2950.     for(Uint32 i = 0; i<noOfLqhs; i++){
  2951.       tmp->lqhNodeId[i] = regTcPtr->tcNodedata[i];
  2952.     }
  2953.   }
  2954.   
  2955.   /* ************************************************************> */
  2956.   /* NO READ LENGTH SENT FROM TC. SEQUENTIAL NUMBER IS 1 AND IT    */
  2957.   /* IS SENT TO A PRIMARY NODE.                                    */
  2958.   /* ************************************************************> */
  2959.   UintR sig0, sig1, sig2, sig3, sig4, sig5, sig6;
  2960.   LqhKeyReq * const lqhKeyReq = (LqhKeyReq *)signal->getDataPtrSend();
  2961.   sig0 = tcConnectptr.i;
  2962.   sig2 = regCachePtr->hashValue;
  2963.   sig4 = cownref;
  2964.   sig5 = regTcPtr->savePointId;
  2965.   lqhKeyReq->clientConnectPtr = sig0;
  2966.   lqhKeyReq->attrLen = tslrAttrLen;
  2967.   lqhKeyReq->hashValue = sig2;
  2968.   lqhKeyReq->requestInfo = Tdata10;
  2969.   lqhKeyReq->tcBlockref = sig4;
  2970.   lqhKeyReq->savePointId = sig5;
  2971.   sig0 = regCachePtr->tableref + ((regCachePtr->schemaVersion << 16) & 0xFFFF0000);
  2972.   sig1 = regCachePtr->fragmentid + (regTcPtr->tcNodedata[1] << 16);
  2973.   sig2 = regApiPtr->transid[0];
  2974.   sig3 = regApiPtr->transid[1];
  2975.   sig4 = regApiPtr->ndbapiBlockref;
  2976.   sig5 = regTcPtr->clientData;
  2977.   sig6 = regCachePtr->scanInfo;
  2978.   lqhKeyReq->tableSchemaVersion = sig0;
  2979.   lqhKeyReq->fragmentData = sig1;
  2980.   lqhKeyReq->transId1 = sig2;
  2981.   lqhKeyReq->transId2 = sig3;
  2982.   lqhKeyReq->scanInfo = sig6;
  2983.   lqhKeyReq->variableData[0] = sig4;
  2984.   lqhKeyReq->variableData[1] = sig5;
  2985.   UintR nextPos = 2;
  2986.   if (regTcPtr->lastReplicaNo > 1) {
  2987.     sig0 = (UintR)regTcPtr->tcNodedata[2] +
  2988.            (UintR)(regTcPtr->tcNodedata[3] << 16);
  2989.     lqhKeyReq->variableData[nextPos] = sig0;
  2990.     nextPos++;
  2991.   }//if
  2992.   sig0 = regCachePtr->keydata[0];
  2993.   sig1 = regCachePtr->keydata[1];
  2994.   sig2 = regCachePtr->keydata[2];
  2995.   sig3 = regCachePtr->keydata[3];
  2996.   UintR Tkeylen = regCachePtr->keylen;
  2997.   lqhKeyReq->variableData[nextPos + 0] = sig0;