#define _INCLUDE_THREADSAFEMEM_H_
#include "MemPoolTemplate.h"
#include "FixLenMemPoolLock.h"
#define MAXWORKTHREADNUM 7//最多7个工作线程
namespace XUANXUAN
{
class CThreadSafeMemQueue;
class CThreadSafeMemFactory;
//////////////////////////////////////////////////////////////////////////
//线程安全缓存 CThreadSafeMem
//1.数据线程建立数据项目,设置绑定用户数目分发到各IO线程,并投递到循环回收线程
//2.IO线程对相关用户处理完一次解绑定 AddBindCount
//3.回收线程轮询调用 CanFreeSafeMem 返回true就可以释放内存
//////////////////////////////////////////////////////////////////////////
class CThreadSafeMem
{
public:
friend class CThreadSafeMemFactory;
friend class CThreadSafeMemQueue;
public:
//设置内存相关处理数据的线程数目
static void SetReactorNum(unsigned short nIONum);
//检测所有相关处理线程是否已经处理完毕
bool CanFreeSafeMem() const;
//设置最大相关用户数目
void MaxBindCount(unsigned short nRefCount) const;
//相关处理线程每处理完数据就调用一次
void AddBindCount(unsigned short nHIndex) const;
//获得缓存头指针
const char* GetMemHead() const;
//获得缓存长度
unsigned int GetMemLen() const;
private:
CThreadSafeMem(const char* pOrgMem,unsigned int nOrgLen);
~CThreadSafeMem();
private:
static unsigned short s_nReactorNum; //IO线程数目
mutable const CThreadSafeMem* m_pNextSafeMem; //下一个消息缓存
mutable unsigned short m_wBindCount[MAXWORKTHREADNUM+1];//各线程操作句柄
const unsigned int m_nSize;
char m_pMemData[1];
};
class IThreadSafeMemQueueDelegate
{
public:
virtual void freeThreadSafeMemProxy(const CThreadSafeMem* &pSafeMem) = 0;
};
//////////////////////////////////////////////////////////////////////////
//线程安全缓存队列 CThreadSafeMemQueue
//链接等待回收的线程安全缓存
//////////////////////////////////////////////////////////////////////////
class CThreadSafeMemQueue
{
public:
CThreadSafeMemQueue(IThreadSafeMemQueueDelegate* pDelegate);
~CThreadSafeMemQueue();
public:
//增加数据项
void pushback(list<const CThreadSafeMem*>& listSafeMem);
//释放可回收的数据
bool CanFreeSafeMem();
private:
void pushback(const CThreadSafeMem*& pSafeMem);
private:
IThreadSafeMemQueueDelegate* const m_pSafeMemDelegate;
const CThreadSafeMem* m_pHead;
const CThreadSafeMem* m_pTail;
};
//////////////////////////////////////////////////////////////////////////
//线程安全缓存内存池CThreadSafeMemFactory
//////////////////////////////////////////////////////////////////////////
class CThreadSafeMemFactory:public IThreadSafeMemQueueDelegate
{
public:
CThreadSafeMemFactory();
const CThreadSafeMem* NewSafeMem(const char* pOrgMem,unsigned int nOrgLen);
void GetMemInfo(string& strMemInfo);
protected:
virtual void freeThreadSafeMemProxy(const CThreadSafeMem* &pSafeMem);
private:
CMemPoolTemplate<CFixLenMemPoolLock> m_memPool;
};
}
#endif
#include "ThreadSafeMem.h"
#include <assert.h>
#include <string.h>
namespace XUANXUAN
{
unsigned short CThreadSafeMem::s_nReactorNum = MAXWORKTHREADNUM;
CThreadSafeMem::CThreadSafeMem(const char* pOrgMem,unsigned int nOrgLen)
:m_pNextSafeMem(NULL)
,m_nSize(nOrgLen)
{
memset(m_wBindCount,0,sizeof(m_wBindCount));
memcpy(m_pMemData,pOrgMem,m_nSize);
}
CThreadSafeMem::~CThreadSafeMem()
{
}
unsigned int CThreadSafeMem::GetMemLen() const
{
return m_nSize;
}
const char* CThreadSafeMem::GetMemHead() const
{
return m_pMemData;
}
void CThreadSafeMem::SetReactorNum( unsigned short nIONum )
{
s_nReactorNum = nIONum;
}
bool CThreadSafeMem::CanFreeSafeMem() const
{
unsigned short localUnRefCount=0;
for (unsigned short i=0;i<s_nReactorNum;++i)
{
localUnRefCount += m_wBindCount[i];
}
return m_wBindCount[MAXWORKTHREADNUM] == localUnRefCount;
}
void CThreadSafeMem::AddBindCount(unsigned short nHIndex) const
{
assert(nHIndex<MAXWORKTHREADNUM);
m_wBindCount[nHIndex]++;
}
void CThreadSafeMem::MaxBindCount(unsigned short nRefCount) const
{
m_wBindCount[MAXWORKTHREADNUM] = nRefCount;
}
CThreadSafeMemQueue::CThreadSafeMemQueue( IThreadSafeMemQueueDelegate* pDelegate )
:m_pSafeMemDelegate(pDelegate)
,m_pHead(NULL)
,m_pTail(NULL)
{
}
CThreadSafeMemQueue::~CThreadSafeMemQueue()
{
while(CanFreeSafeMem());
}
void CThreadSafeMemQueue::pushback( list<const CThreadSafeMem*>& listSafeMem )
{
while(listSafeMem.empty()==false)
{
pushback(listSafeMem.front());
listSafeMem.pop_front();
}
}
void CThreadSafeMemQueue::pushback( const CThreadSafeMem*& pSafeMem )
{
if (pSafeMem)
{
pSafeMem->m_pNextSafeMem = NULL;
if (m_pTail)
{
m_pTail->m_pNextSafeMem = pSafeMem;
m_pTail = pSafeMem;
}
else
{
m_pHead = m_pTail = pSafeMem;
}
pSafeMem = NULL;
}
}
bool CThreadSafeMemQueue::CanFreeSafeMem()
{
bool bRet = false;
while(m_pHead && m_pHead->CanFreeSafeMem())
{
bRet = true;
const CThreadSafeMem* pTemp = m_pHead;
m_pHead = pTemp->m_pNextSafeMem;
m_pSafeMemDelegate->freeThreadSafeMemProxy(pTemp);
}
if (m_pHead==NULL)
{
m_pTail = NULL;
}
return bRet;
}
CThreadSafeMemFactory::CThreadSafeMemFactory()
{
m_memPool.SetPoolName("CSafeMemFactory");
}
const CThreadSafeMem* CThreadSafeMemFactory::NewSafeMem( const char* pOrgMem,unsigned int nOrgLen )
{
CThreadSafeMem* pSafeMem = new (m_memPool.GetMemByLen(sizeof(CThreadSafeMem)+nOrgLen))CThreadSafeMem(pOrgMem,nOrgLen);
return pSafeMem;
}
void CThreadSafeMemFactory::GetMemInfo( string& strMemInfo )
{
m_memPool.GetMemInfo(strMemInfo);
}
void CThreadSafeMemFactory::freeThreadSafeMemProxy( const CThreadSafeMem* &pSafeMem )
{
if (pSafeMem)
{
char* pCircleMem = (char*)pSafeMem;
m_memPool.PutMemByLen(pCircleMem,sizeof(CThreadSafeMem)+pSafeMem->GetMemLen());
pSafeMem = NULL;
}
}
}