int pmdEDUMgr::_createNewEDU(EDU_TYPES type, void* arg, EDUID *eduid) { int rc = EDB_OK; unsigned int probe = 0; pmdEDUCB *cb = NULL; EDUID myEDUID = 0; if (isQuiesced()) { rc = EDB_QUIESCED; goto done; } if (!getEntryFuncByType(type)) { PD_LOG(PDERROR, "The edu[type:%d] not exist or function is null", type); rc = EDB_INVALIDARG; probe = 30; goto error; } cb = new(std::nothrow) pmdEDUCB(this, type); EDB_VALIDATE_GOTOERROR(cb, EDB_OOM, "Out of memery to create agent control block"); cb->setStatus(PMD_EDU_CREATING); _mutex.get(); if (_runQueue.end() != _runQueue.find(_EDUID)) { _mutex.release(); rc = EDB_SYS; probe = 10; goto error; } if (_idleQueue.end() != _idleQueue.find(_EDUID)) { _mutex.release(); rc = EDB_SYS; probe = 15; goto error; } cb->setId(_EDUID); if (eduid) { *eduid = _EDUID; } _runQueue[_EDUID] = (pmdEDUCB*) cb; myEDUID = _EDUID; ++_EDUID; _mutex.release(); try { boost::thread agentThread(pmdEDUEntryPoint, type, cb, arg); agentThread.detach(); } catch (std::exception e) { _runQueue.erase(myEDUID); rc = EDB_SYS; probe = 20; goto error; } cb->postEvent(pmdEDUEvent(PMD_EDU_EVENT_RESUME, false, arg)); done: return rc; error: if (cb) { delete cb; } PD_LOG(PDERROR, "Failed to create new agent, probe = %d", probe); goto done; }
// whoever calling this function should NOT get latch int pmdEDUMgr::_createNewEDU ( EDU_TYPES type, void* arg, EDUID *eduid) { int rc = EDB_OK ; unsigned int probe = 0 ; pmdEDUCB *cb = NULL ; EDUID myEDUID = 0 ; if ( isQuiesced () ) { rc = EDB_QUIESCED ; goto done ; } if ( !getEntryFuncByType ( type ) ) { PD_LOG ( PDERROR, "The edu[type:%d] not exist or function is null", type ) ; rc = EDB_INVALIDARG ; probe = 30 ; goto error ; } cb = new(std::nothrow) pmdEDUCB ( this, type ) ; EDB_VALIDATE_GOTOERROR ( cb, EDB_OOM, "Out of memory to create agent control block" ) // set to creating status cb->setStatus ( PMD_EDU_CREATING ) ; /***********CRITICAL SECTION*********************/ _mutex.get () ; // if the EDU exist in runqueue if ( _runQueue.end() != _runQueue.find ( _EDUID ) ) { _mutex.release () ; rc = EDB_SYS ; probe = 10 ; goto error ; } // if the EDU exist in idle queue if ( _idleQueue.end() != _idleQueue.find ( _EDUID ) ) { _mutex.release () ; rc = EDB_SYS ; probe = 15 ; goto error ; } // assign EDU id and increment global EDUID cb->setID ( _EDUID ) ; if ( eduid ) *eduid = _EDUID ; // place cb into runqueue _runQueue [ _EDUID ] = ( pmdEDUCB* ) cb ; myEDUID = _EDUID ; ++_EDUID ; _mutex.release () ; /***********END CRITICAL SECTION****************/ // create a new thread here, pass agent CB and other arguments try { boost::thread agentThread ( pmdEDUEntryPoint, type, cb, arg ) ; // detach the agent so that he's all on his own // we only track based on CB agentThread.detach () ; } catch ( std::exception e ) { // if we failed to create thread, make sure to clean runqueue _runQueue.erase ( myEDUID ) ; rc = EDB_SYS ; probe = 20 ; goto error ; } //The edu is create, need post a resum event cb->postEvent( pmdEDUEvent( PMD_EDU_EVENT_RESUME, false, arg ) ) ; done : return rc ; error : // clean out memory if it's allocated if ( cb ) delete cb ; PD_LOG ( PDERROR, "Failed to create new agent, probe = %d", probe ) ; goto done ; }