#ifndef _CIRCUITQUEUE_H_ #define _CIRCUITQUEUE_H_ #include #include #include //============================================================================================================================= /// ¿øÇü Å¥ Ŭ·¡½º ÅÛÇø´ /** @author Baek Sang Hyun @since 2004. 5. 30 @history 090416 - waverix : add-in method for double buffering 090424 - waverix : select lock functionality */ //============================================================================================================================= template class CircuitQueue; typedef CircuitQueue CircuitQueueByte; #ifdef __NA000000_090415_DOUBLE_BUFFERING_FOR_SAFELY_CONNECTION__ template class CircuitQueue { public: CircuitQueue() : m_bNeedLock(0) , m_pData(NULL), m_nLength(0), m_nSize(0) , m_nHead(0), m_nTail(0), m_nExtraSize(0) { InitializeCriticalSectionAndSpinCount(&m_cs, 4000); } virtual ~CircuitQueue() { if(m_pData) delete [] m_pData; DeleteCriticalSection(&m_cs); } void LockQueue() { if(m_bNeedLock) EnterCriticalSection(&m_cs); }; void UnlockQueue() { if(m_bNeedLock) LeaveCriticalSection(&m_cs); } //============================================================================================================================= /** @remarks Å¥¸¦ »ý¼ºÇÑ´Ù. @param nSize Å¥ »çÀÌÁî @param nExtraSize ÆÐŶÀÌ ¹öÆÛ µÚÂÊ¿¡¼­ ¾ÕÂÊÀ¸·Î ³ª´©¾î µé¾î°¥ ¶§ ÆÐŶÀ» À̾îÁÖ±â À§ÇØ È®º¸ÇÒ ¹öÆÛ µÚÂÊ ¿©ºÐÀÇ ¸Þ¸ð¸® Å©±â(½ÇÁ¦ ¿©ºÐ ¸Þ¸ð¸® = sizeof(T) * nExtraSize) */ //============================================================================================================================= void Create(int nSize, int nExtraSize = 0, BOOLEAN bDisableLock = 0) { if(bDisableLock == false) m_bNeedLock = true; //LockQueue(); if(m_pData) delete [] m_pData; m_pData = new T[nSize + nExtraSize]; m_nSize = nSize; m_nExtraSize = nExtraSize; //UnlockQueue() } //============================================================================================================================= /** @remarks Å¥¸¦ û¼ÒÇÑ´Ù. */ //============================================================================================================================= inline void Clear() { LockQueue(); m_nLength = m_nHead = m_nTail = 0; UnlockQueue(); } // (WAVERIX) (BUG-FIX) ¿¹±âÄ¡ ¾ÊÀº ¶ô ÇØÁ¦ »óÅ ¹æÁöÇϱâ À§ÇÑ ÀÛ¾÷ + ÄÚµå Áߺ¹ °¨¼Ò #define __GetSpace() (m_nSize - m_nLength) #define __GetLength() (m_nLength) #define __GetBackDataCount() (m_nSize - m_nHead) #define __GetReadPtr() (m_pData + m_nHead) #define __GetWritePtr() (m_pData + m_nTail) /// Å¥ÀÇ ³²Àº °ø°£À» ¸®ÅÏÇÑ´Ù. inline int GetSpace() { int iRet; LockQueue(); iRet = __GetSpace(); UnlockQueue(); return iRet; } /// ÇöÀç »ç¿ëÁßÀΠťÀÇ Å©±â¸¦ ¸®ÅÏÇÑ´Ù. inline int GetLength() { int iRet; LockQueue(); iRet = __GetLength(); UnlockQueue(); return iRet; } /// µ¥ÀÌÅͰ¡ Å¥ µÚÂÊÀ¸·Î ²Ë Â÷¼­ ¾ÕÀ¸·Î À̾îÁö´Â °æ¿ì, µÚÂÊ ³¡±îÁöÀÇ µ¥ÀÌÅÍ °³¼ö¸¦ ¸®ÅÏÇÑ´Ù. inline int GetBackDataCount() { int iRet; LockQueue(); iRet = __GetBackDataCount(); UnlockQueue(); return iRet; } /// µ¥ÀÌÅ͸¦ ÀÐÀ» Æ÷ÀÎÅÍ(Head)¸¦ ¸®ÅÏÇÑ´Ù. inline T* GetReadPtr() { T *pRet; LockQueue(); pRet = __GetReadPtr(); UnlockQueue(); return pRet; } /// µ¥ÀÌÅ͸¦ ¾µ Æ÷ÀÎÅÍ(Tail)¸¦ ¸®ÅÏÇÑ´Ù. inline T* GetWritePtr() { T *pRet; LockQueue(); pRet = __GetWritePtr(); UnlockQueue(); return pRet; } /// À߸®Áö ¾Ê°í Çѹø¿¡ ÀÐÀ» ¼ö ÀÖ´Â ±æÀ̸¦ ¸®ÅÏÇÑ´Ù. inline int GetReadableLen() { int iRet; LockQueue(); if(m_nHead == m_nTail) iRet = __GetLength() > 0 ? m_nSize - m_nHead: 0; else if(m_nHead < m_nTail) iRet = m_nTail - m_nHead; else iRet = m_nSize - m_nHead; UnlockQueue(); return iRet; } /// À߸®Áö ¾Ê°í Çѹø¿¡ ¾²±â °¡´ÉÇÑ ±æÀ̸¦ ¸®ÅÏÇÑ´Ù. inline int GetWritableLen() { int iRet; LockQueue(); if(m_nHead == m_nTail) iRet = __GetLength() > 0 ? 0 : m_nSize - m_nTail; else if(m_nHead < m_nTail) iRet = m_nSize - m_nTail; else iRet = m_nHead - m_nTail; UnlockQueue(); return iRet; } //============================================================================================================================= /** @remarks Å¥¿¡ µ¥ÀÌÅ͸¦ ³Ö´Â´Ù. @param pSrc Å¥¿¡ »ðÀÔÇÒ µ¥ÀÌÅÍ Æ÷ÀÎÅÍ @param nSize Å¥¿¡ »ðÀÔÇÒ µ¥ÀÌÅÍÀÇ ±æÀÌ @retval BOOL Á¤»óÀûÀ¸·Î µ¥ÀÌÅÍ »ðÀÔÀÌ ³¡³ª¸é TRUE¸¦ ¸®ÅÏÇÑ´Ù. Å¥°¡ ²ËÂ÷¼­ »ðÀÔÇÒ ¼ö ¾ø´Â °æ¿ì FALSE¸¦ ¸®ÅÏÇÑ´Ù. */ //============================================================================================================================= BOOL Enqueue(T* pSrc, int nSize) { LockQueue(); if(__GetSpace() < nSize) { UnlockQueue(); return FALSE; } // pData°¡ NULLÀÎ °æ¿ì¿¡´Â µ¥ÀÌÅÍ Å¥À× ¾øÀÌ tail°ú length¸¸ °»½ÅÇÑ´Ù. if(pSrc != NULL) { if(m_nHead <= m_nTail) { // 1. head°¡ tailº¸´Ù ¾Õ¿¡ ÀÖ´Â °æ¿ì int nBackSpaceCount = m_nSize - m_nTail; if(nBackSpaceCount >= nSize) { // µÚÂÊ¿¡ ³²Àº °ø°£ÀÌ º¹»çÇÒ ¾çº¸´Ù °°°Å³ª Å« °æ¿ì Çѹø¿¡ º¹»çÇÑ´Ù. memcpy(m_pData + m_nTail, pSrc, sizeof(T) * nSize); } else { // µÚÂÊ¿¡ ³²Àº °ø°£ÀÌ º¹»çÇÒ ¾çº¸´Ù ÀÛÀº °æ¿ì µÎ¹ø¿¡ ³ª´©¾î º¹»çÇÑ´Ù. memcpy(m_pData + m_nTail, pSrc, sizeof(T) * nBackSpaceCount); memcpy(m_pData, pSrc + nBackSpaceCount, sizeof(T) * (nSize - nBackSpaceCount)); } } else { // 2. head°¡ tailº¸´Ù µÚ¿¡ ÀÖ´Â °æ¿ì memcpy(m_pData + m_nTail, pSrc, sizeof(T) * nSize); } } m_nTail += nSize; m_nTail %= m_nSize; m_nLength += nSize; UnlockQueue(); return TRUE; } //============================================================================================================================= /** @remarks Å¥¿¡¼­ µ¥ÀÌÅ͸¦ ²¨³½´Ù. @param pTar Å¥¿¡¼­ ²¨³½ µ¥ÀÌÅ͸¦ º¹»çÇÒ ¹öÆÛÀÇ Æ÷ÀÎÅÍ @param nSize Å¥¿¡¼­ ²¨³¾ µ¥ÀÌÅÍ ±æÀÌ @retval BOOL Á¤»óÀûÀ¸·Î µ¥ÀÌÅ͸¦ ²¨³»¸é TRUE¸¦ ¸®ÅÏÇÑ´Ù. ²¨³¾ µ¥ÀÌÅͰ¡ nSizeº¸´Ù ÀûÀº °æ¿ì FALSE¸¦ ¸®ÅÏÇÑ´Ù. */ //============================================================================================================================= BOOL Dequeue(T* pTar, int nSize) { LockQueue(); // Peek°ú ·ÎÁ÷ µ¿ÀÏ if(m_nLength < nSize) { UnlockQueue(); return FALSE; } // ³»¿ëÀ» ¹ÞÀ» Æ÷ÀÎÅͰ¡ NULLÀÌ ¾Æ´Ñ °æ¿ì¿¡¸¸ ¸Þ¸ð¸®¸¦ º¹»çÇÑ´Ù. if(pTar != NULL) { if(m_nHead < m_nTail) { // 1. head°¡ tailº¸´Ù ¾Õ¿¡ ÀÖ´Â °æ¿ì memcpy(pTar, m_pData + m_nHead, sizeof(T) * nSize); } else { // 2. head°¡ tailº¸´Ù µÚ¿¡ ÀÖ´Â °æ¿ì int backDataCount = __GetBackDataCount(); if(backDataCount >= nSize) { // µÚÂÊ¿¡ ³²Àº µ¥ÀÌÅͰ¡ ²¨³»°¥ ¾çº¸´Ù °°°Å³ª Å« °æ¿ì nSize¸¸Å­ Çѹø¿¡ º¹»çÇÑ´Ù. memcpy(pTar, m_pData + m_nHead, sizeof(T) * nSize); } else { // µÚÂÊ¿¡ ³²Àº µ¥ÀÌÅͰ¡ ²¨³»°¥ ¾çº¸´Ù ÀÛÀº °æ¿ì µÎ¹ø¿¡ ³ª´©¾î º¹»çÇÑ´Ù. memcpy(pTar, m_pData + m_nHead, sizeof(T) * backDataCount); memcpy(pTar + backDataCount, m_pData, sizeof(T) * (nSize - backDataCount)); } } } ////////////////////////////////////////////////////////////////////////// m_nHead += nSize; m_nHead %= m_nSize; m_nLength -= nSize; UnlockQueue(); return TRUE; } //============================================================================================================================= /** @remarks Å¥¿¡¼­ µ¥ÀÌÅ͸¦ ²¨³»Áö ¾Ê°í º¹»ç¸¸ ÇØ¿Â´Ù. @param pTar Å¥ÀÇ µ¥ÀÌÅ͸¦ º¹»çÇÒ ¹öÆÛÀÇ Æ÷ÀÎÅÍ @param nSize Å¥¿¡¼­ º¹»çÇÒ µ¥ÀÌÅÍ ±æÀÌ @retval BOOL Á¤»óÀûÀ¸·Î µ¥ÀÌÅ͸¦ º¹»çÇϸé TRUE¸¦ ¸®ÅÏÇÑ´Ù. ²¨³¾ µ¥ÀÌÅͰ¡ nSizeº¸´Ù ÀûÀº °æ¿ì FALSE¸¦ ¸®ÅÏÇÑ´Ù. */ //============================================================================================================================= BOOL Peek(T* pTar, int nSize) { LockQueue(); // Dequeue¿Í ·ÎÁ÷ µ¿ÀÏ if(m_nLength < nSize) { UnlockQueue(); return FALSE; } // ³»¿ëÀ» ¹ÞÀ» Æ÷ÀÎÅͰ¡ NULLÀÌ ¾Æ´Ñ °æ¿ì¿¡¸¸ ¸Þ¸ð¸®¸¦ º¹»çÇÑ´Ù. if(pTar != NULL) { if(m_nHead < m_nTail) { // 1. head°¡ tailº¸´Ù ¾Õ¿¡ ÀÖ´Â °æ¿ì memcpy(pTar, m_pData + m_nHead, sizeof(T) * nSize); } else { // 2. head°¡ tailº¸´Ù µÚ¿¡ ÀÖ´Â °æ¿ì int backDataCount = __GetBackDataCount(); if(backDataCount >= nSize) { // µÚÂÊ¿¡ ³²Àº µ¥ÀÌÅͰ¡ ²¨³»°¥ ¾çº¸´Ù °°°Å³ª Å« °æ¿ì nSize¸¸Å­ Çѹø¿¡ º¹»çÇÑ´Ù. memcpy(pTar, m_pData + m_nHead, sizeof(T) * nSize); } else { // µÚÂÊ¿¡ ³²Àº µ¥ÀÌÅͰ¡ ²¨³»°¥ ¾çº¸´Ù ÀÛÀº °æ¿ì µÎ¹ø¿¡ ³ª´©¾î º¹»çÇÑ´Ù. memcpy(pTar, m_pData + m_nHead, sizeof(T) * backDataCount); memcpy(pTar + backDataCount, m_pData, sizeof(T) * (nSize - backDataCount)); } } } UnlockQueue(); return TRUE; } //============================================================================================================================= /** @remarks ÆÐŶÀÌ ¹öÆÛ µÚÂÊ¿¡¼­ ¾ÕÂÊÀ¸·Î ³ª´©¾îÁú ¶§ ÆÐŶÀÌ À̾îÁöµµ·Ï ¿©ºÐÀÇ °ø°£¿¡ Ä«ÇÇÇÑ´Ù. @param nSize µÚÂÊ¿¡¼­ Àß·Á¼­ ¾ÕÂÊÀ¸·Î À̾îÁø µ¥ÀÌÅÍÀÇ ±æÀÌ */ //============================================================================================================================= inline void CopyHeadDataToExtraBuffer(int nSize) { assert(nSize <= m_nExtraSize); LockQueue(); // ¹öÆÛ ¸Ç µÞÂÊ ¿©ºÐ ¹öÆÛ¿¡´Ù°¡ ¹öÆÛ ¸Ç ¾ÕÂÊ¿¡ ÀÖ´Â µ¥ÀÌÅ͸¦ ¾´´Ù. memcpy(m_pData + m_nSize, m_pData, nSize); UnlockQueue(); } BOOL CopyLocalToSecondBuffer(CircuitQueue* pThreadUnsafeDoubleBuffer, int* pRemainedRatio) { if(this == pThreadUnsafeDoubleBuffer) return FALSE; // assert(pThreadUnsafeDoubleBuffer->(m_nSize - m_nLength) >= m_nLength) pThreadUnsafeDoubleBuffer->Clear(); LockQueue(); *pRemainedRatio = int((m_nSize - m_nLength) * 100 / m_nSize); int readableLength = int(sizeof(T) * m_nLength); if(readableLength) { if(m_nHead < m_nTail) { // 1. head°¡ tailº¸´Ù ¾Õ¿¡ ÀÖ´Â °æ¿ì CopyMemory(pThreadUnsafeDoubleBuffer->m_pData, m_pData + m_nHead, readableLength); pThreadUnsafeDoubleBuffer->m_nLength = readableLength; } else { // 2. head°¡ tailº¸´Ù µÚ¿¡ ÀÖ´Â °æ¿ì int backDataCount = __GetBackDataCount(); CopyMemory(pThreadUnsafeDoubleBuffer->m_pData, m_pData + m_nHead, backDataCount); if(readableLength > backDataCount) { CopyMemory(pThreadUnsafeDoubleBuffer->m_pData + backDataCount, m_pData, readableLength - backDataCount); } pThreadUnsafeDoubleBuffer->m_nLength = readableLength; } } UnlockQueue(); return TRUE; } // (WAVERIX) (BUG-FIX) ¿¹±âÄ¡ ¾ÊÀº ¶ô ÇØÁ¦ »óÅ ¹æÁöÇϱâ À§ÇÑ ÀÛ¾÷ + ÄÚµå Áߺ¹ °¨¼Ò #undef __GetSpace #undef __GetLength #undef __GetBackDataCount #undef __GetReadPtr #undef __GetWritePtr protected: CRITICAL_SECTION m_cs; BOOLEAN m_bNeedLock; // ÇØ´ç CircuitQueue¿¡ LockÀ» °É Çʿ䰡 Àִ°¡? T* m_pData; /// Å¥ ¹öÆÛ Æ÷ÀÎÅÍ int m_nLength; /// ÇöÀç µ¥ÀÌÅÍ ±æÀÌ int m_nSize; /// Å¥ ¹öÆÛÀÇ Àüü Å©±â int m_nHead; /// ÇöÀç µ¥ÀÌÅͰ¡ ½ÃÀ۵Ǵ °÷ÀÇ À§Ä¡ int m_nTail; /// ÇöÀç µ¥ÀÌÅͰ¡ ½áÁú °÷ÀÇ À§Ä¡ int m_nExtraSize; /// Å¥ µÚÂÊ¿¡ ¿©ºÐÀ¸·Î ÀâÀ» ¹öÆÛ Å©±â }; #else //!__NA000000_090415_DOUBLE_BUFFERING_FOR_SAFELY_CONNECTION__ template class CircuitQueue { public: CircuitQueue() : m_pData( NULL ), m_nLength( 0 ), m_nSize( 0 ), m_nHead( 0 ), m_nTail( 0 ) { InitializeCriticalSection( &m_cs ); } virtual ~CircuitQueue() { if( m_pData ) delete [] m_pData; DeleteCriticalSection( &m_cs ); } //============================================================================================================================= /** @remarks Å¥¸¦ »ý¼ºÇÑ´Ù. @param nSize Å¥ »çÀÌÁî @param nExtraSize ÆÐŶÀÌ ¹öÆÛ µÚÂÊ¿¡¼­ ¾ÕÂÊÀ¸·Î ³ª´©¾î µé¾î°¥ ¶§ ÆÐŶÀ» À̾îÁÖ±â À§ÇØ È®º¸ÇÒ ¹öÆÛ µÚÂÊ ¿©ºÐÀÇ ¸Þ¸ð¸® Å©±â(½ÇÁ¦ ¿©ºÐ ¸Þ¸ð¸® = sizeof(T) * nExtraSize ) */ //============================================================================================================================= void Create( int nSize, int nExtraSize = 0 ) { EnterCriticalSection( &m_cs ); if( m_pData ) delete [] m_pData; m_pData = new T[nSize + nExtraSize]; m_nSize = nSize; m_nExtraSize = nExtraSize; LeaveCriticalSection( &m_cs ); } //============================================================================================================================= /** @remarks Å¥¸¦ û¼ÒÇÑ´Ù. */ //============================================================================================================================= inline void Clear() { EnterCriticalSection( &m_cs ); m_nLength = 0; m_nHead = 0; m_nTail = 0; LeaveCriticalSection( &m_cs ); } /// Å¥ÀÇ ³²Àº °ø°£À» ¸®ÅÏÇÑ´Ù. inline int GetSpace() { int iRet; EnterCriticalSection( &m_cs ); iRet = m_nSize - m_nLength; LeaveCriticalSection( &m_cs ); return iRet; } /// ÇöÀç »ç¿ëÁßÀΠťÀÇ Å©±â¸¦ ¸®ÅÏÇÑ´Ù. inline int GetLength() { int iRet; EnterCriticalSection( &m_cs ); iRet = m_nLength; LeaveCriticalSection( &m_cs ); return iRet; } /// µ¥ÀÌÅͰ¡ Å¥ µÚÂÊÀ¸·Î ²Ë Â÷¼­ ¾ÕÀ¸·Î À̾îÁö´Â °æ¿ì, µÚÂÊ ³¡±îÁöÀÇ µ¥ÀÌÅÍ °³¼ö¸¦ ¸®ÅÏÇÑ´Ù. inline int GetBackDataCount() { int iRet; EnterCriticalSection( &m_cs ); iRet = m_nSize - m_nHead; LeaveCriticalSection( &m_cs ); return iRet; } /// µ¥ÀÌÅ͸¦ ÀÐÀ» Æ÷ÀÎÅÍ(Head)¸¦ ¸®ÅÏÇÑ´Ù. inline T* GetReadPtr() { T *pRet; EnterCriticalSection( &m_cs ); pRet = m_pData + m_nHead; LeaveCriticalSection( &m_cs ); return pRet; } /// µ¥ÀÌÅ͸¦ ¾µ Æ÷ÀÎÅÍ(Tail)¸¦ ¸®ÅÏÇÑ´Ù. inline T* GetWritePtr() { T *pRet; EnterCriticalSection( &m_cs ); pRet = m_pData + m_nTail; LeaveCriticalSection( &m_cs ); return pRet; } /// À߸®Áö ¾Ê°í Çѹø¿¡ ÀÐÀ» ¼ö ÀÖ´Â ±æÀ̸¦ ¸®ÅÏÇÑ´Ù. inline int GetReadableLen() { int iRet; EnterCriticalSection( &m_cs ); if( m_nHead == m_nTail ) iRet = GetLength() > 0 ? m_nSize - m_nHead: 0; else if( m_nHead < m_nTail ) iRet = m_nTail - m_nHead; else iRet = m_nSize - m_nHead; LeaveCriticalSection( &m_cs ); return iRet; } /// À߸®Áö ¾Ê°í Çѹø¿¡ ¾²±â °¡´ÉÇÑ ±æÀ̸¦ ¸®ÅÏÇÑ´Ù. inline int GetWritableLen() { int iRet; EnterCriticalSection( &m_cs ); if( m_nHead == m_nTail ) iRet = GetLength() > 0 ? 0 : m_nSize - m_nTail; else if( m_nHead < m_nTail ) iRet = m_nSize - m_nTail; else iRet = m_nHead - m_nTail; LeaveCriticalSection( &m_cs ); return iRet; } //============================================================================================================================= /** @remarks Å¥¿¡ µ¥ÀÌÅ͸¦ ³Ö´Â´Ù. @param pSrc Å¥¿¡ »ðÀÔÇÒ µ¥ÀÌÅÍ Æ÷ÀÎÅÍ @param nSize Å¥¿¡ »ðÀÔÇÒ µ¥ÀÌÅÍÀÇ ±æÀÌ @retval BOOL Á¤»óÀûÀ¸·Î µ¥ÀÌÅÍ »ðÀÔÀÌ ³¡³ª¸é TRUE¸¦ ¸®ÅÏÇÑ´Ù. Å¥°¡ ²ËÂ÷¼­ »ðÀÔÇÒ ¼ö ¾ø´Â °æ¿ì FALSE¸¦ ¸®ÅÏÇÑ´Ù. */ //============================================================================================================================= inline BOOL Enqueue( T *pSrc, int nSize ) { EnterCriticalSection( &m_cs ); if( GetSpace() < nSize ) { LeaveCriticalSection( &m_cs ); return FALSE; } // pData°¡ NULLÀÎ °æ¿ì¿¡´Â µ¥ÀÌÅÍ Å¥À× ¾øÀÌ tail°ú length¸¸ °»½ÅÇÑ´Ù. if( pSrc != NULL ) { if( m_nHead <= m_nTail ) { // 1. head°¡ tailº¸´Ù ¾Õ¿¡ ÀÖ´Â °æ¿ì int nBackSpaceCount = m_nSize - m_nTail; if( nBackSpaceCount >= nSize ) { // µÚÂÊ¿¡ ³²Àº °ø°£ÀÌ º¹»çÇÒ ¾çº¸´Ù °°°Å³ª Å« °æ¿ì Çѹø¿¡ º¹»çÇÑ´Ù. memcpy( m_pData + m_nTail, pSrc, sizeof(T) * nSize ); } else { // µÚÂÊ¿¡ ³²Àº °ø°£ÀÌ º¹»çÇÒ ¾çº¸´Ù ÀÛÀº °æ¿ì µÎ¹ø¿¡ ³ª´©¾î º¹»çÇÑ´Ù. memcpy( m_pData + m_nTail, pSrc, sizeof(T) * nBackSpaceCount ); memcpy( m_pData, pSrc + nBackSpaceCount, sizeof(T) * ( nSize - nBackSpaceCount ) ); } } else { // 2. head°¡ tailº¸´Ù µÚ¿¡ ÀÖ´Â °æ¿ì memcpy( m_pData + m_nTail, pSrc, sizeof(T) * nSize ); } } m_nTail += nSize; m_nTail %= m_nSize; m_nLength += nSize; LeaveCriticalSection( &m_cs ); return TRUE; } //============================================================================================================================= /** @remarks Å¥¿¡¼­ µ¥ÀÌÅ͸¦ ²¨³½´Ù. @param pTar Å¥¿¡¼­ ²¨³½ µ¥ÀÌÅ͸¦ º¹»çÇÒ ¹öÆÛÀÇ Æ÷ÀÎÅÍ @param nSize Å¥¿¡¼­ ²¨³¾ µ¥ÀÌÅÍ ±æÀÌ @retval BOOL Á¤»óÀûÀ¸·Î µ¥ÀÌÅ͸¦ ²¨³»¸é TRUE¸¦ ¸®ÅÏÇÑ´Ù. ²¨³¾ µ¥ÀÌÅͰ¡ nSizeº¸´Ù ÀûÀº °æ¿ì FALSE¸¦ ¸®ÅÏÇÑ´Ù. */ //============================================================================================================================= inline BOOL Dequeue( T *pTar, int nSize ) { EnterCriticalSection( &m_cs ); if( !Peek( pTar, nSize ) ) { LeaveCriticalSection( &m_cs ); return FALSE; } m_nHead += nSize; m_nHead %= m_nSize; m_nLength -= nSize; LeaveCriticalSection( &m_cs ); return TRUE; } //============================================================================================================================= /** @remarks Å¥¿¡¼­ µ¥ÀÌÅ͸¦ ²¨³»Áö ¾Ê°í º¹»ç¸¸ ÇØ¿Â´Ù. @param pTar Å¥ÀÇ µ¥ÀÌÅ͸¦ º¹»çÇÒ ¹öÆÛÀÇ Æ÷ÀÎÅÍ @param nSize Å¥¿¡¼­ º¹»çÇÒ µ¥ÀÌÅÍ ±æÀÌ @retval BOOL Á¤»óÀûÀ¸·Î µ¥ÀÌÅ͸¦ º¹»çÇϸé TRUE¸¦ ¸®ÅÏÇÑ´Ù. ²¨³¾ µ¥ÀÌÅͰ¡ nSizeº¸´Ù ÀûÀº °æ¿ì FALSE¸¦ ¸®ÅÏÇÑ´Ù. */ //============================================================================================================================= inline BOOL Peek( T *pTar, int nSize ) { EnterCriticalSection( &m_cs ); if( m_nLength < nSize ) { LeaveCriticalSection( &m_cs ); return FALSE; } // ³»¿ëÀ» ¹ÞÀ» Æ÷ÀÎÅͰ¡ NULLÀÌ ¾Æ´Ñ °æ¿ì¿¡¸¸ ¸Þ¸ð¸®¸¦ º¹»çÇÑ´Ù. if( pTar != NULL ) { if( m_nHead < m_nTail ) { // 1. head°¡ tailº¸´Ù ¾Õ¿¡ ÀÖ´Â °æ¿ì memcpy( pTar, m_pData + m_nHead, sizeof(T) * nSize ); } else { // 2. head°¡ tailº¸´Ù µÚ¿¡ ÀÖ´Â °æ¿ì if( GetBackDataCount() >= nSize ) { // µÚÂÊ¿¡ ³²Àº µ¥ÀÌÅͰ¡ ²¨³»°¥ ¾çº¸´Ù °°°Å³ª Å« °æ¿ì nSize¸¸Å­ Çѹø¿¡ º¹»çÇÑ´Ù. memcpy( pTar, m_pData + m_nHead, sizeof(T) * nSize ); } else { // µÚÂÊ¿¡ ³²Àº µ¥ÀÌÅͰ¡ ²¨³»°¥ ¾çº¸´Ù ÀÛÀº °æ¿ì µÎ¹ø¿¡ ³ª´©¾î º¹»çÇÑ´Ù. memcpy( pTar, m_pData + m_nHead, sizeof(T) * GetBackDataCount() ); memcpy( pTar + GetBackDataCount(), m_pData, sizeof(T) * ( nSize - GetBackDataCount() ) ); } } } LeaveCriticalSection( &m_cs ); return TRUE; } //============================================================================================================================= /** @remarks ÆÐŶÀÌ ¹öÆÛ µÚÂÊ¿¡¼­ ¾ÕÂÊÀ¸·Î ³ª´©¾îÁú ¶§ ÆÐŶÀÌ À̾îÁöµµ·Ï ¿©ºÐÀÇ °ø°£¿¡ Ä«ÇÇÇÑ´Ù. @param nSize µÚÂÊ¿¡¼­ Àß·Á¼­ ¾ÕÂÊÀ¸·Î À̾îÁø µ¥ÀÌÅÍÀÇ ±æÀÌ */ //============================================================================================================================= inline void CopyHeadDataToExtraBuffer( int nSize ) { assert( nSize <= m_nExtraSize ); EnterCriticalSection( &m_cs ); // ¹öÆÛ ¸Ç µÞÂÊ ¿©ºÐ ¹öÆÛ¿¡´Ù°¡ ¹öÆÛ ¸Ç ¾ÕÂÊ¿¡ ÀÖ´Â µ¥ÀÌÅ͸¦ ¾´´Ù. memcpy( m_pData + m_nSize, m_pData, nSize ); LeaveCriticalSection( &m_cs ); } #ifdef __NA000000_090415_DOUBLE_BUFFERING_FOR_SAFELY_CONNECTION__ BOOL CopyLocalToSecondBuffer(CircuitQueue* pThreadUnsafeDoubleBuffer, int* pRemainedRatio) { if(this == pThreadUnsafeDoubleBuffer) return FALSE; // assert(pThreadUnsafeDoubleBuffer->(m_nSize - m_nLength) >= m_nLength) pThreadUnsafeDoubleBuffer->Clear(); EnterCriticalSection(&m_cs); *pRemainedRatio = int((m_nSize - m_nLength) * 100 / m_nSize); int readableLength = int(sizeof(T) * m_nLength); if(readableLength) { if(m_nHead < m_nTail) { // 1. head°¡ tailº¸´Ù ¾Õ¿¡ ÀÖ´Â °æ¿ì CopyMemory(pThreadUnsafeDoubleBuffer->m_pData, m_pData + m_nHead, readableLength); pThreadUnsafeDoubleBuffer->m_nLength = readableLength; } else { // 2. head°¡ tailº¸´Ù µÚ¿¡ ÀÖ´Â °æ¿ì int backDataCount = m_nSize - m_nHead; CopyMemory(pThreadUnsafeDoubleBuffer->m_pData, m_pData + m_nHead, backDataCount); if(readableLength > backDataCount) { CopyMemory(pThreadUnsafeDoubleBuffer->m_pData + backDataCount, m_pData, readableLength - backDataCount); } pThreadUnsafeDoubleBuffer->m_nLength = readableLength; } } LeaveCriticalSection(&m_cs); return TRUE; } #endif //__NA000000_090415_DOUBLE_BUFFERING_FOR_SAFELY_CONNECTION__ protected: CRITICAL_SECTION m_cs; T *m_pData; /// Å¥ ¹öÆÛ Æ÷ÀÎÅÍ int m_nLength; /// ÇöÀç µ¥ÀÌÅÍ ±æÀÌ int m_nSize; /// Å¥ ¹öÆÛÀÇ Àüü Å©±â int m_nHead; /// ÇöÀç µ¥ÀÌÅͰ¡ ½ÃÀ۵Ǵ °÷ÀÇ À§Ä¡ int m_nTail; /// ÇöÀç µ¥ÀÌÅͰ¡ ½áÁú °÷ÀÇ À§Ä¡ int m_nExtraSize; /// Å¥ µÚÂÊ¿¡ ¿©ºÐÀ¸·Î ÀâÀ» ¹öÆÛ Å©±â }; #endif //!__NA000000_090415_DOUBLE_BUFFERING_FOR_SAFELY_CONNECTION__ #endif //_CIRCUITQUEUE_H_