Пример #1
0
//////////////////////////////////////////////////////
// work() for ExTimeoutTcb
//////////////////////////////////////////////////////
short ExTimeoutTcb::work()
{
  while (1) {
    // if no parent request, return
    if (qparent_.down->isEmpty())
      return WORK_OK;
      
    // if no room in up queue, won't be able to return data/status.
    // Come back later.
    if (qparent_.up->isFull()) return WORK_OK;
      
    ex_queue_entry * pentry_down = qparent_.down->getHeadEntry(); 
    ExTimeoutPrivateState & pstate =
      *((ExTimeoutPrivateState*) pentry_down->pstate);

    // Calculate the timeout actual value
    Lng32 timeoutValue = 0; 
    NABoolean goodTimeoutValue = TRUE ;
    if (timeoutValueExpr()) {
      if ( timeoutValueExpr()->eval(pentry_down->getAtp(), workAtp_) 
	   == ex_expr::EXPR_ERROR ) { // expression did not yield a valid value
	handleErrors(pentry_down, pentry_down->getAtp()->getDiagsArea()); 
	goodTimeoutValue = FALSE ;
      } else {
	tupp TP = workAtp_->getTupp(timeoutTdb().workCriDesc_->noTuples()-1);
	timeoutValue = *(Lng32 *)TP.getDataPointer(); // pointer is (char *)
      }
    }

    /****************************************************/
    /********   Do the actual SET TIMEOUT work   ********/
    /**                                                **/
    /** The scope of the work is only making changes   **/
    /** to the global timeout data kept at the context **/
    /****************************************************/

    // Get the global timeout-data object
    ContextCli * currContext = getGlobals()->castToExExeStmtGlobals()->
      castToExMasterStmtGlobals()->getStatement()->getContext();
    
    TimeoutData * GlobalTimeouts = currContext->getTimeouts();

#if _DEBUG    // For debugging only !!!!!
    if ( getenv("DEBUG_TIMEOUT") ) {
      ComDiagsArea* diagsArea = 
	ComDiagsArea::allocate (getGlobals()->getDefaultHeap());
      char errmsg[120];

      if ( timeoutTdb().isStream() ) {   // it was a SET STREAM TIMEOUT
	if ( GlobalTimeouts->isStreamTimeoutSet() ) {
	  sprintf(errmsg, "Stream timeout set to %d\n",
		  GlobalTimeouts->getStreamTimeout() );
	} else sprintf(errmsg, "Stream timeout was NOT SET ! \n");
      } // lock timeout -- not stream
      else {
	if ( theTableName_[0] == '*' ) { // For all tables
	  sprintf(errmsg, "Number of lock timeouts set: %d\n",
		  GlobalTimeouts->entries() );
	} else {
	  Lng32 timeoutValue;
	  NABoolean found = 
	    GlobalTimeouts->getLockTimeout(theTableName_, timeoutValue );
	  if ( ! found ) 
	    sprintf(errmsg, "Lock timeout for table %s was NOT SET ! \n",
		    theTableName_ );
	  else sprintf(errmsg, "Lock timeout for table %s is %d \n",
		       theTableName_ , timeoutValue );
	}
      }
      // emit message as an error ( msg 3066 has no text of its own )
      *diagsArea << DgSqlCode(-3066)
		<< DgString0(errmsg) ;
      ExHandleArkcmpErrors(qparent_, pentry_down, 0, getGlobals(), 
			   diagsArea, (ExeErrorCode) -3066 );
    }  // end of debugging section  
    else   
#endif    

    if ( goodTimeoutValue ) {

      // Update the globals as needed
      if ( timeoutTdb().isStream() ) {   // it was a SET STREAM TIMEOUT
	if ( timeoutTdb().isReset() )  // it was a RESET
	  GlobalTimeouts->resetStreamTimeout(); 
	else                           // it was a SET (with a value)
	  GlobalTimeouts->setStreamTimeout(timeoutValue);
      }
      else {                     // setting a LOCK TIMEOUT
	// TBD =============>>> Check if FORALL string includes CAT.SCH ......
	if ( theTableName_[0] == '*' ) { // For all tables
	  if ( timeoutTdb().isReset() )  // it was a RESET
	    GlobalTimeouts->resetAllLockTimeout();
	  else GlobalTimeouts->setAllLockTimeout(timeoutValue);
	}
	else {  // per specific table
	  if ( timeoutTdb().isReset() )  // it was a RESET
	    GlobalTimeouts->resetTableLockTimeout( theTableName_ );
	  else GlobalTimeouts->setTableLockTimeout(theTableName_,timeoutValue);
	}
      }

      // execution of every SET TIMEOUT stmt increments the change counter !!
      currContext->incrementTimeoutChangeCounter();

      // clear up (i.e. deallocate) the global timeout data, if possible
      if ( GlobalTimeouts->noLockTimeoutsSet() &&
	   ! GlobalTimeouts->isStreamTimeoutSet() )
	currContext->clearTimeoutData();

    } // end of if ( goodTimeoutValue )

    /**********  at this point the actual work is done  ******************/
      
    // all ok. Return EOF.
    ex_queue_entry * up_entry = qparent_.up->getTailEntry();
      
    up_entry->upState.parentIndex = 
      pentry_down->downState.parentIndex;
      
    up_entry->upState.setMatchNo(0);
    up_entry->upState.status = ex_queue::Q_NO_DATA;
      
    // insert into parent
    qparent_.up->insert();
    
    qparent_.down->removeHead();
  }  
  return WORK_OK;
}