DWORD __stdcall CompletionRoutine(LPVOID Param)
{
CompletionPortModel* pCP = (CompletionPortModel*)Param;
DWORD dwNumberBytes;
PPER_HANDLE_CONTEXT lpHandleContext = NULL;
LPWSAOVERLAPPED lpOverlapped = NULL;
int nResult;
BOOL bSuccess;
EnterCriticalSection(&pCP->m_CPCriSection);
++ pCP->CPThreadCount;
LeaveCriticalSection(&pCP->m_CPCriSection);
TRACE("第%d个完成端口处理线程启动。/n",pCP->CPThreadCount);
while (pCP->CPThreadRun == 1)
{
bSuccess = GetQueuedCompletionStatus(pCP->m_hCOP,&dwNumberBytes,(PULONG_PTR )&lpHandleContext,&lpOverlapped,1000);//INFINITE);
PPER_IO_CONTEXT lpPerIoContext = (PPER_IO_CONTEXT)lpOverlapped;
if (FALSE == bSuccess && pCP->CPThreadRun == 1)
{
#ifndef _DEBUG
TRACE( "GetQueuedCompletionStatus() failed: %d" , GetLastError());
#endif
if (lpPerIoContext)
{
pCP->ReleaseClient(lpPerIoContext);
pCP->InsertToLookaside(lpPerIoContext, NULL);
}
if (lpHandleContext)
{
lpHandleContext->pNext = NULL;
pCP->InsertToLookaside(NULL, lpHandleContext);
}
continue;
}
if (pCP->CPThreadRun == 1)
{
if (NULL == lpHandleContext)
{
//
//PostQueuedCompletionStatus发过来一个空的单句柄数据,表示线程要退出了。
//
TRACE("第%d个完成端口处理线程退出:PostQueuedCompletionStatus发过来一个空的单句柄数据,表示线程要退出了/n",pCP->CPThreadCount);
--pCP->CPThreadCount;
return 0;
}
#ifdef _DEBUG
// TRACE( "recv buffer data: %s %d/n", lpPerIoContext->szBuffer,lpPerIoContext->dataLen);
#endif
if(IoAccept != lpPerIoContext->IoOperation && 0 == dwNumberBytes)//非连接消息且收发数据长度为0,则关闭连接
{
pCP->OnClientClose(lpPerIoContext->unId);
pCP->ReleaseClient(lpPerIoContext);
pCP->InsertToLookaside(lpPerIoContext, NULL);
lpHandleContext->pNext = NULL;
pCP->InsertToLookaside(NULL, lpHandleContext);
continue;
}
HANDLE hResult;
PPER_HANDLE_CONTEXT lpNewperHandleContext = NULL;
switch(lpPerIoContext->IoOperation)
{
case IoAccept :
if (dwNumberBytes > 0)
{
//
//第一次连接成功并且收到了数据,将这个结点从链表中解除
//
EnterCriticalSection(&pCP->m_ListCriSection);
pCP->ReleaseNode(lpPerIoContext);
LeaveCriticalSection(&pCP->m_ListCriSection);
}
//将客户连接和服务器监听连接关联,即在客户连接中设置服务器监听连接
nResult = setsockopt(lpPerIoContext->sClient,
SOL_SOCKET,
SO_UPDATE_ACCEPT_CONTEXT,
(char *)&pCP->m_ListenSocket,
sizeof(pCP->m_ListenSocket)
);
if(SOCKET_ERROR == nResult)
{
TRACE( "SO_UPDATE_ACCEPT_CONTEXT failed to update accept socket/n" );
pCP->ReleaseClient(lpPerIoContext);
pCP->InsertToLookaside(lpPerIoContext, NULL);
continue;
}
//获取一个空闲的节点
lpNewper
{
CompletionPortModel* pCP = (CompletionPortModel*)Param;
DWORD dwNumberBytes;
PPER_HANDLE_CONTEXT lpHandleContext = NULL;
LPWSAOVERLAPPED lpOverlapped = NULL;
int nResult;
BOOL bSuccess;
EnterCriticalSection(&pCP->m_CPCriSection);
++ pCP->CPThreadCount;
LeaveCriticalSection(&pCP->m_CPCriSection);
TRACE("第%d个完成端口处理线程启动。/n",pCP->CPThreadCount);
while (pCP->CPThreadRun == 1)
{
bSuccess = GetQueuedCompletionStatus(pCP->m_hCOP,&dwNumberBytes,(PULONG_PTR )&lpHandleContext,&lpOverlapped,1000);//INFINITE);
PPER_IO_CONTEXT lpPerIoContext = (PPER_IO_CONTEXT)lpOverlapped;
if (FALSE == bSuccess && pCP->CPThreadRun == 1)
{
#ifndef _DEBUG
TRACE( "GetQueuedCompletionStatus() failed: %d" , GetLastError());
#endif
if (lpPerIoContext)
{
pCP->ReleaseClient(lpPerIoContext);
pCP->InsertToLookaside(lpPerIoContext, NULL);
}
if (lpHandleContext)
{
lpHandleContext->pNext = NULL;
pCP->InsertToLookaside(NULL, lpHandleContext);
}
continue;
}
if (pCP->CPThreadRun == 1)
{
if (NULL == lpHandleContext)
{
//
//PostQueuedCompletionStatus发过来一个空的单句柄数据,表示线程要退出了。
//
TRACE("第%d个完成端口处理线程退出:PostQueuedCompletionStatus发过来一个空的单句柄数据,表示线程要退出了/n",pCP->CPThreadCount);
--pCP->CPThreadCount;
return 0;
}
#ifdef _DEBUG
// TRACE( "recv buffer data: %s %d/n", lpPerIoContext->szBuffer,lpPerIoContext->dataLen);
#endif
if(IoAccept != lpPerIoContext->IoOperation && 0 == dwNumberBytes)//非连接消息且收发数据长度为0,则关闭连接
{
pCP->OnClientClose(lpPerIoContext->unId);
pCP->ReleaseClient(lpPerIoContext);
pCP->InsertToLookaside(lpPerIoContext, NULL);
lpHandleContext->pNext = NULL;
pCP->InsertToLookaside(NULL, lpHandleContext);
continue;
}
HANDLE hResult;
PPER_HANDLE_CONTEXT lpNewperHandleContext = NULL;
switch(lpPerIoContext->IoOperation)
{
case IoAccept :
if (dwNumberBytes > 0)
{
//
//第一次连接成功并且收到了数据,将这个结点从链表中解除
//
EnterCriticalSection(&pCP->m_ListCriSection);
pCP->ReleaseNode(lpPerIoContext);
LeaveCriticalSection(&pCP->m_ListCriSection);
}
//将客户连接和服务器监听连接关联,即在客户连接中设置服务器监听连接
nResult = setsockopt(lpPerIoContext->sClient,
SOL_SOCKET,
SO_UPDATE_ACCEPT_CONTEXT,
(char *)&pCP->m_ListenSocket,
sizeof(pCP->m_ListenSocket)
);
if(SOCKET_ERROR == nResult)
{
TRACE( "SO_UPDATE_ACCEPT_CONTEXT failed to update accept socket/n" );
pCP->ReleaseClient(lpPerIoContext);
pCP->InsertToLookaside(lpPerIoContext, NULL);
continue;
}
//获取一个空闲的节点
lpNewper