win32 线程同步缓冲队列

用于进程内线程间数据通信/同步
  1. //CBufList.h
  2. #ifndef _BUF_LIST_h_
  3. #define _BUF_LIST_h_
  4. #include "CRWLock.h"
  5. #include <stdlib.h>
  6. enum eBufCellStatus
  7. {
  8.  eFree = 0,
  9.  eAllocated,
  10.  eActived,
  11. };
  12. #define HALFMAX_SORTKEY ((uint32_t)(0xffffffff)>>1)
  13. struct TBufCellComHead
  14. {
  15.  TBufCellComHead *lpPreCell;
  16.  TBufCellComHead *lpNextCell;
  17.  eBufCellStatus eCellStatus;
  18.  uint32_t  ulSortKey;
  19.  uint32_t  ulDataSize;
  20.  uint8_t   *lpData; 
  21. };
  22. class CBufList
  23. {
  24. public:
  25.  CBufList();
  26.  int32_t Init(uint32_t ulCellSize, uint32_t ulCount, 
  27.      uint32_t ulMaxCount, uint32_t ulMaxActiveCount = 0,
  28.      BOOL bIsWorkWithEvent = TRUE);
  29.  int32_t Destroy(void);
  30.  void WorkerExit(void);
  31.  TBufCellComHead* AllocateOnListHead(void);
  32.  TBufCellComHead* AllocateInsBySortKey(uint32_t ulSortKey);
  33.  int32_t Active(TBufCellComHead* lpBufCell);
  34.  TBufCellComHead* GetBufCellOnProc(void);
  35.  int32_t Release(TBufCellComHead* lpBufCell);
  36.  inline BOOL IsEmpty(voidconst
  37.  {
  38.   return (NULL == m_lpListOnProc);
  39.  }
  40.  inline HANDLE GetActiveHandle(voidconst
  41.  {
  42.   return m_hExistAcvtivedBufCell;
  43.  }
  44.  inline HANDLE GetExitHandle(voidconst
  45.  {
  46.   return m_hWorkExit;
  47.  }
  48.  inline uint32_t GetCurActiveCount(voidconst
  49.  {
  50.   return m_ulCurActiveCount;
  51.  }
  52.  inline void SetMaxActiveCount(uint32_t ulMaxActiveCount)
  53.  {
  54.   m_ActiveCountLock.WLock();
  55.   m_ulMaxActiveCount = ulMaxActiveCount;
  56.   m_ActiveCountLock.WUnLock();
  57.   if (m_ulCurActiveCount!=0)
  58.   {
  59.    ::SetEvent(m_hExistAcvtivedBufCell);
  60.   }
  61.  }
  62.  inline uint32_t GetMaxActiveCount(voidconst
  63.  {
  64.   return m_ulMaxActiveCount;
  65.  }
  66. private:
  67.  int32_t InitLeakMem(uint32_t ulCellSize, uint32_t ulCount);
  68.  BOOL IsMyCell(TBufCellComHead* lpBufCell);
  69. private:
  70.  TBufCellComHead *m_list;
  71.  TBufCellComHead *m_listAppend;
  72.  uint32_t m_ulCellSize;
  73.  uint32_t m_ulCurCount;
  74.  uint32_t m_ulMaxCount;
  75.  uint32_t m_ulCurActiveCount;
  76.  uint32_t m_ulMaxActiveCount;
  77.  TBufCellComHead *m_lpListHead;
  78.  TBufCellComHead *m_lpListOnProc;
  79.  TBufCellComHead *m_lpListTail;
  80.  BOOL m_bIsWorkWithEvent;
  81.  HANDLE m_hExistAcvtivedBufCell;
  82.  HANDLE m_hIsWorkExit;
  83.  HANDLE m_hWorkExit;
  84.  CRWLock m_ListHeadLock;
  85.  CRWLock m_ListTailLock;
  86.  CRWLock m_ListOnProcLock;
  87.  CRWLock m_ActiveCountLock;
  88. };
  89. #endif
  90. //CBufList.cpp
  91. #include "CBufList.h"
  92. CBufList::CBufList(void)
  93. {
  94.  m_bIsWorkWithEvent = FALSE;
  95.  m_ulCellSize = 0;
  96.  m_ulCurCount = 0;
  97.  m_ulMaxCount = 0;
  98.  m_ulCurActiveCount = 0;
  99.  m_ulMaxActiveCount = 0;
  100.  m_list = NULL;
  101.  m_listAppend = NULL;
  102.  m_lpListHead = NULL;
  103.  m_lpListTail = NULL;
  104.  m_lpListOnProc = NULL;
  105.  m_hExistAcvtivedBufCell = NULL;
  106.  m_hWorkExit = NULL;
  107.  m_hIsWorkExit = NULL;
  108. }
  109. TBufCellComHead* CBufList::AllocateOnListHead(void)
  110. {
  111.  TBufCellComHead *pTmp = NULL;
  112.  m_ListTailLock.Lock();//Disable alloc
  113.  if (m_lpListTail->eCellStatus != eFree)
  114.  {
  115.   if (m_ulCurCount >= m_ulMaxCount)
  116.   {
  117.    m_ListTailLock.UnLock();
  118.    return NULL;
  119.   }
  120.   pTmp = (TBufCellComHead *)malloc(m_ulCellSize);
  121.   if (NULL == pTmp)
  122.   {
  123.    m_ListTailLock.UnLock();
  124.    return pTmp;
  125.   }
  126.   if (NULL == m_listAppend)
  127.   {
  128.    m_listAppend = m_lpListTail;
  129.   }
  130.   memset(pTmp, 0 , m_ulCellSize);
  131.   m_ulCurCount++;
  132.   pTmp->lpPreCell = m_lpListTail;
  133.   pTmp->lpNextCell = NULL;
  134.   if (m_ulCellSize>sizeof(TBufCellComHead))
  135.   {
  136.    pTmp->lpData = (uint8_t *)pTmp + sizeof(TBufCellComHead);
  137.    pTmp->ulDataSize = m_ulCellSize - sizeof(TBufCellComHead);
  138.   }
  139.   m_lpListTail->lpNextCell = pTmp;
  140.   m_lpListTail = pTmp;
  141.  }
  142.  pTmp = m_lpListTail;
  143.  m_lpListTail = m_lpListTail->lpPreCell;
  144.  m_lpListTail->lpNextCell = NULL;
  145.  pTmp->eCellStatus = eAllocated;
  146.  pTmp->lpNextCell = NULL;
  147.  pTmp->lpPreCell = NULL;
  148.  m_ListHeadLock.Lock();
  149.  pTmp->lpNextCell = m_lpListHead;
  150.  pTmp->lpPreCell = NULL;
  151.  m_lpListHead->lpPreCell = pTmp;
  152.  m_lpListHead = pTmp;
  153.  m_ListHeadLock.UnLock();
  154.  if (NULL == m_lpListOnProc)
  155.  {
  156.   
  157.   m_ListOnProcLock.Lock();
  158.   m_lpListOnProc = pTmp;
  159.   m_ListOnProcLock.UnLock();
  160.  }
  161.  m_ListTailLock.UnLock();//Enable alloc
  162.  return pTmp;
  163. }
  164. TBufCellComHead* CBufList::AllocateInsBySortKey(uint32_t ulSortKey)
  165. {
  166.  TBufCellComHead *pTmp = NULL;
  167.  if (0 == m_ulMaxActiveCount)
  168.  {
  169.   return NULL;
  170.  }
  171.  m_ListTailLock.Lock();//Disable alloc
  172.  if (m_lpListTail->eCellStatus != eFree)
  173.  {
  174.   if (m_ulCurCount >= m_ulMaxCount)
  175.   {
  176.    m_ListTailLock.UnLock();
  177.    return NULL;
  178.   }
  179.   
  180.   pTmp = (TBufCellComHead *)malloc(m_ulCellSize);
  181.   if (NULL == pTmp)
  182.   {
  183.    m_ListTailLock.UnLock();
  184.    return pTmp;
  185.   }
  186.   if (NULL == m_listAppend)
  187.   {
  188.    m_listAppend = m_lpListTail;
  189.   }
  190.   
  191.   memset(pTmp, 0 , m_ulCellSize);
  192.   
  193.   m_ulCurCount++;
  194.   
  195.   pTmp->lpPreCell = m_lpListTail;
  196.   pTmp->lpNextCell = NULL;
  197.   if (m_ulCellSize>sizeof(TBufCellComHead))
  198.   {
  199.    pTmp->lpData = (uint8_t *)pTmp + sizeof(TBufCellComHead);
  200.    pTmp->ulDataSize = m_ulCellSize - sizeof(TBufCellComHead);
  201.   }
  202.   m_lpListTail->lpNextCell = pTmp;
  203.   m_lpListTail = pTmp;
  204.  }
  205.  pTmp = m_lpListTail;
  206.  m_lpListTail = m_lpListTail->lpPreCell;
  207.  m_lpListTail->lpNextCell = NULL;
  208.  pTmp->eCellStatus = eAllocated;
  209.  pTmp->ulSortKey = ulSortKey;
  210.  pTmp->lpNextCell = NULL;
  211.  pTmp->lpPreCell = NULL;
  212.  if (((ulSortKey>m_lpListHead->ulSortKey) && (ulSortKey-m_lpListHead->ulSortKey<HALFMAX_SORTKEY))
  213.   ||((ulSortKey<m_lpListHead->ulSortKey)&&(m_lpListHead->ulSortKey-ulSortKey>=HALFMAX_SORTKEY)))
  214.  {
  215.   m_ListHeadLock.Lock();
  216.   m_lpListHead->lpPreCell = pTmp;
  217.   pTmp->lpNextCell = m_lpListHead;
  218.   pTmp->lpPreCell = NULL;
  219.   m_lpListHead = pTmp;
  220.   m_ListHeadLock.UnLock();
  221.   if (NULL == m_lpListOnProc)
  222.   {
  223.    
  224.    m_ListOnProcLock.Lock();
  225.    m_lpListOnProc = pTmp;
  226.    m_ListOnProcLock.UnLock();
  227.   }
  228.  }
  229.  else
  230.  { 
  231.   m_ListOnProcLock.Lock();
  232.   TBufCellComHead *pTmpSort = m_lpListHead->lpNextCell;
  233.   while ((pTmpSort!=NULL) && (pTmpSort->eCellStatus!=eFree))
  234.   {
  235.    if (((ulSortKey>pTmpSort->ulSortKey) && (ulSortKey-pTmpSort->ulSortKey<HALFMAX_SORTKEY))
  236.     ||((ulSortKey<pTmpSort->ulSortKey)&&(pTmpSort->ulSortKey-ulSortKey>=HALFMAX_SORTKEY)))
  237.    {  
  238.     pTmp->lpNextCell = pTmpSort;
  239.     pTmp->lpPreCell = pTmpSort->lpPreCell;
  240.     if (pTmpSort->lpPreCell != NULL)
  241.     {
  242.      pTmpSort->lpPreCell->lpNextCell = pTmp;
  243.     }
  244.     pTmpSort->lpPreCell = pTmp;
  245.     
  246.     break;
  247.    }
  248.    pTmpSort = pTmpSort->lpNextCell;
  249.   }
  250.   
  251.   if ((NULL==pTmp->lpPreCell)&&(NULL==pTmp->lpNextCell))
  252.   { 
  253.    if (NULL == pTmpSort)
  254.    {
  255.     pTmpSort = m_lpListTail;
  256.    }
  257.    else
  258.    {
  259.     pTmpSort = pTmpSort->lpPreCell;
  260.    }
  261.    pTmp->lpNextCell = pTmpSort->lpNextCell;
  262.    pTmp->lpPreCell = pTmpSort;
  263.    if (pTmpSort->lpNextCell != NULL)
  264.    {
  265.     pTmpSort->lpNextCell->lpPreCell = pTmp;
  266.    }
  267.    pTmpSort->lpNextCell = pTmp;
  268.    if (pTmpSort == m_lpListOnProc)
  269.    {
  270.     m_lpListOnProc = pTmp;
  271.    }    
  272.    if (pTmpSort == m_lpListTail)
  273.    {
  274.     m_lpListTail = pTmp;
  275.    }
  276.   }
  277.   m_ListOnProcLock.UnLock();
  278.  }
  279.  m_ListTailLock.UnLock();//Enable alloc
  280.  return pTmp;
  281. }
  282. int32_t CBufList::Active(TBufCellComHead* lpBufCell)
  283. {
  284.  if (!IsMyCell(lpBufCell))
  285.  {
  286.   if (lpBufCell != NULL)
  287.   {  
  288.    OutputDebugString("CBufList::Active error/n");
  289.   }
  290.   return -1;
  291.  }
  292.  if (m_ulMaxActiveCount != 0)
  293.  {
  294.   m_ActiveCountLock.WLock();
  295.   lpBufCell->eCellStatus = eActived;
  296.   m_ulCurActiveCount++;
  297.   m_ActiveCountLock.WUnLock();
  298.  }
  299.  else
  300.  {
  301.   lpBufCell->eCellStatus = eActived;
  302.  }
  303.  if (m_bIsWorkWithEvent)
  304.  {
  305.   if (m_ulMaxActiveCount != 0)
  306.   {
  307.    m_ActiveCountLock.RLock();
  308.    if (m_ulCurActiveCount>=m_ulMaxActiveCount)
  309.    {
  310.     ::SetEvent(m_hExistAcvtivedBufCell);
  311.    }
  312.    m_ActiveCountLock.RUnLock();
  313.   }
  314.   
  315.   else
  316.   {
  317.    ::SetEvent(m_hExistAcvtivedBufCell);
  318.   }
  319.  }
  320.  return 0;
  321. }
  322. TBufCellComHead* CBufList::GetBufCellOnProc(void)
  323. {
  324.  if (NULL == m_lpListOnProc)
  325.  {
  326.   return NULL;
  327.  }
  328.  m_ActiveCountLock.RLock();
  329.  if ((m_ulMaxActiveCount>0) && (m_ulMaxActiveCount>m_ulCurActiveCount))
  330.  {
  331.   m_ActiveCountLock.RUnLock();
  332.   return NULL;
  333.  }
  334.  m_ActiveCountLock.RUnLock();
  335.  m_ListOnProcLock.Lock();
  336.  if (m_lpListOnProc->eCellStatus != eActived)
  337.  {
  338.   m_ListOnProcLock.UnLock();
  339.   return NULL;
  340.  }
  341.  return m_lpListOnProc;
  342. }
  343. BOOL CBufList::IsMyCell(TBufCellComHead* lpBufCell)
  344. {
  345.  TBufCellComHead *pTmp;
  346.  pTmp = m_lpListHead;
  347.  while (pTmp != NULL)
  348.  {
  349.   if (pTmp == lpBufCell)
  350.   {
  351.    return TRUE;
  352.   }
  353.   pTmp = pTmp->lpNextCell;
  354.  } 
  355.  return FALSE;
  356. }
  357. int32_t CBufList::Release(TBufCellComHead* lpBufCell)
  358. {
  359.  if (!IsMyCell(lpBufCell))
  360.  {
  361.   if (lpBufCell != NULL)
  362.   {
  363.    OutputDebugString("CBufList::Release error/n");
  364.   }
  365.   return -1;
  366.  }
  367.  if (m_ulMaxActiveCount != 0)
  368.  {
  369.   m_ActiveCountLock.WLock();
  370.   m_ulCurActiveCount--;
  371.   m_lpListOnProc->eCellStatus = eFree;
  372.   m_lpListOnProc->ulSortKey = 0;
  373.   m_ActiveCountLock.WUnLock();
  374.  }
  375.  else
  376.  {
  377.   m_lpListOnProc->eCellStatus = eFree;
  378.  }
  379.  m_lpListOnProc = m_lpListOnProc->lpPreCell;
  380.  m_ListOnProcLock.UnLock();
  381.  if (m_bIsWorkWithEvent && (m_lpListOnProc!=NULL))
  382.  {
  383.   if (m_ulMaxActiveCount>0)
  384.   {
  385.    m_ActiveCountLock.RLock();
  386.    if (m_ulMaxActiveCount<=m_ulCurActiveCount)
  387.    {
  388.     ::SetEvent(m_hExistAcvtivedBufCell);
  389.    }
  390.    m_ActiveCountLock.RUnLock();
  391.   }
  392.   else
  393.   {
  394.    ::SetEvent(m_hExistAcvtivedBufCell);
  395.   }
  396.  }
  397.  return 0;
  398. }
  399. int32_t CBufList::Init(uint32_t ulCellSize, uint32_t ulCount, 
  400.        uint32_t ulMaxCount, uint32_t ulMaxActiveCount,
  401.      BOOL bIsWorkWithEvent)
  402. {
  403.  uint32_t ulTotalSize = ulCellSize * ulCount;
  404.  TBufCellComHead *pTmp;
  405.  m_ulMaxCount = ulMaxCount;
  406.  m_ActiveCountLock.WLock();
  407.  m_ulMaxActiveCount = ulMaxActiveCount;
  408.  m_ActiveCountLock.WUnLock();
  409.  if (ulCount>ulMaxCount)
  410.  {
  411.   return -1;
  412.  }
  413.  if (bIsWorkWithEvent)
  414.  {
  415.   m_hExistAcvtivedBufCell = CreateEvent(NULL, FALSE, FALSE, NULL);
  416.   if (NULL == m_hExistAcvtivedBufCell)
  417.   {
  418.    return -1;
  419.   }
  420.   
  421.   m_hWorkExit = CreateEvent(NULL, FALSE, FALSE, NULL);
  422.   if (NULL == m_hWorkExit)
  423.   {
  424.    CloseHandle(m_hExistAcvtivedBufCell);
  425.    return -1;
  426.   }
  427.   m_hIsWorkExit = CreateEvent(NULL, TRUE, FALSE, NULL);
  428.   if (NULL == m_hIsWorkExit)
  429.   {
  430.    CloseHandle(m_hExistAcvtivedBufCell);
  431.    CloseHandle(m_hWorkExit);
  432.    return -1;
  433.   }
  434.  }
  435.  m_list = (TBufCellComHead *)malloc(ulTotalSize);
  436.  if (NULL == m_list)
  437.  {
  438.   return InitLeakMem(ulCellSize, ulCount);
  439.  }
  440.  else
  441.  {
  442.   memset(m_list, 0 , ulTotalSize);
  443.  }
  444.  m_bIsWorkWithEvent = bIsWorkWithEvent;
  445.  m_ulCellSize = ulCellSize;
  446.  m_ulCurCount = ulCount;
  447.  m_lpListHead = m_list;
  448.  m_lpListTail = (TBufCellComHead *)((uint8_t *)m_list + (ulTotalSize - ulCellSize));
  449.  m_listAppend = m_lpListTail;
  450.  m_lpListHead->lpPreCell = NULL;
  451.  pTmp = m_lpListHead;
  452.  while (pTmp != m_lpListTail)
  453.  {
  454.   pTmp->lpNextCell = (TBufCellComHead *)((uint8_t *)pTmp + ulCellSize);
  455.   pTmp->lpNextCell->lpPreCell = pTmp;
  456.   if (ulCellSize>sizeof(TBufCellComHead))
  457.   {
  458.    pTmp->lpData = (uint8_t *)pTmp + sizeof(TBufCellComHead);
  459.    pTmp->ulDataSize = ulCellSize - sizeof(TBufCellComHead);
  460.   }
  461.   pTmp = pTmp->lpNextCell;
  462.  }
  463.  if (ulCellSize>sizeof(TBufCellComHead))
  464.  {
  465.   pTmp->lpData = (uint8_t *)pTmp + sizeof(TBufCellComHead);
  466.   pTmp->ulDataSize = ulCellSize - sizeof(TBufCellComHead);
  467.  }
  468.  pTmp->lpNextCell = NULL;
  469.  return 0;
  470. }
  471. int32_t CBufList::InitLeakMem(uint32_t ulCellSize, uint32_t ulCount)
  472. {
  473.  return -1;
  474. }
  475. int32_t CBufList::Destroy(void)
  476. {
  477.  TBufCellComHead *pTmp,*pToDel;
  478.  if (m_bIsWorkWithEvent)
  479.  {
  480.   uint32_t ret;
  481.   
  482.   while (1)
  483.   {
  484.    ::SetEvent(m_hWorkExit);
  485.    
  486.    ret = WaitForSingleObject(m_hIsWorkExit, INFINITE);
  487.    if (ret != WAIT_TIMEOUT)
  488.    {
  489.     break;
  490.    }
  491.   }
  492.   
  493.   CloseHandle(m_hIsWorkExit);
  494.   CloseHandle(m_hWorkExit);  
  495.   CloseHandle(m_hExistAcvtivedBufCell);
  496.  }
  497.  if (m_list != NULL)
  498.  {
  499.   if (m_listAppend!=NULL)
  500.   {
  501.    pTmp = m_lpListHead;
  502.    while (pTmp != NULL)
  503.    {
  504.     pToDel = pTmp;
  505.     pTmp = pTmp->lpNextCell; 
  506.     if ((pToDel>m_listAppend) || (pToDel<m_list))
  507.     {
  508.      if (pToDel->lpNextCell != NULL)
  509.      {
  510.       pToDel->lpNextCell->lpPreCell = pToDel->lpPreCell;
  511.      }
  512.      
  513.      if (pToDel->lpPreCell != NULL)
  514.      {
  515.       pToDel->lpPreCell->lpNextCell = pToDel->lpNextCell;
  516.      }
  517.      free(pToDel);
  518.     }
  519.    }
  520.    m_listAppend = NULL;
  521.   }
  522.   free(m_list);
  523.   m_list = NULL;
  524.   m_lpListHead = NULL;
  525.   m_lpListTail = NULL;
  526.   m_lpListOnProc = NULL;
  527.  }
  528.  return 0;
  529. }
  530. void CBufList::WorkerExit(void)
  531. {
  532.  if (m_bIsWorkWithEvent)
  533.  {
  534.   ::SetEvent(m_hIsWorkExit);
  535.  }
  536. }

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值