In order to avoid frequent application release the memory , using memory pool to manage buffer objects and client context object memory use.
Using the pointer to save all free memory blocks , forming the free list .
When the application memory, this pointer is not NULL, from the free list to remove a used , if take complete, on a real application memory .
1 buffer objects
Using the procedure described CIOCPBuffer per-IO data, comprising the necessary information IO operations, when submitted, the object is CIOCPBuffer
Here is the application buffer object code:
CIOCPBuffer *CIOCPServer::AllocateBuffer(int nLen){
CIOCPBuffer *pBuffer = NULL;
if(nLen>BUFFER_SIZE)
return NULL;
::EnterCriticalSection(&m_FreeBufferListLock);
if(m_pFreeBufferList == NULL)
{
pBuffer=(CIOCPBuffer*)::HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(CIOCPBuffer)+BUFFER_SIZE);
}
else
{
pBuffer = m_pFreeBufferList;
m_pFreeBufferList = m_pFreeBufferList->pNext;
pBuffer->pNext = NULL;
m_nFreeBufferCount--;
}
::LeaveCriticalSection(&m_FreeBufferListLock);
if(pBuffer!=NULL)
{
pBuffer->buff = (char*)(pBuffer+1);
pBuffer->nLen = nLen;
}
return pBuffer;
}
Here is the code to release the buffer object:
void CIOCPServer::ReleaseBuffer(CIOCPBuffer *pBuffer)
{
::EnterCriticalSection(&m_pFreeBufferListLock);
if(m_nFreeBufferCount<=m_nMaxFreeBuffers)
{
memset(pBuffer,0,sizeof(CIOCPBuffer)+BUFFERSIZE);
pBuffer->pNext = m_pFreeBufferList;
m_pFreeBufferList = pBuffer;
m_pFreeBufferCount++;
}
else
{
::HeapFree(::GetProcessHeap(),0,pBuffer);
}
::LeaveCriticalSection(&m_pFreeBufferListLock);
}
2 client area context object
Client context object is the per-Handle data, including information about the sockets, the server program receives a new connection, you create a client context object for the new connection, to record customer information.
Code buffer context object with almost the same, the release code is as follows:
void CIOCPServer::RealeaseContext(CIOCPContext *pContext)
{
if(pContext->s != INVALID_SOCKET)
::closesocket(pContext->s);
CIOCPBuffer *pNext;
while(pContext->pOutOfOrderReads !=NULL)
{
pNext = pContext->pOutOfOrderReads->pNext;
ReleaseBuffer(pContext->pOutOfOrderReads);
pContext->pOutOfOrderReads = pNext;
}
::EnterCriticalSection(&m_pFreeBufferListLock);
if(m_nFreeBufferCount<=m_nMaxFreeBuffers)
{
CRITICAL_SECTION cstmp = pContext->Lock;
memset(pContext,0,sizeof(CIOCPContext));
pContext->Lock = cstmp;
pContext->pNext = m_pFreeContextList;
m_pFreeContextList = pContext;
m_nFreeContextCount++;
}
else
{
::DeleteCriticalSection(&pContext->Lock);
::HeapFree(::GetProcessHeap(),0,pBuffer);
}
::LeaveCriticalSection(&m_pFreeBufferListLock);
}
Reproduced in: https: //my.oschina.net/u/204616/blog/545039