#pragma once #include using namespace std; template class MsgLoop { size_t m_MaxThreshold; HANDLE m_Lock; HANDLE m_NotifyInQue; deque m_DataQueue; public: MsgLoop(void) { m_MaxThreshold = 0; m_Lock = CreateMutex(0,0,0); m_NotifyInQue = CreateEvent(0,1,0,0); }; ~MsgLoop(void) { Clear(); CloseHandle(m_Lock); CloseHandle(m_NotifyInQue); }; void init(size_t LoopThreshold) { m_MaxThreshold = LoopThreshold; }; bool Clear() { ResetEvent(m_NotifyInQue); WaitForSingleObject(m_Lock,INFINITE); m_DataQueue.clear(); ReleaseMutex(m_Lock); return true; }; MsgLoop& operator = (const MsgLoop &tValue) { if(this != &tValue) { WaitForSingleObject(m_Lock, INFINITE); WaitForSingleObject(tValue.m_Lock, INFINITE); m_DataQueue = tValue.m_DataQueue; ReleaseMutex(m_Lock); ReleaseMutex(tValue.m_Lock); } return (*this); }; void Lock() { WaitForSingleObject(m_Lock, INFINITE); }; void UnLock() { ReleaseMutex(m_Lock); }; T* PeekLatest() { size_t Size = m_DataQueue.size(); if (Size > 0) { return &(m_DataQueue.front()); } return NULL; } T* PeekBackware() { size_t Size = m_DataQueue.size(); if (Size > 0) { if (Size <= m_MaxThreshold) { return &(m_DataQueue.back()); } else { return &(m_DataQueue[m_MaxThreshold - 1]); } } return NULL; } bool InQueueBackward(T &rMsg) { bool ret = false; WaitForSingleObject(m_Lock, INFINITE); //printf("Thread:%d,Pop REQ one\n", GetCurrentThreadId()); m_DataQueue.push_back(rMsg); //while (m_DataQueue.size() > (m_MaxThreshold*2)) //{ // m_DataQueue.pop_front(); //} ReleaseMutex(m_Lock); SetEvent(m_NotifyInQue); return ret; }; bool InQueue(T &rMsg) { bool ret = false; WaitForSingleObject(m_Lock, INFINITE); //printf("Thread:%d,Pop REQ one\n", GetCurrentThreadId()); m_DataQueue.push_front(rMsg); //while (m_DataQueue.size() > (m_MaxThreshold*2)) //{ // m_DataQueue.pop_back(); //} ReleaseMutex(m_Lock); SetEvent(m_NotifyInQue); return ret; }; void DeQueueLatest() { WaitForSingleObject(m_Lock, INFINITE); if (m_DataQueue.size() > 0) { m_DataQueue.pop_front(); } ReleaseMutex(m_Lock); }; size_t size() { size_t Size = 0; WaitForSingleObject(m_Lock, INFINITE); Size = m_DataQueue.size(); ReleaseMutex(m_Lock); if (Size > m_MaxThreshold) { Size = m_MaxThreshold; } return Size; }; HANDLE GetNotifyHandle() { return m_NotifyInQue; }; //must use with lock&unlock method T& operator [] (size_t idx) { if (idx >= m_MaxThreshold) { assert(0); } return m_DataQueue[idx]; }; DWORD WaitForInQue(DWORD timeout) { DWORD ret = WAIT_TIMEOUT; WaitForSingleObject(m_Lock, INFINITE); if (m_DataQueue.size() > 0) { ret = WAIT_OBJECT_0; } ReleaseMutex(m_Lock); if (ret == WAIT_TIMEOUT) { ret = WaitForSingleObject(m_NotifyInQue, timeout); if (ret == WAIT_TIMEOUT) { return ret; } //check again //make sure data is in the que WaitForSingleObject(m_Lock, INFINITE); if (m_DataQueue.size() > 0) { ret = WAIT_OBJECT_0; } ReleaseMutex(m_Lock); } return ret; }; };