CStatus CThreadForMsgLoop::Run(void * pContext) { if(m_pThread == 0) { return CStatus(-1,0,"In CThreadForMsgLoop::Run : m_pThread is null"); } CEvent event; CThreadInitialFinishedNotifier notifier(&event); SInitialParameter para; para.pContext = pContext; para.pNotifier = ¬ifier; CStatus s_r = m_pThread->Run(¶); if(!s_r.IsSuccess()) { m_bWaitForDeath = false; m_pThread = 0; return CStatus(-1,0,"In CThreadForMsgLoop::Run invoke run failed!"); } //主线程等待子线程初始化完毕 CStatus s_w = event.Wait(); if(!s_w.IsSuccess()) return s_w; //判断子线程初始化是否成功 if(!notifier.IsInitialSuccess()) return CStatus(-1,0,"In CThreadForMsgLoop::Run : Thread initial failed"); else return CStatus(0,0); }
/* * === FUNCTION ====================================================================== * Name: Register * Description: 把消息的类型ID和此类消息的处理对象注册到分发表中 * ===================================================================================== */ CStatus CMessageLoopManager::Register(unsigned int iMsgTypeID, CallBackFunctionOfMsgObserver pFunction) { if(0 == pFunction) { return CStatus(-1,0,"in Register of CMessageLoopManager : pMsgObserver is null"); } m_MsgFuncMappingTable[iMsgTypeID] = pFunction; return CStatus(0,0); }
CStatus CMessageLoopManager::EnterMessageLoop(void * pContext) { //允许传递给线程的参数是NULL型,表示不传递参数,所以不做检查 //1、进入消息循环前,允许消息循环做一些初始化的工作 CStatus s1 = Initialize(); if(!s1.IsSuccess()) return s1; //在进入消息循环前,调用观察者的初始化函数 CStatus s_initOfMsgObserver = m_pMsgObserver->Initialize(this,pContext); if(!s_initOfMsgObserver.IsSuccess()) return s_initOfMsgObserver; //3、消息队列的拥有线程owner开始进入一个死循环(即消息循环机制) //owner 阻塞的一直从消息队列中读取other线程发给它的消息 //然后根据自己手中的消息分发表,将消息派送给不同的消息处理类去 //处理消息。 //当任何其他线程向他发送一个退出消息后,owner结束处理消息的工作j while(true) { int failed_counter = 0; CMessage * pMsg = WaitForMessage(); if(0 == pMsg) { //如果等待消息失败超过5次,就认为消息队列出问题 //推出消息循环 if(failed_counter++ < WaitForMessageFailedTimes) continue; else return CStatus(-1,0,"in EnterMessageLoop of CMessageLoopManager : wait for message faild"); } CStatus s2 = DispatchMessage(pMsg); if(!s2.IsSuccess()) return s2; if(s2.m_ciReturnCode == QUIT_MESSAGE_LOOP) break; } //5、允许消息队列做一些收尾工作 CStatus s3 = Uninitialize(); if(!s3.IsSuccess()) return s3; return CStatus(0,0); }
/* * === FUNCTION ====================================================================== * Name: Push * Description: 以互斥的方式向消息队列中插入一条消息 * ===================================================================================== */ CStatus CUsrDefMsgQueue::Push(CMessage * pMsg) { CEnterCriticalSection ecs(&m_Mutex); if( IsFull() ) { CStatus s = EnlargeQueue(); if(!s.IsSuccess()) return CStatus(-1,0,"failed to Enlarge the queue!"); } m_pQueueSpace[m_iQueueTail] = pMsg; m_iQueueTail = (m_iQueueTail + 1) % m_iTotalRoom; return CStatus(0,0); }
/* * === FUNCTION ====================================================================== * Name: EnlargeQueue * Description: 扩展当前的消息队列 * ===================================================================================== */ CStatus CUsrDefMsgQueue::EnlargeQueue() { CMessage ** p = new CMessage * [m_iTotalRoom+QUEUE_AUTO_INCREMENT_SIZE]; int index = 0; //队列中有一个单元不用,所以当队列满的状况下共有元素 m_iTotalRoom - 1 个 //将这m_iTotalRoom - 1个元素拷贝到新存储单元中去, for(int i = 0; i < m_iTotalRoom - 1; i++) { index = (m_iQueueHead+i) % m_iTotalRoom; p[i] = m_pQueueSpace[index]; } //新队列从下表0开始存储,所以转存完后要校准队列头和尾的位置 m_iQueueHead = 0; m_iQueueTail = m_iTotalRoom - 1; m_iTotalRoom += QUEUE_AUTO_INCREMENT_SIZE; delete m_pQueueSpace; m_pQueueSpace = p; return CStatus(0,0); }
CCommunicationByMsgQueue:: CCommunicationByMsgQueue(CUsrDefMsgQueue * pMsgQueue) { if(0 == pMsgQueue) { std::cout <<"in construction of CCommunicationByMessageQueue : paremeter is null"<< std::endl; throw CStatus(-1,0); } m_pMsgQueue = pMsgQueue; }
//在构造函数中,初始化指向业务逻辑的成员变量 CExecutiveObject::CExecutiveObject(IUsrBizForExecObj * pUsrBizForExecObj) { if(0 == pUsrBizForExecObj) { std::cout<<"In CExecutiveObject::Construction pUsrBizForExecObj is null"<<std::endl; throw CStatus(-1,0); } m_pUsrBizForExecObj = pUsrBizForExecObj; }
CUsrBizUsingMsgLoop::CUsrBizUsingMsgLoop(CMsgLoopManager *pMsgLoopManager) { if(0 == pMsgLoopManager) { std::cout <<"In CUsrBizUsingMsgLoop::Construction pMsgLoopManager is null"<<std::endl; throw CStatus(-1,0); } m_pMsgLoopManager = pMsgLoopManager; }
CStatus CCommunicationByMsgQueue:: PostMessage(CMessage * pMsg) { if(0 == pMsg) { std::cout <<"in PostMessage of CCommunicationByMessageQueue: paremeter is null"<<std::endl; return CStatus(-1,0); } return m_pMsgQueue->PushMessage(pMsg); }
CThreadForMsgLoop:: CThreadForMsgLoop(const char * strThreadName,CMessageObserver * pMsgObserver,bool bWaitForDeath) { if(0 == strThreadName || 0 == pMsgObserver) { throw CStatus(-1,0,"In Construction of CThreadForMsgLoop,paremeter is null"); } m_bWaitForDeath =bWaitForDeath; m_pThread = new CThread(new CClientBizUsingMsgLoop(new CMsgLoopMgrForUserDefinedQueue(strThreadName,pMsgObserver)),bWaitForDeath); }
/* * === FUNCTION ====================================================================== * Name: PushMessage * Description: 向消息队列中插入一条消息,同时使用事件来通知消息读取者新增了一条消息 * ===================================================================================== */ CStatus CUsrDefMsgQueue::PushMessage(CMessage * pMsg) { if(NULL == pMsg) { return CStatus(-1,0,"in PushMessage of CMessageQueueByUserDefined : pMsg is NULL"); } CStatus s1 = Push(pMsg); if( !s1.IsSuccess() ) { return s1; } CStatus s2 = m_Event.Set(); if(!s2.IsSuccess()) { return s2; } return CStatus(0,0); }
/* * === FUNCTION ====================================================================== * Name: DispatchMessage * Description: 消息循环用来派送消息的函数 * 具体做法是:根据消息的ID,去自己手中的分发表(map)中 * 查找相应的处理类,然后调用他们的虚函数(统一的消息处理 * 接口) * ===================================================================================== */ CStatus CMessageLoopManager::DispatchMessage(CMessage * pMsg) { if(0 == pMsg) { return CStatus(-1,0,"in DispatchMessage of CMessageLoopManager:bad paremeter ,pmsg is null"); } //遍历查找消息处理函数 std::map<unsigned int,CMessageObserver *>::iterator it; it = m_MsgFuncMappingTable.find(pMsg->m_clMsgID); if(it == m_MsgFuncMappingTable.end()) { return CStatus(-1,0,"尚未注册该消息"); } CallBackFunctionOfMsgObserver pFunction = it->second; if(pFunction != 0) return (m_pMsgObserver->*pFunction)(pMsg); else return CStatus(-1,0,"该消息没有注册处理类"); }
//-------------------------------------------------------------------------------- int CStatus::Error(LPCTSTR pFormat, ...) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); if(! IsDisplayed()) return 0; va_list marker; va_start(marker, pFormat); char temp[2048]; int nCount = vsprintf(temp, pFormat, marker); CStatus(temp, EVENTLOG_ERROR_TYPE); return nCount; }
//-------------------------------------------------------------------------------- int CStatus::Trace(CStatus::eLevel nLevel, LPCTSTR pFormat, ...) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); if(! IsDisplayed(nLevel)) return 0; va_list marker; va_start(marker, pFormat); char temp[2048]; int nCount = vsprintf(temp, pFormat, marker); CStatus(nLevel, temp); return nCount; }
//-------------------------------------------------------------------------------- int CStatus::Log(WORD nEventType, LPCTSTR pFormat, ...) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); if(! IsDisplayed()) return 0; va_list marker; va_start(marker, pFormat); char temp[2048]; int nCount = vsprintf(temp, pFormat, marker); CStatus(temp, nEventType); return nCount; }
//-------------------------------------------------------------------------------- CStatus::CStatus(LPCTSTR lpszMsg, WORD wEventType, DWORD dwEventID) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); m_nRefCount++; eLevel nLevel = S_LOG; CString sEventType; switch(wEventType) { case EVENTLOG_ERROR_TYPE: sEventType = "EVENTLOG_ERROR_TYPE"; nLevel = S_ERROR; break; case EVENTLOG_WARNING_TYPE: sEventType = "EVENTLOG_WARNING_TYPE"; break; case EVENTLOG_INFORMATION_TYPE: sEventType = "EVENTLOG_INFORMATION_TYPE"; break; case EVENTLOG_AUDIT_SUCCESS: sEventType = "EVENTLOG_AUDIT_SUCCESS"; break; case EVENTLOG_AUDIT_FAILURE: sEventType = "EVENTLOG_AUDIT_FAILURE"; break; default: sEventType = "Unknown"; break; } sEventType = "Type: " + sEventType; CString sEventId; sEventId.Format("ID: %ld", dwEventID); CStatus(nLevel, lpszMsg, NULL, 0, sEventType, sEventId); }
CStatus CMessageLoopManager::EnterMessageLoop(void * pContext) { //允许传递给线程的参数是NULL型,表示不传递参数,所以不做检查 //1、进入消息循环前,允许消息循环做一些初始化的工作 CStatus s1 = Initialize(); if(!s1.IsSuccess()) return s1; //2、线程创建时,也许会给某些消息处理类通过pContext传递一些参数 //所以编类所有的消息处理类,挨个的调用他们的初始化函数,把参数传递 //给他们(这里我们是不会管会不会某些处理类不需要参数来初始化自己的) //如果不许要,直接丢弃掉参数就好 std::map<unsigned int, CMessageObserver *>::iterator it1; for(it1 = m_MsgFuncMappingTable.begin(); it1 != m_MsgFuncMappingTable.end(); it1++) { it1->second->Initialize(pContext); } //3、消息队列的拥有线程owner开始进入一个死循环(即消息循环机制) //owner 阻塞的一直从消息队列中读取other线程发给它的消息 //然后根据自己手中的消息分发表,将消息派送给不同的消息处理类去 //处理消息。 //当任何其他线程向他发送一个退出消息后,owner结束处理消息的工作j while(true) { int failed_counter = 0; CMessage * pMsg = WaitForMessage(); if(0 == pMsg) { //如果等待消息失败超过5次,就认为消息队列出问题 //推出消息循环 if(failed_counter++ < WaitForMessageFailedTimes) continue; else return CStatus(-1,0,"in EnterMessageLoop of CMessageLoopManager : wait for message faild"); } CStatus s2 = DispatchMessage(pMsg); if(!s2.IsSuccess()) return s2; if(s2.m_ciReturnCode == QUIT_MESSAGE_LOOP) break; } //4、等消息循环退出后,说明消息队列的拥有线程不再处理任何发给 //它的消息了。此时应该把该消息队列中的所有对象销毁 std::map<unsigned int, CMessageObserver *>::iterator it2; for(it2 = m_MsgFuncMappingTable.begin(); it2 != m_MsgFuncMappingTable.end(); it2++) { delete it2->second; } //5、允许消息队列做一些收尾工作 CStatus s3 = Uninitialize(); if(!s3.IsSuccess()) return s3; return CStatus(0,0); }