用于进程内线程间数据通信/同步
- //CBufList.h
- #ifndef _BUF_LIST_h_
- #define _BUF_LIST_h_
- #include "CRWLock.h"
- #include <stdlib.h>
- enum eBufCellStatus
- {
- eFree = 0,
- eAllocated,
- eActived,
- };
- #define HALFMAX_SORTKEY ((uint32_t)(0xffffffff)>>1)
- struct TBufCellComHead
- {
- TBufCellComHead *lpPreCell;
- TBufCellComHead *lpNextCell;
- eBufCellStatus eCellStatus;
- uint32_t ulSortKey;
- uint32_t ulDataSize;
- uint8_t *lpData;
- };
- class CBufList
- {
- public:
- CBufList();
- int32_t Init(uint32_t ulCellSize, uint32_t ulCount,
- uint32_t ulMaxCount, uint32_t ulMaxActiveCount = 0,
- BOOL bIsWorkWithEvent = TRUE);
- int32_t Destroy(void);
- void WorkerExit(void);
- TBufCellComHead* AllocateOnListHead(void);
- TBufCellComHead* AllocateInsBySortKey(uint32_t ulSortKey);
- int32_t Active(TBufCellComHead* lpBufCell);
- TBufCellComHead* GetBufCellOnProc(void);
- int32_t Release(TBufCellComHead* lpBufCell);
- inline BOOL IsEmpty(void) const
- {
- return (NULL == m_lpListOnProc);
- }
- inline HANDLE GetActiveHandle(void) const
- {
- return m_hExistAcvtivedBufCell;
- }
- inline HANDLE GetExitHandle(void) const
- {
- return m_hWorkExit;
- }
- inline uint32_t GetCurActiveCount(void) const
- {
- return m_ulCurActiveCount;
- }
- inline void SetMaxActiveCount(uint32_t ulMaxActiveCount)
- {
- m_ActiveCountLock.WLock();
- m_ulMaxActiveCount = ulMaxActiveCount;
- m_ActiveCountLock.WUnLock();
- if (m_ulCurActiveCount!=0)
- {
- ::SetEvent(m_hExistAcvtivedBufCell);
- }
- }
- inline uint32_t GetMaxActiveCount(void) const
- {
- return m_ulMaxActiveCount;
- }
- private:
- int32_t InitLeakMem(uint32_t ulCellSize, uint32_t ulCount);
- BOOL IsMyCell(TBufCellComHead* lpBufCell);
- private:
- TBufCellComHead *m_list;
- TBufCellComHead *m_listAppend;
- uint32_t m_ulCellSize;
- uint32_t m_ulCurCount;
- uint32_t m_ulMaxCount;
- uint32_t m_ulCurActiveCount;
- uint32_t m_ulMaxActiveCount;
- TBufCellComHead *m_lpListHead;
- TBufCellComHead *m_lpListOnProc;
- TBufCellComHead *m_lpListTail;
- BOOL m_bIsWorkWithEvent;
- HANDLE m_hExistAcvtivedBufCell;
- HANDLE m_hIsWorkExit;
- HANDLE m_hWorkExit;
- CRWLock m_ListHeadLock;
- CRWLock m_ListTailLock;
- CRWLock m_ListOnProcLock;
- CRWLock m_ActiveCountLock;
- };
- #endif
- //CBufList.cpp
- #include "CBufList.h"
- CBufList::CBufList(void)
- {
- m_bIsWorkWithEvent = FALSE;
- m_ulCellSize = 0;
- m_ulCurCount = 0;
- m_ulMaxCount = 0;
- m_ulCurActiveCount = 0;
- m_ulMaxActiveCount = 0;
- m_list = NULL;
- m_listAppend = NULL;
- m_lpListHead = NULL;
- m_lpListTail = NULL;
- m_lpListOnProc = NULL;
- m_hExistAcvtivedBufCell = NULL;
- m_hWorkExit = NULL;
- m_hIsWorkExit = NULL;
- }
- TBufCellComHead* CBufList::AllocateOnListHead(void)
- {
- TBufCellComHead *pTmp = NULL;
- m_ListTailLock.Lock();//Disable alloc
- if (m_lpListTail->eCellStatus != eFree)
- {
- if (m_ulCurCount >= m_ulMaxCount)
- {
- m_ListTailLock.UnLock();
- return NULL;
- }
- pTmp = (TBufCellComHead *)malloc(m_ulCellSize);
- if (NULL == pTmp)
- {
- m_ListTailLock.UnLock();
- return pTmp;
- }
- if (NULL == m_listAppend)
- {
- m_listAppend = m_lpListTail;
- }
- memset(pTmp, 0 , m_ulCellSize);
- m_ulCurCount++;
- pTmp->lpPreCell = m_lpListTail;
- pTmp->lpNextCell = NULL;
- if (m_ulCellSize>sizeof(TBufCellComHead))
- {
- pTmp->lpData = (uint8_t *)pTmp + sizeof(TBufCellComHead);
- pTmp->ulDataSize = m_ulCellSize - sizeof(TBufCellComHead);
- }
- m_lpListTail->lpNextCell = pTmp;
- m_lpListTail = pTmp;
- }
- pTmp = m_lpListTail;
- m_lpListTail = m_lpListTail->lpPreCell;
- m_lpListTail->lpNextCell = NULL;
- pTmp->eCellStatus = eAllocated;
- pTmp->lpNextCell = NULL;
- pTmp->lpPreCell = NULL;
- m_ListHeadLock.Lock();
- pTmp->lpNextCell = m_lpListHead;
- pTmp->lpPreCell = NULL;
- m_lpListHead->lpPreCell = pTmp;
- m_lpListHead = pTmp;
- m_ListHeadLock.UnLock();
- if (NULL == m_lpListOnProc)
- {
- m_ListOnProcLock.Lock();
- m_lpListOnProc = pTmp;
- m_ListOnProcLock.UnLock();
- }
- m_ListTailLock.UnLock();//Enable alloc
- return pTmp;
- }
- TBufCellComHead* CBufList::AllocateInsBySortKey(uint32_t ulSortKey)
- {
- TBufCellComHead *pTmp = NULL;
- if (0 == m_ulMaxActiveCount)
- {
- return NULL;
- }
- m_ListTailLock.Lock();//Disable alloc
- if (m_lpListTail->eCellStatus != eFree)
- {
- if (m_ulCurCount >= m_ulMaxCount)
- {
- m_ListTailLock.UnLock();
- return NULL;
- }
- pTmp = (TBufCellComHead *)malloc(m_ulCellSize);
- if (NULL == pTmp)
- {
- m_ListTailLock.UnLock();
- return pTmp;
- }
- if (NULL == m_listAppend)
- {
- m_listAppend = m_lpListTail;
- }
- memset(pTmp, 0 , m_ulCellSize);
- m_ulCurCount++;
- pTmp->lpPreCell = m_lpListTail;
- pTmp->lpNextCell = NULL;
- if (m_ulCellSize>sizeof(TBufCellComHead))
- {
- pTmp->lpData = (uint8_t *)pTmp + sizeof(TBufCellComHead);
- pTmp->ulDataSize = m_ulCellSize - sizeof(TBufCellComHead);
- }
- m_lpListTail->lpNextCell = pTmp;
- m_lpListTail = pTmp;
- }
- pTmp = m_lpListTail;
- m_lpListTail = m_lpListTail->lpPreCell;
- m_lpListTail->lpNextCell = NULL;
- pTmp->eCellStatus = eAllocated;
- pTmp->ulSortKey = ulSortKey;
- pTmp->lpNextCell = NULL;
- pTmp->lpPreCell = NULL;
- if (((ulSortKey>m_lpListHead->ulSortKey) && (ulSortKey-m_lpListHead->ulSortKey<HALFMAX_SORTKEY))
- ||((ulSortKey<m_lpListHead->ulSortKey)&&(m_lpListHead->ulSortKey-ulSortKey>=HALFMAX_SORTKEY)))
- {
- m_ListHeadLock.Lock();
- m_lpListHead->lpPreCell = pTmp;
- pTmp->lpNextCell = m_lpListHead;
- pTmp->lpPreCell = NULL;
- m_lpListHead = pTmp;
- m_ListHeadLock.UnLock();
- if (NULL == m_lpListOnProc)
- {
- m_ListOnProcLock.Lock();
- m_lpListOnProc = pTmp;
- m_ListOnProcLock.UnLock();
- }
- }
- else
- {
- m_ListOnProcLock.Lock();
- TBufCellComHead *pTmpSort = m_lpListHead->lpNextCell;
- while ((pTmpSort!=NULL) && (pTmpSort->eCellStatus!=eFree))
- {
- if (((ulSortKey>pTmpSort->ulSortKey) && (ulSortKey-pTmpSort->ulSortKey<HALFMAX_SORTKEY))
- ||((ulSortKey<pTmpSort->ulSortKey)&&(pTmpSort->ulSortKey-ulSortKey>=HALFMAX_SORTKEY)))
- {
- pTmp->lpNextCell = pTmpSort;
- pTmp->lpPreCell = pTmpSort->lpPreCell;
- if (pTmpSort->lpPreCell != NULL)
- {
- pTmpSort->lpPreCell->lpNextCell = pTmp;
- }
- pTmpSort->lpPreCell = pTmp;
- break;
- }
- pTmpSort = pTmpSort->lpNextCell;
- }
- if ((NULL==pTmp->lpPreCell)&&(NULL==pTmp->lpNextCell))
- {
- if (NULL == pTmpSort)
- {
- pTmpSort = m_lpListTail;
- }
- else
- {
- pTmpSort = pTmpSort->lpPreCell;
- }
- pTmp->lpNextCell = pTmpSort->lpNextCell;
- pTmp->lpPreCell = pTmpSort;
- if (pTmpSort->lpNextCell != NULL)
- {
- pTmpSort->lpNextCell->lpPreCell = pTmp;
- }
- pTmpSort->lpNextCell = pTmp;
- if (pTmpSort == m_lpListOnProc)
- {
- m_lpListOnProc = pTmp;
- }
- if (pTmpSort == m_lpListTail)
- {
- m_lpListTail = pTmp;
- }
- }
- m_ListOnProcLock.UnLock();
- }
- m_ListTailLock.UnLock();//Enable alloc
- return pTmp;
- }
- int32_t CBufList::Active(TBufCellComHead* lpBufCell)
- {
- if (!IsMyCell(lpBufCell))
- {
- if (lpBufCell != NULL)
- {
- OutputDebugString("CBufList::Active error/n");
- }
- return -1;
- }
- if (m_ulMaxActiveCount != 0)
- {
- m_ActiveCountLock.WLock();
- lpBufCell->eCellStatus = eActived;
- m_ulCurActiveCount++;
- m_ActiveCountLock.WUnLock();
- }
- else
- {
- lpBufCell->eCellStatus = eActived;
- }
- if (m_bIsWorkWithEvent)
- {
- if (m_ulMaxActiveCount != 0)
- {
- m_ActiveCountLock.RLock();
- if (m_ulCurActiveCount>=m_ulMaxActiveCount)
- {
- ::SetEvent(m_hExistAcvtivedBufCell);
- }
- m_ActiveCountLock.RUnLock();
- }
- else
- {
- ::SetEvent(m_hExistAcvtivedBufCell);
- }
- }
- return 0;
- }
- TBufCellComHead* CBufList::GetBufCellOnProc(void)
- {
- if (NULL == m_lpListOnProc)
- {
- return NULL;
- }
- m_ActiveCountLock.RLock();
- if ((m_ulMaxActiveCount>0) && (m_ulMaxActiveCount>m_ulCurActiveCount))
- {
- m_ActiveCountLock.RUnLock();
- return NULL;
- }
- m_ActiveCountLock.RUnLock();
- m_ListOnProcLock.Lock();
- if (m_lpListOnProc->eCellStatus != eActived)
- {
- m_ListOnProcLock.UnLock();
- return NULL;
- }
- return m_lpListOnProc;
- }
- BOOL CBufList::IsMyCell(TBufCellComHead* lpBufCell)
- {
- TBufCellComHead *pTmp;
- pTmp = m_lpListHead;
- while (pTmp != NULL)
- {
- if (pTmp == lpBufCell)
- {
- return TRUE;
- }
- pTmp = pTmp->lpNextCell;
- }
- return FALSE;
- }
- int32_t CBufList::Release(TBufCellComHead* lpBufCell)
- {
- if (!IsMyCell(lpBufCell))
- {
- if (lpBufCell != NULL)
- {
- OutputDebugString("CBufList::Release error/n");
- }
- return -1;
- }
- if (m_ulMaxActiveCount != 0)
- {
- m_ActiveCountLock.WLock();
- m_ulCurActiveCount--;
- m_lpListOnProc->eCellStatus = eFree;
- m_lpListOnProc->ulSortKey = 0;
- m_ActiveCountLock.WUnLock();
- }
- else
- {
- m_lpListOnProc->eCellStatus = eFree;
- }
- m_lpListOnProc = m_lpListOnProc->lpPreCell;
- m_ListOnProcLock.UnLock();
- if (m_bIsWorkWithEvent && (m_lpListOnProc!=NULL))
- {
- if (m_ulMaxActiveCount>0)
- {
- m_ActiveCountLock.RLock();
- if (m_ulMaxActiveCount<=m_ulCurActiveCount)
- {
- ::SetEvent(m_hExistAcvtivedBufCell);
- }
- m_ActiveCountLock.RUnLock();
- }
- else
- {
- ::SetEvent(m_hExistAcvtivedBufCell);
- }
- }
- return 0;
- }
- int32_t CBufList::Init(uint32_t ulCellSize, uint32_t ulCount,
- uint32_t ulMaxCount, uint32_t ulMaxActiveCount,
- BOOL bIsWorkWithEvent)
- {
- uint32_t ulTotalSize = ulCellSize * ulCount;
- TBufCellComHead *pTmp;
- m_ulMaxCount = ulMaxCount;
- m_ActiveCountLock.WLock();
- m_ulMaxActiveCount = ulMaxActiveCount;
- m_ActiveCountLock.WUnLock();
- if (ulCount>ulMaxCount)
- {
- return -1;
- }
- if (bIsWorkWithEvent)
- {
- m_hExistAcvtivedBufCell = CreateEvent(NULL, FALSE, FALSE, NULL);
- if (NULL == m_hExistAcvtivedBufCell)
- {
- return -1;
- }
- m_hWorkExit = CreateEvent(NULL, FALSE, FALSE, NULL);
- if (NULL == m_hWorkExit)
- {
- CloseHandle(m_hExistAcvtivedBufCell);
- return -1;
- }
- m_hIsWorkExit = CreateEvent(NULL, TRUE, FALSE, NULL);
- if (NULL == m_hIsWorkExit)
- {
- CloseHandle(m_hExistAcvtivedBufCell);
- CloseHandle(m_hWorkExit);
- return -1;
- }
- }
- m_list = (TBufCellComHead *)malloc(ulTotalSize);
- if (NULL == m_list)
- {
- return InitLeakMem(ulCellSize, ulCount);
- }
- else
- {
- memset(m_list, 0 , ulTotalSize);
- }
- m_bIsWorkWithEvent = bIsWorkWithEvent;
- m_ulCellSize = ulCellSize;
- m_ulCurCount = ulCount;
- m_lpListHead = m_list;
- m_lpListTail = (TBufCellComHead *)((uint8_t *)m_list + (ulTotalSize - ulCellSize));
- m_listAppend = m_lpListTail;
- m_lpListHead->lpPreCell = NULL;
- pTmp = m_lpListHead;
- while (pTmp != m_lpListTail)
- {
- pTmp->lpNextCell = (TBufCellComHead *)((uint8_t *)pTmp + ulCellSize);
- pTmp->lpNextCell->lpPreCell = pTmp;
- if (ulCellSize>sizeof(TBufCellComHead))
- {
- pTmp->lpData = (uint8_t *)pTmp + sizeof(TBufCellComHead);
- pTmp->ulDataSize = ulCellSize - sizeof(TBufCellComHead);
- }
- pTmp = pTmp->lpNextCell;
- }
- if (ulCellSize>sizeof(TBufCellComHead))
- {
- pTmp->lpData = (uint8_t *)pTmp + sizeof(TBufCellComHead);
- pTmp->ulDataSize = ulCellSize - sizeof(TBufCellComHead);
- }
- pTmp->lpNextCell = NULL;
- return 0;
- }
- int32_t CBufList::InitLeakMem(uint32_t ulCellSize, uint32_t ulCount)
- {
- return -1;
- }
- int32_t CBufList::Destroy(void)
- {
- TBufCellComHead *pTmp,*pToDel;
- if (m_bIsWorkWithEvent)
- {
- uint32_t ret;
- while (1)
- {
- ::SetEvent(m_hWorkExit);
- ret = WaitForSingleObject(m_hIsWorkExit, INFINITE);
- if (ret != WAIT_TIMEOUT)
- {
- break;
- }
- }
- CloseHandle(m_hIsWorkExit);
- CloseHandle(m_hWorkExit);
- CloseHandle(m_hExistAcvtivedBufCell);
- }
- if (m_list != NULL)
- {
- if (m_listAppend!=NULL)
- {
- pTmp = m_lpListHead;
- while (pTmp != NULL)
- {
- pToDel = pTmp;
- pTmp = pTmp->lpNextCell;
- if ((pToDel>m_listAppend) || (pToDel<m_list))
- {
- if (pToDel->lpNextCell != NULL)
- {
- pToDel->lpNextCell->lpPreCell = pToDel->lpPreCell;
- }
- if (pToDel->lpPreCell != NULL)
- {
- pToDel->lpPreCell->lpNextCell = pToDel->lpNextCell;
- }
- free(pToDel);
- }
- }
- m_listAppend = NULL;
- }
- free(m_list);
- m_list = NULL;
- m_lpListHead = NULL;
- m_lpListTail = NULL;
- m_lpListOnProc = NULL;
- }
- return 0;
- }
- void CBufList::WorkerExit(void)
- {
- if (m_bIsWorkWithEvent)
- {
- ::SetEvent(m_hIsWorkExit);
- }
- }