/*************************************************************************** void releaseSignal(NdbApiSignal* aSignal); Parameters: aSignal : The released NdbApiSignal object. Remark: Add a NdbApiSignal object into the signal idlelist. ***************************************************************************/ void Ndb::releaseSignal(NdbApiSignal* aSignal) { #if defined VM_TRACE // Check that signal is not null assert(aSignal != NULL); #if 0 // Check that signal is not already in list NdbApiSignal* tmp = theSignalIdleList; while (tmp != NULL){ assert(tmp != aSignal); tmp = tmp->next(); } #endif #endif #ifdef POORMANSPURIFY creleaseSignals++; #endif theImpl->theSignalIdleList.release(aSignal); }
/****************************************************************************** * void release(); * * Remark: Release all objects connected to the operation object. *****************************************************************************/ void NdbOperation::release() { NdbApiSignal* tSignal; NdbApiSignal* tSaveSignal; NdbBranch* tBranch; NdbBranch* tSaveBranch; NdbLabel* tLabel; NdbLabel* tSaveLabel; NdbCall* tCall; NdbCall* tSaveCall; NdbSubroutine* tSubroutine; NdbSubroutine* tSaveSubroutine; NdbBlob* tBlob; NdbBlob* tSaveBlob; tSignal = theTCREQ; while (tSignal != NULL) { tSaveSignal = tSignal; tSignal = tSignal->next(); theNdb->releaseSignal(tSaveSignal); } theTCREQ = NULL; theLastKEYINFO = NULL; tSignal = theFirstATTRINFO; while (tSignal != NULL) { tSaveSignal = tSignal; tSignal = tSignal->next(); theNdb->releaseSignal(tSaveSignal); } theFirstATTRINFO = NULL; theCurrentATTRINFO = NULL; if (theInterpretIndicator == 1) { tBranch = theFirstBranch; while (tBranch != NULL) { tSaveBranch = tBranch; tBranch = tBranch->theNext; theNdb->releaseNdbBranch(tSaveBranch); } tLabel = theFirstLabel; while (tLabel != NULL) { tSaveLabel = tLabel; tLabel = tLabel->theNext; theNdb->releaseNdbLabel(tSaveLabel); } tCall = theFirstCall; while (tCall != NULL) { tSaveCall = tCall; tCall = tCall->theNext; theNdb->releaseNdbCall(tSaveCall); } tSubroutine = theFirstSubroutine; while (tSubroutine != NULL) { tSaveSubroutine = tSubroutine; tSubroutine = tSubroutine->theNext; theNdb->releaseNdbSubroutine(tSaveSubroutine); } } tBlob = theBlobList; while (tBlob != NULL) { tSaveBlob = tBlob; tBlob = tBlob->theNext; theNdb->releaseNdbBlob(tSaveBlob); } theBlobList = NULL; theReceiver.release(); }
/** * The execute function : Handle received signal */ void execute(void * callbackObj, SignalHeader * const header, Uint8 prio, Uint32 * const theData, LinearSectionPtr ptr[3]){ TransporterFacade * theFacade = (TransporterFacade*)callbackObj; TransporterFacade::ThreadData::Object_Execute oe; Uint32 tRecBlockNo = header->theReceiversBlockNumber; #ifdef API_TRACE if(setSignalLog() && TRACE_GSN(header->theVerId_signalNumber)){ signalLogger.executeSignal(* header, prio, theData, theFacade->ownId(), ptr, header->m_noOfSections); signalLogger.flushSignalLog(); } #endif if (tRecBlockNo >= MIN_API_BLOCK_NO) { oe = theFacade->m_threads.get(tRecBlockNo); if (oe.m_object != 0 && oe.m_executeFunction != 0) { /** * Handle received signal immediately to avoid any unnecessary * copying of data, allocation of memory and other things. Copying * of data could be interesting to support several priority levels * and to support a special memory structure when executing the * signals. Neither of those are interesting when receiving data * in the NDBAPI. The NDBAPI will thus read signal data directly as * it was written by the sender (SCI sender is other node, Shared * memory sender is other process and TCP/IP sender is the OS that * writes the TCP/IP message into a message buffer). */ NdbApiSignal tmpSignal(*header); NdbApiSignal * tSignal = &tmpSignal; tSignal->setDataPtr(theData); (* oe.m_executeFunction) (oe.m_object, tSignal, ptr); }//if } else if (tRecBlockNo == API_PACKED) { /** * Block number == 2047 is used to signal a signal that consists of * multiple instances of the same signal. This is an effort to * package the signals so as to avoid unnecessary communication * overhead since TCP/IP has a great performance impact. */ Uint32 Tlength = header->theLength; Uint32 Tsent = 0; /** * Since it contains at least two data packets we will first * copy the signal data to safe place. */ while (Tsent < Tlength) { Uint32 Theader = theData[Tsent]; Tsent++; Uint32 TpacketLen = (Theader & 0x1F) + 3; tRecBlockNo = Theader >> 16; if (TpacketLen <= 25) { if ((TpacketLen + Tsent) <= Tlength) { /** * Set the data length of the signal and the receivers block * reference and then call the API. */ header->theLength = TpacketLen; header->theReceiversBlockNumber = tRecBlockNo; Uint32* tDataPtr = &theData[Tsent]; Tsent += TpacketLen; if (tRecBlockNo >= MIN_API_BLOCK_NO) { oe = theFacade->m_threads.get(tRecBlockNo); if(oe.m_object != 0 && oe.m_executeFunction != 0){ NdbApiSignal tmpSignal(*header); NdbApiSignal * tSignal = &tmpSignal; tSignal->setDataPtr(tDataPtr); (*oe.m_executeFunction)(oe.m_object, tSignal, 0); } } } } } return; } else if (tRecBlockNo == API_CLUSTERMGR) {
void NdbScanFilterImpl::handle_filter_too_large() { DBUG_ENTER("NdbScanFilterImpl::handle_filter_too_large"); NdbOperation* const op = m_operation; m_error.code = NdbScanFilter::FilterTooLarge; if (m_abort_on_too_large) op->setErrorCodeAbort(m_error.code); /* * Possible interpreted parts at this point are: * * 1. initial read * 2. interpreted program * * It is assumed that NdbScanFilter has created all of 2 * so that we don't have to save interpreter state. */ const Uint32 size = get_size(); assert(size != 0); // new ATTRINFO size const Uint32 new_size = m_initial_AI_size; // find last signal for new size assert(op->theFirstATTRINFO != NULL); NdbApiSignal* lastSignal = op->theFirstATTRINFO; Uint32 n = 0; while (n + AttrInfo::DataLength < new_size) { lastSignal = lastSignal->next(); assert(lastSignal != NULL); n += AttrInfo::DataLength; } assert(n < size); // release remaining signals NdbApiSignal* tSignal = lastSignal->next(); op->theNdb->releaseSignalsInList(&tSignal); lastSignal->next(NULL); // length of lastSignal const Uint32 new_curr = AttrInfo::HeaderLength + new_size - n; assert(new_curr <= 25); DBUG_PRINT("info", ("op status: %d->%d tot AI: %u->%u in curr: %u->%u", op->theStatus, m_initial_op_status, op->theTotalCurrAI_Len, new_size, op->theAI_LenInCurrAI, new_curr)); // reset op state op->theStatus = m_initial_op_status; // reset interpreter state to initial NdbBranch* tBranch = op->theFirstBranch; while (tBranch != NULL) { NdbBranch* tmp = tBranch; tBranch = tBranch->theNext; op->theNdb->releaseNdbBranch(tmp); } op->theFirstBranch = NULL; op->theLastBranch = NULL; NdbLabel* tLabel = op->theFirstLabel; while (tLabel != NULL) { NdbLabel* tmp = tLabel; tLabel = tLabel->theNext; op->theNdb->releaseNdbLabel(tmp); } op->theFirstLabel = NULL; op->theLastLabel = NULL; NdbCall* tCall = op->theFirstCall; while (tCall != NULL) { NdbCall* tmp = tCall; tCall = tCall->theNext; op->theNdb->releaseNdbCall(tmp); } op->theFirstCall = NULL; op->theLastCall = NULL; NdbSubroutine* tSubroutine = op->theFirstSubroutine; while (tSubroutine != NULL) { NdbSubroutine* tmp = tSubroutine; tSubroutine = tSubroutine->theNext; op->theNdb->releaseNdbSubroutine(tmp); } op->theFirstSubroutine = NULL; op->theLastSubroutine = NULL; op->theNoOfLabels = 0; op->theNoOfSubroutines = 0; // reset AI size op->theTotalCurrAI_Len = new_size; op->theAI_LenInCurrAI = new_curr; // reset signal pointers op->theCurrentATTRINFO = lastSignal; op->theATTRINFOptr = &lastSignal->getDataPtrSend()[new_curr]; // interpreter sizes are set later somewhere DBUG_VOID_RETURN; }