#pragma once #include "Logger.h" #include "DiosLock.h" #include #include "Definitions.h" using namespace std; template class MsgCircle { DWORD m_MaxThreshold; DWORD m_CurThreshold; DiosLock m_Lock; HANDLE m_NotifyInQue; deque m_DataQueue; public: MsgCircle(void) { m_CurThreshold = 0; m_MaxThreshold = 2500000; m_NotifyInQue = CreateEvent(0,1,0,0); }; ~MsgCircle(void) { Clear(); CloseHandle(m_NotifyInQue); }; bool Clear() { ResetEvent(m_NotifyInQue); Lock(); m_DataQueue.clear(); UnLock(); return true; }; bool Peek(T &rMsg) { bool ret = false; Lock(); //DebugPrint("before deQue size:%d\n",m_DataQueue.size()); if (m_DataQueue.size() > 0) { rMsg = m_DataQueue.front(); ret = true; } //DebugPrint("after deQue size:%d\n",m_DataQueue.size()); UnLock(); return ret; }; bool DeQueue(T &rMsg) { bool ret = false; Lock(); //DebugPrint("before deQue size:%d\n",m_DataQueue.size()); if(m_DataQueue.size() > 0) { rMsg = m_DataQueue.front(); m_DataQueue.pop_front(); ret = true; } //DebugPrint("after deQue size:%d\n",m_DataQueue.size()); if (m_DataQueue.size() == 0) { ResetEvent(m_NotifyInQue); } UnLock(); return ret; }; MsgCircle& operator = (const MsgCircle &tValue) { if(this != &tValue) { Lock(); tValue.Lock(); m_DataQueue = tValue.m_DataQueue; UnLock(); tValue.UnLock(); } return (*this); }; void Lock() { m_Lock.Thread_Lock(); }; void UnLock() { m_Lock.Thread_UnLock(); }; bool InQueue(T &rMsg) { bool ret = false; Lock(); DWORD curSize = (DWORD)m_DataQueue.size(); #ifdef _DEBUG if (curSize > m_CurThreshold) { printf("Raising The Threshold:%d\n", curSize); m_CurThreshold = curSize; } #endif //printf("Thread:%d,Pop REQ one\n", GetCurrentThreadId()); if (curSize < m_MaxThreshold) { ret = true; m_DataQueue.push_back(rMsg); } else { printf("WARNING:Hitting MaxThreshold:%d\n", curSize); printf("WARNING:Losing the Packet------------!!!!\n"); TPRINTA_FATAL("WARNING:Hitting MaxThreshold : %d.Losing packets\n", curSize); } UnLock(); SetEvent(m_NotifyInQue); return ret; }; DWORD size() { Lock(); DWORD size = (DWORD)m_DataQueue.size(); UnLock(); return size; }; T& front() { return m_DataQueue.front(); }; HANDLE GetNotifyHandle() { return m_NotifyInQue; }; //must use with lock&unlock method T& operator [] (DWORD idx) { if(idx > m_DataQueue.size()) { assert(0); } return m_DataQueue[idx]; }; DWORD WaitForInQue(DWORD timeout) { DWORD ret = WAIT_TIMEOUT; Lock(); if (m_DataQueue.size() > 0) { ret = WAIT_OBJECT_0; } UnLock(); if (ret == WAIT_TIMEOUT) { ret = WaitForSingleObject(m_NotifyInQue, timeout); if (ret == WAIT_TIMEOUT) { return ret; } //check again //make sure data is in the que Lock(); if (m_DataQueue.size() > 0) { ret = WAIT_OBJECT_0; } UnLock(); } return ret; }; };