short ExExeUtilLongRunningTcb::finalizeDoLongRunning() { // Close the statements Lng32 rc = cliInterface()->prepareAndExecRowsEpilogue(); NADELETE(initialOutputVarPtrList_, Queue, getHeap()); NADELETE(continuingOutputVarPtrList_, Queue, getHeap()); NADELETEBASIC(lruStmtAndPartInfo_, getHeap()); NADELETEBASIC(lruStmtWithCKAndPartInfo_, getHeap()); // if this is an ESP, deallocate transaction CliGlobals *cliGlobals = GetCliGlobals(); if (cliGlobals->isESPProcess()) { NADELETEBASIC(currTransaction_, getHeap()); currTransaction_ = NULL; } return 0; }
NABoolean isParentQueryCanceled() { NABoolean isCanceled = FALSE; CliGlobals *cliGlobals = GetCliGlobals(); StatsGlobals *statsGlobals = cliGlobals->getStatsGlobals(); const char *parentQid = CmpCommon::context()->sqlSession()->getParentQid(); if (statsGlobals && parentQid) { short savedPriority, savedStopMode; statsGlobals->getStatsSemaphore(cliGlobals->getSemId(), cliGlobals->myPin(), savedPriority, savedStopMode, FALSE /*shouldTimeout*/); StmtStats *ss = statsGlobals->getMasterStmtStats(parentQid, strlen(parentQid), RtsQueryId::ANY_QUERY_); if (ss) { ExMasterStats *masterStats = ss->getMasterStats(); if (masterStats && masterStats->getCanceledTime() != -1) isCanceled = TRUE; } statsGlobals->releaseStatsSemaphore(cliGlobals->getSemId(), cliGlobals->myPin(), savedPriority, savedStopMode); } return isCanceled; }
_callable void removeProcess() { CliGlobals *cliGlobals = GetCliGlobals(); StatsGlobals *statsGlobals = cliGlobals->getStatsGlobals(); if (statsGlobals != NULL) { int error = statsGlobals->getStatsSemaphore(cliGlobals->getSemId(), cliGlobals->myPin()); if (error == 0) { statsGlobals->removeProcess(cliGlobals->myPin()); statsGlobals->releaseStatsSemaphore(cliGlobals->getSemId(), cliGlobals->myPin()); statsGlobals->logProcessDeath(cliGlobals->myCpu(), cliGlobals->myPin(), "Normal process death"); } else if (error == 4011) { // BINSEM_LOCK_ timed out. Halt the CPU PROCESSOR_HALT_ (SQL_FS_INTERNAL_ERROR); } } }
SQL_QFO_FUNCTION_ATTRIBUTES short Sql_Qfo_Close(short quasi_file_number) { CliGlobals *cliGlobals; if (QfoRevealSegs(cliGlobals) != 0) return 0; cliGlobals->setLogEmsEvents(FALSE); jmp_buf jmpBuf; cliGlobals->setJmpBufPtr(&jmpBuf); Int32 jmpRc = setjmp(jmpBuf); if (jmpRc) { cliGlobals->setLogEmsEvents(TRUE); QfoHideSegs(cliGlobals); return 0; } QuasiFileManager *quasiFileManager = cliGlobals->getQuasiFileManager(); quasiFileManager->closeQuasiFile(quasi_file_number); cliGlobals->setLogEmsEvents(TRUE); QfoHideSegs(cliGlobals); return 0; }
SQL_QFO_FUNCTION_ATTRIBUTES short Sql_Qfo_IOComp(short quasi_file_number /*in*/, Lng32 *tag /*out*/, unsigned short *waitmask /*out*/, short userstop /*in*/) { short retVal, feError = FEOK; RETCODE retcode; QuasiFileManager *quasiFileManager; *waitmask = LDONE; CliGlobals *cliGlobals; if (QfoRevealSegs(cliGlobals) != 0) return FEBADPARMVALUE; jmp_buf jmpBuf; short oldStop; oldStop = SETSTOP(1); cliGlobals->setJmpBufPtr(&jmpBuf); Int32 jmpRc = setjmp(jmpBuf); if (jmpRc) { QfoHideSegs(cliGlobals); SETSTOP(oldStop); return FEBADPARMVALUE; // longjmp not associated with statement } quasiFileManager = cliGlobals->getQuasiFileManager(); if (quasiFileManager->getPendingNowaitOps() > 0) retcode = quasiFileManager->awaitIox(quasi_file_number, tag, &feError); else { QfoHideSegs(cliGlobals); SETSTOP(oldStop); return FENONEOUT; } if (feError != FEOK) retVal = feError; // May be FEBADPARMVALUE, or FENONEOUT else { if (1) // Not used but is compiled on NT retVal = FEQFOEVENTCONSUMED; else switch (retcode) { case SUCCESS: retVal = FEOK; break; case ERROR: retVal = FESQLERR; break; case SQL_EOF: case WARNING: retVal = FESQLWARN; break; case NOT_FINISHED: retVal = FEQFONOTCOMPLETE; break; default: retVal = FEBADPARMVALUE; } } QfoHideSegs(cliGlobals); SETSTOP(oldStop); return retVal; }
short ExExeUtilLongRunningTcb::processInitial(Lng32 &rc) { Int64 rowsAffected = 0; setInitialOutputVarPtrList(new(getHeap()) Queue(getHeap())); setContinuingOutputVarPtrList(new(getHeap()) Queue(getHeap())); lruStmtAndPartInfo_ = new(getHeap()) char[(UInt32)(lrTdb().getLruStmtLen() + lrTdb().getPredicateLen() + 10)]; ExExeStmtGlobals *exeGlob = getGlobals()->castToExExeStmtGlobals(); ExEspStmtGlobals *espGlob = exeGlob->castToExEspStmtGlobals(); ContextCli *currContext = NULL; CliGlobals *cliGlobals = NULL; if (espGlob) { cliGlobals = GetCliGlobals(); currContext = cliGlobals->currContext(); } else { currContext = exeGlob->castToExMasterStmtGlobals()->getStatement()->getContext(); } Int32 espNum = 1; // we are executing inside an ESP go ahead and set the partition number to the // ESP instance number. The added one is because ESP instances are 0 based if (espGlob) { espNum = (Int32) espGlob->getMyInstanceNumber() + 1; } if (lrTdb().getPredicate() != NULL) str_sprintf(lruStmtAndPartInfo_, lrTdb().getLruStmt(), espNum, lrTdb().getPredicate()); else str_sprintf(lruStmtAndPartInfo_, lrTdb().getLruStmt(), espNum); lruStmtWithCKAndPartInfo_ = new(getHeap()) char[(UInt32)(lrTdb().getLruStmtWithCKLen() + lrTdb().getPredicateLen() + 10)]; if (lrTdb().getPredicate() != NULL) str_sprintf(lruStmtWithCKAndPartInfo_, lrTdb().getLruStmtWithCK(), espNum, lrTdb().getPredicate()); else str_sprintf(lruStmtWithCKAndPartInfo_, lrTdb().getLruStmtWithCK(), espNum); // All internal queries issued from CliInterface assume that // they are in ISO_MAPPING. // For LongRunning we need to send the actual ISO_MAPPING. // Save it and restore after the prepare Int32 savedIsoMapping = cliInterface()->getIsoMapping(); cliInterface()->setIsoMapping (currContext->getSessionDefaults()->getIsoMappingEnum()); // If the table we are deleting from is an IUD log table, // we need to set the parserflags to accept the special // table type and the quoted column names if (lrTdb().useParserflags()) currContext->setSqlParserFlags(0x3); rc = cliInterface()->prepareAndExecRowsPrologue(lruStmtAndPartInfo_, lruStmtWithCKAndPartInfo_, getInitialOutputVarPtrList(), getContinuingOutputVarPtrList(), rowsAffected); cliInterface()->setIsoMapping(savedIsoMapping); if (rc < 0) { return -1; } if (rc >= 0 && rowsAffected > 0) addRowsDeleted(rowsAffected); return 0; }
short ExExeUtilLongRunningTcb::doLongRunning() { Lng32 cliRC =0; short retcode = 0; NABoolean xnAlreadyStarted = FALSE; // Get the globals stucture of the master executor. ExExeStmtGlobals *exeGlob = getGlobals()->castToExExeStmtGlobals(); ExMasterStmtGlobals *masterGlob = exeGlob->castToExMasterStmtGlobals(); ex_queue_entry * pentry_down = qparent_.down->getHeadEntry(); ExExeUtilPrivateState & pstate = *((ExExeUtilPrivateState*) pentry_down->pstate); CliGlobals *cliGlobals = 0; cliGlobals = GetCliGlobals(); ex_assert(cliGlobals != NULL, "Cli globals is NULL - should have been allocated already"); if (cliGlobals->isESPProcess()) { if (!currTransaction_) currTransaction_ = new (getHeap()) ExTransaction (cliGlobals, getHeap()); } else // in master executor { currTransaction_ = masterGlob->getStatement()->getContext()->getTransaction(); } if (currTransaction_->xnInProgress()) { xnAlreadyStarted = TRUE; } // cannot run LRU when a user transaction is in progress if (xnAlreadyStarted) { ExHandleErrors(qparent_, pentry_down, 0, getGlobals(), NULL, (ExeErrorCode)(-8603), NULL, exeUtilTdb().getTableName() ); return (-8603); } SQL_EXEC_ClearDiagnostics(NULL); // no Xn in progress. Start one. cliRC = currTransaction_->beginTransaction (); if (cliRC < 0) { ExHandleErrors(qparent_, pentry_down, 0, getGlobals(), NULL, (ExeErrorCode)(cliRC), NULL, exeUtilTdb().getTableName() ); return (short) cliRC; } retcode = executeLongRunningQuery(); // Rollback the transaction, if there is an error. if (retcode < 0) { // rollback the transaction cliRC = currTransaction_->rollbackTransaction (); return retcode; } else { // commit the transaction cliRC = currTransaction_->commitTransaction (); if (cliRC < 0) { ExHandleErrors(qparent_, pentry_down, 0, getGlobals(), NULL, (ExeErrorCode)(cliRC), NULL, exeUtilTdb().getTableName() ); return short(cliRC); } addTransactionCount(); } return retcode; }
Int32 runESP(Int32 argc, char** argv, GuaReceiveFastStart *guaReceiveFastStart) { // initialize ESP global data StatsGlobals * statsGlobals; XCONTROLMESSAGESYSTEM(XCTLMSGSYS_SETRECVLIMIT, XMAX_SETTABLE_RECVLIMIT_H); CliGlobals *cliGlobals = NULL; cliGlobals = CliGlobals::createCliGlobals(TRUE); // TRUE indicates a non-master process (WAIT on LREC) if (cliGlobals == NULL) // Sanity check NAExit(1); // Abend Int32 shmid; statsGlobals = shareStatsSegment(shmid); cliGlobals->setSharedMemId(shmid); //Lng32 numCliCalls = cliGlobals->incrNumOfCliCalls(); cliGlobals->setIsESPProcess(TRUE); NAHeap *espExecutorHeap = cliGlobals->getExecutorMemory(); // must create default context after set IpcEnvironment in CliGlobals first // because context's ExSqlComp object needs IpcEnvironment cliGlobals->initiateDefaultContext(); NAHeap *espIpcHeap = cliGlobals->getIpcHeap(); IpcEnvironment *ipcEnvPtr = cliGlobals->getEnvironment(); if (statsGlobals != NULL) cliGlobals->setMemoryMonitor(statsGlobals->getMemoryMonitor()); else { // Start the memory monitor for dynamic memory management Lng32 memMonitorWindowSize = 10; Lng32 memMonitorSampleInterval = 10; MemoryMonitor *memMonitor = new (espExecutorHeap) MemoryMonitor(memMonitorWindowSize, memMonitorSampleInterval, espExecutorHeap); cliGlobals->setMemoryMonitor(memMonitor); } // After CLI globals are initialized but before we begin ESP message // processing, have the CLI context set its user identity based on // the OS user identity. ContextCli *context = cliGlobals->currContext(); ex_assert(context, "Invalid context pointer"); context->initializeUserInfoFromOS(); ExEspFragInstanceDir espFragInstanceDir(cliGlobals, espExecutorHeap, (StatsGlobals *)statsGlobals); ExEspControlMessage espIpcControlMessage(&espFragInstanceDir, ipcEnvPtr, espIpcHeap); // handle startup (command line args, control connection) DoEspStartup(argc,argv,*ipcEnvPtr,espFragInstanceDir,guaReceiveFastStart); // the control message stream talks through the control connection espIpcControlMessage.addRecipient( ipcEnvPtr->getControlConnection()->getConnection()); // start the first receive operation espIpcControlMessage.receive(FALSE); NABoolean timeout; Int64 prevWaitTime = 0; // while there are requesters while (espFragInstanceDir.getNumMasters() > 0) { // ----------------------------------------------------------------- // The ESPs most important line of code: DO THE WORK // ----------------------------------------------------------------- espFragInstanceDir.work(prevWaitTime); // ----------------------------------------------------------------- // After we have done work, it's necessary to wait for some I/O // (the frag instance dir work procedure works until it is blocked). // ----------------------------------------------------------------- ipcEnvPtr->getAllConnections()-> waitOnAll(IpcInfiniteTimeout, TRUE, &timeout, &prevWaitTime); // TRUE means: Called by ESP main } // nobody wants us anymore, right now that means that we stop return 0; }
void runServer(Int32 argc, char **argv) { Int32 shmid; jmp_buf sscpJmpBuf; StatsGlobals *statsGlobals = NULL; void *statsGlobalsAddr; NABoolean createStatsGlobals = FALSE; CliGlobals *cliGlobals = CliGlobals::createCliGlobals(FALSE); char tmbuf[64]; time_t now; struct tm *nowtm; long maxSegSize = STATS_MAX_SEG_SIZE; char *envSegSize = getenv("MX_RTS_STATS_SEG_SIZE"); if (envSegSize) { maxSegSize = (long) str_atoi(envSegSize, str_len(envSegSize)); if (maxSegSize < 32) maxSegSize = 32; else if (maxSegSize > 256) maxSegSize = 256; maxSegSize *= 1024 * 1024; } long enableHugePages = 0; int shmFlag = RMS_SHMFLAGS; char *envShmHugePages = getenv("SQ_RMS_ENABLE_HUGEPAGES"); if (envShmHugePages != NULL) { enableHugePages = (long) str_atoi(envShmHugePages, str_len(envShmHugePages)); if (enableHugePages > 0) shmFlag = shmFlag | SHM_HUGETLB; } now = time(NULL); nowtm = localtime(&now); strftime(tmbuf, sizeof tmbuf, "%Y-%m-%d %H:%M:%S ", nowtm); if ((shmid = shmget((key_t)getStatsSegmentId(), 0, // size doesn't matter unless we are creating. shmFlag)) == -1) { if (errno == ENOENT) { // Normal case, segment does not exist yet. Try to create. bool didCreate = true; if ((shmid = shmget((key_t)getStatsSegmentId(), maxSegSize, shmFlag | IPC_CREAT)) == -1) { if (enableHugePages > 0) { enableHugePages = 0; // try again withouf hugepages shmFlag = shmFlag & ~SHM_HUGETLB; if ((shmid = shmget((key_t)getStatsSegmentId(), maxSegSize, shmFlag | IPC_CREAT)) == -1) didCreate = false; } else didCreate = false; } if (didCreate) { cout << tmbuf << " RMS Shared segment id = " << shmid << ", key = " << (key_t)getStatsSegmentId() ; if (enableHugePages > 0) cout << ", created with huge pages support." << endl; else cout << ", created without huge pages support." << endl; createStatsGlobals = TRUE; } else { cout << tmbuf << " Shmget failed, key = " << getStatsSegmentId() <<", Error code: " << errno << " (" << strerror(errno) << ")" << endl; exit(errno); } } // if ENOENT (i.e., attempting creation.) } else { cout << tmbuf << " RMS Shared segment exists, attaching to it, shmid="<< shmid << ", key=" << (key_t)getStatsSegmentId() << "\n"; } if ((statsGlobalsAddr = shmat(shmid, getRmsSharedMemoryAddr(), 0)) == (void *)-1) { cout << tmbuf << "Shmat failed, shmid=" <<shmid << ", key=" << (key_t) getStatsSegmentId() << ", Error code : " << errno << "(" << strerror(errno) << ")\n"; exit(errno); } char *statsGlobalsStartAddr = (char *)statsGlobalsAddr; if (createStatsGlobals) { short envType = StatsGlobals::RTS_GLOBAL_ENV; statsGlobals = new (statsGlobalsStartAddr) StatsGlobals((void *)statsGlobalsAddr, envType, maxSegSize); cliGlobals->setSharedMemId(shmid); // We really should not squirrel the statsGlobals pointer away like // this until the StatsGloblas is initialized, but // statsGlobals->init() needs it ...... cliGlobals->setStatsGlobals(statsGlobals); statsGlobals->init(); } else { statsGlobals = (StatsGlobals *)statsGlobalsAddr; cliGlobals->setSharedMemId(shmid); cliGlobals->setStatsGlobals(statsGlobals); } XPROCESSHANDLE_GETMINE_(statsGlobals->getSscpProcHandle()); NAHeap *sscpHeap = cliGlobals->getExecutorMemory(); cliGlobals->setJmpBufPtr(&sscpJmpBuf); if (setjmp(sscpJmpBuf)) NAExit(1); // Abend IpcEnvironment *sscpIpcEnv = new (sscpHeap) IpcEnvironment(sscpHeap, cliGlobals->getEventConsumed(), FALSE, IPC_SQLSSCP_SERVER, FALSE, TRUE); SscpGlobals *sscpGlobals = NULL; sscpGlobals = new (sscpHeap) SscpGlobals(sscpHeap, statsGlobals); // Currently open $RECEIVE with 256 SscpGuaReceiveControlConnection *cc = new(sscpHeap) SscpGuaReceiveControlConnection(sscpIpcEnv, sscpGlobals, 256); sscpIpcEnv->setControlConnection(cc); while (TRUE) { while (cc->getConnection() == NULL) cc->wait(IpcInfiniteTimeout); #ifdef _DEBUG_RTS cerr << "No. of Requesters-1 " << cc->getNumRequestors() << " \n"; #endif while (cc->getNumRequestors() > 0) { sscpIpcEnv->getAllConnections()->waitOnAll(IpcInfiniteTimeout); } // Inner while } } // runServer
ExWorkProcRetcode ExCancelTcb::work() { ExMasterStmtGlobals *masterGlobals = getGlobals()->castToExExeStmtGlobals()->castToExMasterStmtGlobals(); CliGlobals *cliGlobals = masterGlobals->getCliGlobals(); while ((qparent_.down->isEmpty() == FALSE) && (qparent_.up->isFull() == FALSE)) { ex_queue_entry *pentry_down = qparent_.down->getHeadEntry(); switch (step_) { case NOT_STARTED: { if (pentry_down->downState.request == ex_queue::GET_NOMORE) step_ = DONE; else { retryCount_ = 0; // Priv checking is done during compilation. To support // REVOKE, prevent a prepared CANCEL/SUSPEND/ACTIVATE // that was compiled more than 1 second ago from executing // by raising the 8734 error to force an AQR. Int64 microSecondsSinceCompile = NA_JulianTimestamp() - masterGlobals->getStatement()->getCompileEndTime(); if (microSecondsSinceCompile > 1000*1000) { ComDiagsArea *diagsArea = ComDiagsArea::allocate(getGlobals()->getDefaultHeap()); *diagsArea << DgSqlCode(-CLI_INVALID_QUERY_PRIVS); reportError(diagsArea); step_ = DONE; break; } // Figure out which MXSSMP broker to use. if (cancelTdb().getAction() == ComTdbCancel::CancelByPname) { int nid = -1; int rc = msg_mon_get_process_info(cancelTdb().getCancelPname(), &nid, &pid_); switch (rc) { case XZFIL_ERR_OK: cpu_ = (short) nid; break; case XZFIL_ERR_NOTFOUND: case XZFIL_ERR_BADNAME: case XZFIL_ERR_NOSUCHDEV: { ComDiagsArea *diagsArea = ComDiagsArea::allocate(getGlobals()->getDefaultHeap()); *diagsArea << DgSqlCode(-EXE_CANCEL_PROCESS_NOT_FOUND); *diagsArea << DgString0(cancelTdb().getCancelPname()); reportError(diagsArea); step_ = DONE; break; } default: { char buf[200]; str_sprintf(buf, "Unexpected error %d returned from " "msg_mon_get_process_info", rc); ex_assert(0, buf); } } if (step_ != NOT_STARTED) break; } else if (cancelTdb().getAction() == ComTdbCancel::CancelByNidPid) { cpu_ = (short) cancelTdb().getCancelNid(); pid_ = cancelTdb().getCancelPid(); // check that process exists, if not report error. char processName[MS_MON_MAX_PROCESS_NAME]; int rc = msg_mon_get_process_name(cpu_, pid_, processName); if (XZFIL_ERR_OK == rc) ; // good. nid & pid are valid. else { if ((XZFIL_ERR_NOTFOUND != rc) && (XZFIL_ERR_BADNAME != rc) && (XZFIL_ERR_NOSUCHDEV != rc)) { // Log rc in case it needs investigation later. char buf[200]; str_sprintf(buf, "Unexpected error %d returned from " "msg_mon_get_process_name", rc); SQLMXLoggingArea::logExecRtInfo(__FILE__, __LINE__, buf, 0); } char nid_pid_str[32]; str_sprintf(nid_pid_str, "%d, %d", cpu_, pid_); ComDiagsArea *diagsArea = ComDiagsArea::allocate(getGlobals()->getDefaultHeap()); *diagsArea << DgSqlCode(-EXE_CANCEL_PROCESS_NOT_FOUND); *diagsArea << DgString0(nid_pid_str); reportError(diagsArea); step_ = DONE; break; } } else { char * qid = cancelTdb().qid_; Lng32 qid_len = str_len(qid); // This static method is defined in SqlStats.cpp. It side-effects // the nodeName and cpu_ according to the input qid. if (getMasterCpu( qid, qid_len, nodeName_, sizeof(nodeName_) - 1, cpu_) == -1) { ComDiagsArea *diagsArea = ComDiagsArea::allocate(getGlobals()->getDefaultHeap()); *diagsArea << DgSqlCode(-EXE_RTS_INVALID_QID); reportError(diagsArea); step_ = DONE; break; } } // Testpoints for hard to reproduce problems: bool fakeError8028 = false; fakeError8028 = (getenv("HP_FAKE_ERROR_8028") != NULL); if ((cliGlobals->getCbServerClass() == NULL) || fakeError8028) { ComDiagsArea *diagsArea = ComDiagsArea::allocate(getGlobals()->getDefaultHeap()); *diagsArea << DgSqlCode(-EXE_CANCEL_PROCESS_NOT_FOUND); *diagsArea << DgString0("$ZSM000"); reportError(diagsArea); step_ = DONE; break; } ComDiagsArea *diagsArea = NULL; bool fakeError2024 = false; fakeError2024 = (getenv("HP_FAKE_ERROR_2024") != NULL); if (fakeError2024) { cbServer_ = NULL; diagsArea = ComDiagsArea::allocate(getGlobals()->getDefaultHeap()); if (getenv("HP_FAKE_ERROR_8142")) { *diagsArea << DgSqlCode(-8142); *diagsArea << DgString0(__FILE__); *diagsArea << DgString1("cbServer_ is NULL"); } else *diagsArea << DgSqlCode(-2024); } else cbServer_ = cliGlobals->getCbServerClass()->allocateServerProcess( &diagsArea, cliGlobals->getEnvironment()->getHeap(), nodeName_, cpu_, IPC_PRIORITY_DONT_CARE, FALSE, // usesTransactions TRUE, // waitedCreation 2 // maxNowaitRequests -- cancel+(1 extra). ); if (cbServer_ == NULL || cbServer_->getControlConnection() == NULL) { ex_assert(diagsArea != NULL, "allocateServerProcess failed, but no diags"); // look for SQLCode 2024 // "*** ERROR[2024] Server Process $0~string0 // is not running or could not be created. Operating System // Error $1~int0 was returned." // Remap to cancel-specfic error 8028. if (diagsArea->contains(-2024) && cancelTdb().actionIsCancel()) { diagsArea->deleteError(diagsArea->returnIndex(-2024)); reportError(diagsArea, true, EXE_CANCEL_PROCESS_NOT_FOUND, nodeName_, cpu_); } else reportError(diagsArea); step_ = DONE; break; } // the reportError method was not called -- see break above. if (diagsArea != NULL) diagsArea->decrRefCount(); //Create the stream on the IpcHeap, since we don't dispose // of it immediately. We just add it to the list of completed // messages in the IpcEnv, and it is disposed of later. cancelStream_ = new (cliGlobals->getIpcHeap()) CancelMsgStream(cliGlobals->getEnvironment(), this); cancelStream_->addRecipient(cbServer_->getControlConnection()); } step_ = SEND_MESSAGE; break; } // end case NOT_STARTED #pragma warning (disable : 4291) case SEND_MESSAGE: { RtsHandle rtsHandle = (RtsHandle) this; if (cancelTdb().actionIsCancel()) { Int64 cancelStartTime = JULIANTIMESTAMP(); Lng32 firstEscalationInterval = cliGlobals->currContext()-> getSessionDefaults()->getCancelEscalationInterval(); Lng32 secondEscalationInterval = cliGlobals->currContext()-> getSessionDefaults()->getCancelEscalationMxosrvrInterval(); NABoolean cancelEscalationSaveabend = cliGlobals->currContext()-> getSessionDefaults()->getCancelEscalationSaveabend(); bool cancelLogging = (TRUE == cliGlobals->currContext()-> getSessionDefaults()->getCancelLogging()); CancelQueryRequest *cancelMsg = new (cliGlobals->getIpcHeap()) CancelQueryRequest(rtsHandle, cliGlobals->getIpcHeap(), cancelStartTime, firstEscalationInterval, secondEscalationInterval, cancelEscalationSaveabend, cancelTdb().getCommentText(), str_len(cancelTdb().getCommentText()), cancelLogging, cancelTdb().action_ != ComTdbCancel::CancelByQid, pid_, cancelTdb().getCancelPidBlockThreshold()); #pragma warning (default : 4291) *cancelStream_ << *cancelMsg; cancelMsg->decrRefCount(); } else if (ComTdbCancel::Suspend == cancelTdb().action_) { bool suspendLogging = (TRUE == cliGlobals->currContext()-> getSessionDefaults()->getSuspendLogging()); #pragma warning (disable : 4291) SuspendQueryRequest * suspendMsg = new (cliGlobals->getIpcHeap()) SuspendQueryRequest(rtsHandle, cliGlobals->getIpcHeap(), ComTdbCancel::Force == cancelTdb().forced_, suspendLogging); #pragma warning (default : 4291) *cancelStream_ << *suspendMsg; suspendMsg->decrRefCount(); } else { ex_assert( ComTdbCancel::Activate == cancelTdb().action_, "invalid action for ExCancelTcb"); bool suspendLogging = (TRUE == cliGlobals->currContext()-> getSessionDefaults()->getSuspendLogging()); #pragma warning (disable : 4291) ActivateQueryRequest * activateMsg = new (cliGlobals->getIpcHeap()) ActivateQueryRequest(rtsHandle, cliGlobals->getIpcHeap(), suspendLogging); #pragma warning (default : 4291) *cancelStream_ << *activateMsg; activateMsg->decrRefCount(); } if ((cancelTdb().getAction() != ComTdbCancel::CancelByPname) && (cancelTdb().getAction() != ComTdbCancel::CancelByNidPid)) { char * qid = cancelTdb().qid_; Lng32 qid_len = str_len(qid); #pragma warning (disable : 4291) RtsQueryId *rtsQueryId = new (cliGlobals->getIpcHeap()) RtsQueryId( cliGlobals->getIpcHeap(), qid, qid_len); #pragma warning (default : 4291) *cancelStream_ << *rtsQueryId; rtsQueryId->decrRefCount(); } // send a no-wait request to the cancel broker. cancelStream_->send(FALSE); step_ = GET_REPLY; // Come back when I/O completes. return WORK_OK; break; } // end case SEND_MESSAGE case GET_REPLY: { // Handle general IPC error. bool fakeError201 = false; fakeError201 = (getenv("HP_FAKE_ERROR_201") != NULL); if ((cbServer_->getControlConnection()->getErrorInfo() != 0) || fakeError201) { ComDiagsArea *diagsArea = ComDiagsArea::allocate(getGlobals()->getDefaultHeap()); cbServer_->getControlConnection()-> populateDiagsArea( diagsArea, getGlobals()->getDefaultHeap()); if (fakeError201) { *diagsArea << DgSqlCode(-2034) << DgInt0(201) << DgString0("I say") << DgString1("control broker"); } if (diagsArea->contains(-8921)) { // Should not get timeout error 8921. Get a core-file // of the SSMP and this process too so that this can be // debugged. cbServer_->getControlConnection()-> dumpAndStopOtherEnd(true, false); genLinuxCorefile("Unexpected timeout error"); } reportError(diagsArea); step_ = DONE; break; } // See if stream has the reply yet. if (!cancelStream_->moreObjects()) return WORK_OK; #pragma warning (disable : 4291) ControlQueryReply *reply = new (cliGlobals->getIpcHeap()) ControlQueryReply(INVALID_RTS_HANDLE, cliGlobals->getIpcHeap()); #pragma warning (default : 4291) *cancelStream_ >> *reply; if (reply->didAttemptControl()) { // yeaah! cancelStream_->clearAllObjects(); } else { if (cancelStream_->moreObjects() && cancelStream_->getNextObjType() == IPC_SQL_DIAG_AREA) { ComDiagsArea *diagsArea = ComDiagsArea::allocate(getGlobals()->getDefaultHeap()); *cancelStream_ >> *diagsArea; cancelStream_->clearAllObjects(); if ( retryQidNotActive_ && (diagsArea->mainSQLCODE() == -EXE_SUSPEND_QID_NOT_ACTIVE) && (++retryCount_ <= 60)) { SQLMXLoggingArea::logExecRtInfo(__FILE__, __LINE__, "Retrying error 8672.", 0); DELAY(500); diagsArea->decrRefCount(); step_ = SEND_MESSAGE; break; } reportError(diagsArea); } else ex_assert(0, "Control failed, but no diagnostics."); } step_ = DONE; break; } case DONE: { if (cancelStream_) { cancelStream_->addToCompletedList(); cancelStream_ = NULL; } if (cbServer_) { cbServer_->release(); cbServer_ = NULL; } ex_queue_entry * up_entry = qparent_.up->getTailEntry(); up_entry->copyAtp(pentry_down); up_entry->upState.parentIndex = pentry_down->downState.parentIndex; up_entry->upState.downIndex = qparent_.down->getHeadIndex(); up_entry->upState.setMatchNo(1); up_entry->upState.status = ex_queue::Q_NO_DATA; qparent_.up->insert(); qparent_.down->removeHead(); step_ = NOT_STARTED; break; } default: ex_assert( 0, "Unknown step_."); }