int pmdEDUMgr::postEDUPost ( EDUID eduID, pmdEDUEventTypes type, bool release , void *pData ) { int rc = EDB_OK ; pmdEDUCB* eduCB = NULL ; std::map<EDUID, pmdEDUCB*>::iterator it ; // shared lock the block, since we don't change anything _mutex.get_shared () ; if ( _runQueue.end () == ( it = _runQueue.find ( eduID )) ) { // if we cannot find it in runqueue, we search for idle queue // note that during the time, we already have EDUMgr locked, // so thread cannot change queue from idle to run // that means we are safe to exame both queues if ( _idleQueue.end () == ( it = _idleQueue.find ( eduID )) ) { // we can't find edu id anywhere rc = EDB_SYS ; goto error ; } } eduCB = ( *it ).second ; eduCB->postEvent( pmdEDUEvent ( type, release, pData ) ) ; done : _mutex.release_shared () ; return rc ; error : goto done ; }
void _replMsgHandler::_postMainMsg( const NET_HANDLE &handle, MsgHeader *pNewMsg ) { pNewMsg->TID = (UINT32)CLS_REPL ; _pMgrEDUCB->postEvent( pmdEDUEvent( PMD_EDU_EVENT_MSG, PMD_EDU_MEM_ALLOC, pNewMsg, (UINT64)handle ) ) ; }
// PD_TRACE_DECLARE_FUNCTION ( SDB__PMDEDUCB_DISCONNECT, "_pmdEDUCB::disconnect" ) void _pmdEDUCB::disconnect () { PD_TRACE_ENTRY ( SDB__PMDEDUCB_DISCONNECT ); ossScopedRWLock assist ( &_callInMutex, SHARED ) ; interrupt () ; _ctrlFlag |= EDU_CTRL_DISCONNECTED ; postEvent ( pmdEDUEvent ( PMD_EDU_EVENT_TERM ) ) ; PD_TRACE_EXIT ( SDB__PMDEDUCB_DISCONNECT ); }
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; }
void _shdMsgHandler::_postMainMsg( const NET_HANDLE & handle, MsgHeader * pNewMsg ) { if ( _pShardCB && ( MSG_CAT_NODEGRP_RES == (UINT32)pNewMsg->opCode || MSG_CAT_QUERY_CATALOG_RSP == (UINT32)pNewMsg->opCode || MSG_CAT_QUERY_SPACEINFO_RSP == (UINT32)pNewMsg->opCode || ( MSG_CAT_CATGRP_RES == (UINT32)pNewMsg->opCode && _pShardCB->getTID() != (UINT32)pNewMsg->requestID ) ) ) { _pShardCB->postEvent( pmdEDUEvent( PMD_EDU_EVENT_MSG, PMD_EDU_MEM_ALLOC, pNewMsg, (UINT64)handle ) ) ; } else { pNewMsg->TID = (UINT32)CLS_SHARD ; _pMgrEDUCB->postEvent( pmdEDUEvent( PMD_EDU_EVENT_MSG, PMD_EDU_MEM_ALLOC, pNewMsg, (UINT64)handle ) ); } }
// PD_TRACE_DECLARE_FUNCTION ( SDB_NETMLTRTAGT_HNDMSG, "netMultiRouteAgent::handleMsg" ) INT32 netMultiRouteAgent::handleMsg( const NET_HANDLE &handle, const _MsgHeader *header, const CHAR *msg ) { INT32 rc = SDB_OK; PD_TRACE_ENTRY ( SDB_NETMLTRTAGT_HNDMSG ); CHAR *pMsgRsp = (CHAR *)SDB_OSS_MALLOC( header->messageLength ); PD_CHECK( pMsgRsp, SDB_OOM, error, PDERROR, "Memory malloc failed(size = %d)", header->messageLength ) ; ossMemcpy( pMsgRsp, msg, header->messageLength ); { ossScopedLock _lock( &_mutex, SHARED ) ; COORD_SESSION_MAP::iterator it = _sessionMap.find( header->TID ); if ( _sessionMap.end() != it ) { it->second->postEvent( pmdEDUEvent( PMD_EDU_EVENT_MSG, PMD_EDU_MEM_ALLOC, pMsgRsp ) ) ; } else { PD_LOG( PDWARNING, "Recieve expired msg[opCode:[%d]%d, TID:%d," "ReqID:%lld] from node[%d:%d:%d]", IS_REPLY_TYPE( header->opCode ), GET_REQUEST_TYPE( header->opCode ), header->TID, header->requestID, header->routeID.columns.groupID, header->routeID.columns.nodeID, header->routeID.columns.serviceID ) ; rc = SDB_SYS ; goto error ; } } done: PD_TRACE_EXITRC ( SDB_NETMLTRTAGT_HNDMSG, rc ); return rc ; error: if ( pMsgRsp ) { SDB_OSS_FREE( pMsgRsp ) ; } goto done ; }
// PD_TRACE_DECLARE_FUNCTION ( SDB_COORDSN_DISCONN, "CoordSession::disConnect" ) INT32 CoordSession::disConnect( const MsgRouteID &routeID ) { INT32 rc = SDB_OK; PD_TRACE_ENTRY ( SDB_COORDSN_DISCONN ); BOOLEAN hasSession = FALSE; { ossScopedLock _lock( &_mutex ) ; COORD_SUBSESSION_MAP::iterator it; it = _subSessionMap.find( routeID.value ); if ( it != _subSessionMap.end() ) { hasSession = TRUE; it->second.isConnected = FALSE; } } if ( hasSession ) { MsgOpReply *pMsg = (MsgOpReply *)SDB_OSS_MALLOC( sizeof(MsgOpReply) ); if ( NULL != pMsg ) { pMsg->header.messageLength = sizeof(MsgOpReply); pMsg->header.opCode = MSG_COOR_REMOTE_DISC; pMsg->header.routeID = routeID; pMsg->header.requestID = pmdGetKRCB()->getCoordCB( )->getRouteAgent()->reqIDNew(); pMsg->flags = SDB_COORD_REMOTE_DISC; pMsg->numReturned = 0; pMsg->contextID = -1 ; pMsg->startFrom = 0 ; _pEduCB->postEvent ( pmdEDUEvent( PMD_EDU_EVENT_MSG, PMD_EDU_MEM_ALLOC, pMsg ) ) ; } else { rc = SDB_OOM; PD_LOG( PDERROR, "malloc failed(size=%d)", sizeof(MsgHeader) ); } } PD_TRACE_EXITRC ( SDB_COORDSN_DISCONN, rc ); return rc; }
int pmdEDUMgr::postEDUPost(EDUID eduID, pmdEDUEventTypes type, bool release, void *pData) { int rc = EDB_OK; 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; goto error; } } eduCB = (*it).second; eduCB->postEvent(pmdEDUEvent (type, release, pData)); done: _mutex.release_shared(); return rc; error: goto done; }
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 ; }
// 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 ; }
// PD_TRACE_DECLARE_FUNCTION ( SDB_DPSLOCKBUCKET_WAKEUP, "dpsLockBucket::wakeUp" ) void dpsLockBucket::wakeUp( _pmdEDUCB *eduCB ) { eduCB->postEvent( pmdEDUEvent( PMD_EDU_EVENT_LOCKWAKEUP, PMD_EDU_MEM_NONE, NULL )); PD_TRACE_EXIT ( SDB_DPSLOCKBUCKET_WAKEUP ); }