Пример #1
0
int pmdEDUMgr::startEDU(EDU_TYPES type, void *arg, EDUID *eduid)
{
	int rc = EDB_OK;
	EDUID eduID = 0;
	pmdEDUCB* eduCB = NULL;
	std::map<EDUID, pmdEDUCB*>::iterator it;
	
	if (isQuiesced()) {
		rc = EDB_QUIESCED;
		goto done;	
	}

	_mutex.get();
	if (true == _idleQueue.empty() || !isPoolable(type)) {
		_mutex.release();
		rc = _createNewEDU(type, arg, eduid);
		if (EDB_OK == rc) {
			goto done;	
		} else {
			goto error;	
		}
	}

	for (it = _idleQueue.begin(); (_idleQueue.end() != it) && (PMD_EDU_IDLE != (*it).second->getStatus()); it++);

	if (_idleQueue.end() == it) {
		_mutex.release();
		rc = _createNewEDU(type, arg, eduid);
		if (EDB_OK == rc) {
			goto done;	
		} else {
			goto error;	
		}
	}

	eduID = (*it).first;
	eduCB = (*it).second;
	_idleQueue.erase(eduID);
	EDB_ASSERT(isPoolable(type), "must be agent.");

	eduCB->setType(type);
	eduCB->setStatus(PMD_EDU_WAITING);
	_runQueue[eduID] = eduCB;
	*eduid = eduID;
	_mutex.release();

	eduCB->postEvent(pmdEDUEvent(PMD_EDU_EVENT_RESUME, false, arg));

done:
	return rc;
error:
	goto done;
}
Пример #2
0
int pmdEDUMgr::returnEDU(EDUID eduID, bool force, bool* destroyed)
{
	int rc = EDB_OK;
	EDU_TYPES type = EDU_TYPE_UNKNOWN;
	pmdEDUCB* eduCB = NULL;
	std::map<EDUID, pmdEDUCB*>::iterator it;
	_mutex.get_shared();
	if (_runQueue.end() == (it = _runQueue.find(eduID))) {
		if (_idleQueue.end() == (it = _idleQueue.find(eduID))) {
			rc = EDB_SYS;
			*destroyed = false;
			_mutex.release_shared();
			goto error;	
		}	
	}	

	eduCB = (*it).second;
	if (eduCB) {
		type = eduCB->getType();	
	}
	_mutex.release_shared();

	if (!isPoolable(type) || force || isDestroyed()
		|| size() > (unsigned int) pmdGetKRCB()->getMaxPool())
	{
		rc = _destroyEDU(eduID);	
		if (destroyed) {
			if (EDB_OK == rc || EDB_SYS == rc) {
				*destroyed = true;
			} else {
				*destroyed = false;
			}		
		}
	} else {
		rc = _deactivateEDU(eduID);
		if (destroyed) {
			if (EDB_SYS == rc) {
				*destroyed = true;	
			} else {
				*destroyed = false;	
			}
		}	
	}

done:
	return rc;
error:
	goto done;
}
Пример #3
0
// creating/waiting status edu can be deactivated (pooled)
// deactivateEDU supposed only happened to AGENT EDUs
// any EDUs other than AGENT will be destroyed and EDB_SYS will be returned
int pmdEDUMgr::_deactivateEDU ( EDUID eduID )
{
   int rc         = EDB_OK ;
   unsigned int eduStatus = PMD_EDU_CREATING ;
   pmdEDUCB* eduCB  = NULL ;
   std::map<EDUID, pmdEDUCB*>::iterator it ;
   // cross queue operation, need X lock
   _mutex.get() ;
   if ( _runQueue.end () == ( it = _runQueue.find ( eduID )) )
   {
      // if it's not in run queue, then is it in idle queue?
      // if it's already idle, we don't need to do anything
      if ( _idleQueue.end() != _idleQueue.find ( eduID )  )
      {
         goto done ;
      }
      // we can't find EDU in run queue
      rc = EDB_SYS ;
      goto error ;
   }
   eduCB = ( *it ).second ;

   eduStatus = eduCB->getStatus () ;

   // if it's already idle, let's get out of here
   if ( PMD_IS_EDU_IDLE ( eduStatus ) )
      goto done ;

   if ( !PMD_IS_EDU_WAITING ( eduStatus ) &&
        !PMD_IS_EDU_CREATING ( eduStatus ) )
   {
      rc = EDB_EDU_INVAL_STATUS ;
      goto error ;
   }

   // only Agent can be deactivated (pooled), other system
   // EDUs can only be destroyed
   EDB_ASSERT ( isPoolable ( eduCB->getType() ),
                "Only agent can be pooled" )
   _runQueue.erase ( eduID ) ;
   eduCB->setStatus ( PMD_EDU_IDLE ) ;
   _idleQueue [ eduID ] = eduCB ;
done :
   _mutex.release () ;
   return rc ;
error :
   goto done ;
}
Пример #4
0
int pmdEDUMgr::_deactivateEDU(EDUID eduID)
{
	int rc				   = EDB_OK;
	unsigned int eduStatus = PMD_EDU_CREATING;	
	pmdEDUCB* eduCB = NULL;
	std::map<EDUID, pmdEDUCB*>::iterator it;
	_mutex.get();
	if (_runQueue.end() == (it = _runQueue.find(eduID))) {
		if (_idleQueue.end() == (it = _idleQueue.find(eduID))) {
			goto done;	
		}
		rc = EDB_SYS;
		goto error;
	}

	eduCB = (*it).second;
	eduStatus = eduCB->getStatus();
	if (PMD_IS_EDU_IDLE(eduStatus)) {
		goto done;	
	}

	if (!PMD_IS_EDU_WAITING(eduStatus) && !PMD_IS_EDU_CREATING(eduStatus)) {
		rc = EDB_EDU_INVAL_STATUS;
		goto error;	
	}

	EDB_ASSERT(isPoolable(eduCB->getType()), "Only agent can be pooled");
	_runQueue.erase(eduID);
	eduCB->setStatus(PMD_EDU_IDLE);
	_idleQueue[eduID] = eduCB;

done:
	_mutex.release();
	return rc;
error:
	goto done;
}
Пример #5
0
// get an EDU from idle pool, if idle pool is empty, create new one
int pmdEDUMgr::startEDU ( EDU_TYPES type, void* arg, EDUID *eduid)
{
   int     rc = EDB_OK ;
   EDUID     eduID = 0 ;
   pmdEDUCB* eduCB = NULL ;
   std::map<EDUID, pmdEDUCB*>::iterator it ;

   if ( isQuiesced () )
   {
      rc = EDB_QUIESCED ;
      goto done ;
   }
   /****************** CRITICAL SECTION **********************/
   // get exclusive latch, we don't latch the entire function
   // in order to avoid creating new thread while holding latch
   _mutex.get () ;
   // if there's any pooled EDU?
   // or is the request type can be pooled ?
   if ( true == _idleQueue.empty () || !isPoolable ( type ) )
   {
      // note that EDU types other than "agent" shouldn't be pooled at all
      // release latch before calling createNewEDU
      _mutex.release () ;
      rc = _createNewEDU ( type, arg, eduid ) ;
      if ( EDB_OK == rc )
         goto done ;
      goto error ;
   }

   // if we can find something in idle queue, let's get the first of it
   for ( it = _idleQueue.begin () ;
         ( _idleQueue.end () != it ) &&
         ( PMD_EDU_IDLE != ( *it ).second->getStatus ()) ;
         it ++ ) ;

   // if everything in idleQueue are in DESTROY status, we still need to
   // create a new EDU
   if ( _idleQueue.end () == it )
   {
      // release latch before calling createNewEDU
      _mutex.release () ;
      rc = _createNewEDU ( type, arg, eduid ) ;
      if ( EDB_OK == rc )
         goto done ;
      goto error ;
   }

   // now "it" is pointing to an idle EDU
   // note that all EDUs in the idleQueue should be AGENT type
   eduID = ( *it ).first ;
   eduCB = ( *it ).second ;
   _idleQueue.erase ( eduID ) ;
   EDB_ASSERT ( isPoolable ( type ),
                "must be agent" )
   // switch agent type for the EDU ( call different agent entry point )
   eduCB->setType ( type ) ;
   eduCB->setStatus ( PMD_EDU_WAITING ) ;
   _runQueue [ eduID ] = eduCB ;
   *eduid = eduID ;
   _mutex.release () ;
   /*************** END CRITICAL SECTION **********************/

   //The edu is start, need post a resum event
   eduCB->postEvent( pmdEDUEvent( PMD_EDU_EVENT_RESUME, false, arg ) ) ;

done :
   return rc ;
error :
   goto done ;
}
Пример #6
0
// release control from a given EDU
// EDUMgr should decide whether put the EDU to pool or destroy it
// EDU Status must be in waiting or creating
int pmdEDUMgr::returnEDU ( EDUID eduID, bool force, bool* destroyed )
{
   int rc        = EDB_OK ;
   EDU_TYPES type  = EDU_TYPE_UNKNOWN ;
   pmdEDUCB *educb = NULL ;
   std::map<EDUID, pmdEDUCB*>::iterator it ;
   // shared critical section
   _mutex.get_shared () ;
   if ( _runQueue.end() == ( it = _runQueue.find ( eduID ) ) )
   {
      if ( _idleQueue.end() == ( it = _idleQueue.find ( eduID ) ) )
      {
         rc = EDB_SYS ;
         *destroyed = false ;
         _mutex.release_shared () ;
         goto error ;
      }
   }
   educb = (*it).second ;
   // if we are trying to destry EDU manager, or enforce destroy, or
   // if the total number of threads are more than what we need
   // we need to destroy this EDU
   //
   // Currentl we only able to pool agent and coordagent
   if ( educb )
   {
      type = educb->getType() ;
   }
   _mutex.release_shared () ;

   // if the EDU type can't be pooled, or if we forced, or if the EDU is
   // destroied, or we exceed max pooled edus, let's destroy it
   if ( !isPoolable(type) || force || isDestroyed () ||
        size() > (unsigned int)pmdGetKRCB()->getMaxPool () )
   {
      rc = _destroyEDU ( eduID ) ;
      if ( destroyed )
      {
         // we consider the EDU is destroyed when destroyEDU returns
         // OK or EDB_SYS (edu can't be found), so that thread can terminate
         // itself
         if ( EDB_OK == rc || EDB_SYS == rc )
            *destroyed = true ;
         else
            *destroyed = false ;
      }
   }
   else
   {
      // in this case, we don't need to care whether the EDU is agent or not
      // as long as we treat EDB_SYS as "destroyed" signal, we should be
      // safe here
      rc = _deactivateEDU ( eduID ) ;
      if ( destroyed )
      {
         // when we try to pool the EDU, destroyed set to true only when
         // the EDU can't be found in the list
         if ( EDB_SYS == rc )
            *destroyed = true ;
         else
            *destroyed = false ;
      }
   }
done :
   return rc ;
error :
   goto done ;
}