Example #1
0
/***************************************************************************
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);
}
Example #2
0
/******************************************************************************
 * 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();
}
Example #3
0
/**
 * 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) {
Example #4
0
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;
}