?? clientimpleventmanager.cpp
字號:
/*
Copyright (c) 2008, Intel Corporation.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
* Neither the name of Intel Corporation nor the names of its contributors
may be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
OF SUCH DAMAGE.
*/#include "base_EventClient_Impl.h"#include "base_Observer_Impl.h"#include "ClientImplEventManager.h"#include "base_Exception.h"#include <algorithm>//CClientImplEventManager g_ClientImplEventManagerInst;extern "C" void MonitorTrigger(BOOL bStart){ if(bStart) CClientImplEventManager::GetClientImplEventManagerInst().StartMonitor(); else CClientImplEventManager::GetClientImplEventManagerInst().EndMonitor(); /* if(bStart) g_ClientImplEventManagerInst.StartMonitor(); else g_ClientImplEventManagerInst.EndMonitor();*/}////////////////////////////////////////////////////////////////////////////////////CMapEventType2EventBindCMapEventType2EventBind::CMapEventType2EventBind(){ m_MapEventType2EventBind.clear();}CMapEventType2EventBind::~CMapEventType2EventBind(){ MapEventType2EventBind::iterator it = m_MapEventType2EventBind.begin(); for(; it != m_MapEventType2EventBind.end(); it++) delete it->second;}bool CMapEventType2EventBind::HasAddedObserver(Event::EventType eType){ MapEventType2EventBind::iterator it = m_MapEventType2EventBind.find(eType); if(it != m_MapEventType2EventBind.end()) return true; else return false;}void CMapEventType2EventBind::RemoveEventBind(Event::EventType eType, BOOL &bDeleteMap){ MapEventType2EventBind::iterator itr = m_MapEventType2EventBind.find(eType); if(itr != m_MapEventType2EventBind.end()) { delete itr->second; m_MapEventType2EventBind.erase(itr); if(m_MapEventType2EventBind.size() == 0) bDeleteMap = TRUE; else bDeleteMap = FALSE; }}//given [(ServerObject *) + Event::EventType], find respondent (CEventBind *),//if not exist && bCreateNoneExist, create itCEventBind *CMapEventType2EventBind::GetEventBind( EventClientImpl *pEvtCltImp, Event::EventType eType, BOOL bCreateNoneExist/* = TRUE*/){ MapEventType2EventBind::iterator itr = m_MapEventType2EventBind.find(eType); if(itr != m_MapEventType2EventBind.end()) return itr->second; else if(bCreateNoneExist) { CEventBind *pEb = new CEventBind(pEvtCltImp, eType); pair<Event::EventType, CEventBind *> ePair(eType, pEb); m_MapEventType2EventBind.insert(ePair); return pEb; } else return NULL;}//CMapEventType2EventBind//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////CClientEventMapManagerCClientEventMapManager::CClientEventMapManager(){ m_mapSvrObj.clear();CClientEventMapManager::~CClientEventMapManager(){ MapSvrObj::iterator it = m_mapSvrObj.begin(); for(; it != m_mapSvrObj.end(); it++) delete it->second;}bool CClientEventMapManager::HasAddedObserver(void *pSvrObj, Event::EventType eType){ MapSvrObj::iterator it = m_mapSvrObj.find(pSvrObj); if(it != m_mapSvrObj.end()) { CMapEventType2EventBind *pMap = it->second; return pMap->HasAddedObserver(eType); } else return false;}//given [(ServerObject *) + Event::EventType], find respondent (CEventBind *),//if not exist && bCreateNoneExist, create it//EventClientImpl * is not persistent while the underlying ServerObject * isCEventBind *CClientEventMapManager::GetEventBind(EventClientImpl *pEvtCltImp, Event::EventType eType, BOOL bCreateNoneExist/* = TRUE*/){ CMapEventType2EventBind *pMapEventType2EventBind = NULL; void *pSvrObj = pEvtCltImp->GetSvrObj(); MapSvrObj::iterator itr = m_mapSvrObj.find(pSvrObj); if(itr != m_mapSvrObj.end()) pMapEventType2EventBind = itr->second; else if(bCreateNoneExist) { pMapEventType2EventBind = new CMapEventType2EventBind(); m_mapSvrObj.insert(pair<void *, CMapEventType2EventBind *>(pSvrObj, pMapEventType2EventBind)); } if(pMapEventType2EventBind) return pMapEventType2EventBind->GetEventBind(pEvtCltImp, eType, bCreateNoneExist); else return NULL;}void CClientEventMapManager::RemoveEventBind(EventClientImpl *pEvtCltImp, Event::EventType eType){ void *pSvrObj = pEvtCltImp->GetSvrObj(); MapSvrObj::iterator itr = m_mapSvrObj.find(pSvrObj); if(itr != m_mapSvrObj.end()) { CMapEventType2EventBind *pMapEventType2EventBind = itr->second; BOOL bDeleteMap; pMapEventType2EventBind->RemoveEventBind(eType, bDeleteMap); if(bDeleteMap) { delete pMapEventType2EventBind; m_mapSvrObj.erase(itr); } }}//CClientEventMapManager////////////////////////////////////////////////////////////////////////////////////CClientImplEventManager CClientImplEventManager::s_ClientImplEventManagerInst;CClientImplEventManager s_ClientImplEventManagerInst;//////////////////////////////////////////////////////////////////////// Construction/Destruction//////////////////////////////////////////////////////////////////////CClientImplEventManager::CClientImplEventManager(){ //cout << "CClientImplEventManager::CClientImplEventManager" << endl; m_hCtrlEvent = CreateEvent(NULL, FALSE, FALSE, NULL); InitializeCriticalSection(&m_cs); m_nEventCount = 0; m_hMonitorThread = INVALID_HANDLE_VALUE; m_mapObserversOnSameEvent.clear(); memset(m_arrayEventHandle, 0, sizeof(HANDLE) * MAXIMUM_WAIT_OBJECTS); MonitorTrigger(TRUE);//nhu}CClientImplEventManager::~CClientImplEventManager(){ EndMonitor(); //cout << "CClientImplEventManager::~CClientImplEventManager" << endl; DeleteCriticalSection(&m_cs); CloseHandle(m_hCtrlEvent); MapObserversOnSameEvent::iterator it = m_mapObserversOnSameEvent.begin(); for(; it != m_mapObserversOnSameEvent.end(); it++) delete (*it).second;}const ObserverImpl* CClientImplEventManager::GetObserver(HANDLE hEvent, unsigned int nIndex ){ const ObserverImpl* pObserver = NULL; EnterCriticalSection(&m_cs); try { MapObserversOnSameEvent::iterator it = m_mapObserversOnSameEvent.find(hEvent); if(it != m_mapObserversOnSameEvent.end()) { CObserversOnSameEvent* m_vObservers = (*it).second; if ( nIndex < m_vObservers->GetObservCount()) { pObserver = m_vObservers->GetObserver(nIndex); } } } catch(...) { LeaveCriticalSection(&m_cs); IntelMobileException ex( IntelMobileText("Operation Error"), IntelMobileText("CClientImplEventManager"), IntelMobileText("GetObserver") ); throw( ex ); } LeaveCriticalSection(&m_cs); return pObserver;}bool CClientImplEventManager::RemoveObservers(HANDLE hEvent ){ bool bRemoved = true; EnterCriticalSection(&m_cs); try { MapObserversOnSameEvent::iterator it = m_mapObserversOnSameEvent.find(hEvent); if(it != m_mapObserversOnSameEvent.end()) { CObserversOnSameEvent* m_vObservers = (*it).second; m_vObservers->RemoveObservers(); m_mapObserversOnSameEvent.erase(it); delete m_vObservers;// m_nThreadCtrlFlag = nDELETE_EVENT_FROM_MONITOR; //event handle is added / removed only by main thread DeleteEventFromMonitor(hEvent); SetEvent(m_hCtrlEvent); } } catch(...) { LeaveCriticalSection(&m_cs); bRemoved = false; IntelMobileException ex( IntelMobileText("Operation Error"), IntelMobileText("CClientImplEventManager"), IntelMobileText("RemoveObserver") ); throw( ex ); } LeaveCriticalSection(&m_cs); return bRemoved;}unsigned int CClientImplEventManager::GetObserverCount( HANDLE hEvent ){ unsigned int iCount = 0; EnterCriticalSection(&m_cs); try { MapObserversOnSameEvent::iterator it = m_mapObserversOnSameEvent.find(hEvent); if(it != m_mapObserversOnSameEvent.end()) { //the event handle exist,add the observer to its observer_list iCount = (*it).second->GetObservCount(); } } catch(...) { LeaveCriticalSection(&m_cs); IntelMobileException ex( IntelMobileText("Operation Error"), IntelMobileText("CClientImplEventManager"), IntelMobileText("GetObserverCount") ); throw( ex ); } LeaveCriticalSection(&m_cs); return iCount;}BOOL CClientImplEventManager::StartMonitor(){ //cout<<"startmonitor!\n"; try { //cout << "m_hMonitorThread " << m_hMonitorThread << endl; if(m_hMonitorThread == INVALID_HANDLE_VALUE) {// m_nThreadCtrlFlag = nSTART_THREAD; m_bStopMonitorThread = FALSE; //the 1st should be m_hCtrlEvent to monitor if(m_nEventCount == 0) { //cout << "AddEvent2Monitor is "<< m_hCtrlEvent << endl; AddEvent2Monitor(m_hCtrlEvent); } //cout << "Before CreateThread" << endl; m_hMonitorThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)MonitorThreadProc, this, 0, &m_dwThreadId); } } catch(...) { IntelMobileException ex( IntelMobileText("Operation Error"), IntelMobileText("CClientImplEventManager"), IntelMobileText("OnUnderlayingEvent") ); throw( ex ); } return (m_hMonitorThread != INVALID_HANDLE_VALUE);}DWORD WINAPI CClientImplEventManager::MonitorThreadProc(LPVOID lpParam){ //cout << "MonitroThreadProc Begine" << endl; try { CClientImplEventManager *pEventMgr = (CClientImplEventManager *)lpParam; //while(nSTOP_THREAD != pEventMgr->m_nThreadCtrlFlag) while(FALSE == pEventMgr->m_bStopMonitorThread) { //cout<<"Before WaitForEvents\t"<<endl; DWORD dwRtn = pEventMgr->WaitForEvents(); //cout<<"After WaitForEvents"<<endl; switch(dwRtn) { case WAIT_OBJECT_0: //control event: //nSTOP_THREAD/nADD_EVENT_FOR_MONITOR/nDELETE_EVENT_FROM_MONITOR //event handle is added / removed only by main thread //pEventMgr->OnCtrlEvent(); //cout << "WAIT_OBJECT_0" << endl; break; default://Underlaying Event //cout << "Underlaying Event" << endl; pEventMgr->OnUnderlayingEvent(dwRtn - WAIT_OBJECT_0); break; } } //cout << "MonitorThreadProc Finish" << endl; } catch(...) { IntelMobileException ex( IntelMobileText("Operation Error"), IntelMobileText("CClientImplEventManager"), IntelMobileText("OnUnderlayingEvent") ); throw( ex ); } return 0;}//add a new event to monitor//return false if try to monitor more than 63 eventsBOOL CClientImplEventManager::AddEvent2Monitor(HANDLE hEvent){ BOOL bRtn = TRUE; EnterCriticalSection(&m_cs); if(MAXIMUM_WAIT_OBJECTS == m_nEventCount) { //WaitForMultipleObjects can monitor no more than 64 events bRtn = FALSE; } else m_arrayEventHandle[m_nEventCount++] = hEvent; LeaveCriticalSection(&m_cs); return bRtn;}void CClientImplEventManager::EndMonitor(){ try { if(m_hMonitorThread != INVALID_HANDLE_VALUE) {// m_nThreadCtrlFlag = nSTOP_THREAD; m_bStopMonitorThread = TRUE; //cout << "EndMonitor handle is " << m_hCtrlEvent << endl; /* if(SetEvent(m_hCtrlEvent))//set special event to notify monitoring thread //cout << "SetEvent Success\n"; else //cout << "SetEvent Fail\n"; */ SetEvent(m_hCtrlEvent); //wait the end of the monitor thread for 5 seconds, prevent from resource leak if(WAIT_TIMEOUT == WaitForSingleObject(m_hMonitorThread, 5 * 1000)) TerminateThread(m_hMonitorThread, 0);//Terminate Thread rudely //CloseHandle(m_hMonitorThread); m_hMonitorThread = INVALID_HANDLE_VALUE; m_nEventCount = 0; memset(m_arrayEventHandle, 0, sizeof(HANDLE) * MAXIMUM_WAIT_OBJECTS); } } catch(...) { IntelMobileException ex( IntelMobileText("Operation Error"), IntelMobileText("CClientImplEventManager"), IntelMobileText("EndMonitor") ); throw( ex ); }}// Update the theEvent of the EventHandlebool CClientImplEventManager::UpdateEventOfHandle(HANDLE hEvent, Event &pTheEvent){ bool bRtn = true;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -