// filename: CEIocpSocket.cpp
// author: enic
// date: 2013-03-30
#include "CEIocpSocket.h"
#include "CESpinLock.h"
HANDLE CEIocpSocket::ms_hIoComplete = NULL;
CEIocpSocket::~CEIocpSocket()
{
}
E_DWORD CEIocpSocket::InitIocpWorkThreads()
{
if (ms_hIoComplete != false)
{
return E_ERR;
}
SYSTEM_INFO nativeSysInfo;
::GetNativeSystemInfo(&nativeSysInfo);
E_SIZE nThreadNum = nativeSysInfo.dwNumberOfProcessors*2;
ms_hIoComplete = ::CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, NULL, nThreadNum);
Thread_EIocpSocket_StartParameter startParameter;
memset(&startParameter, NULL, sizeof(startParameter));
startParameter.hIoComplete = ms_hIoComplete;
for (E_SIZE n = 0; n < nThreadNum; ++n)
{
boost::thread newThread(
boost::bind(&CEIocpSocket::Thread_EIocpSocket, startParameter));
EIOCP_OVERLAPPED* pIocpOverlapped = new EIOCP_OVERLAPPED;
memset(pIocpOverlapped, NULL, sizeof(*pIocpOverlapped));
pIocpOverlapped->pEIocpSocket = reinterpret_cast<CEIocpSocket*>(n);
// PostQueuedCompletionStatus和GetQueuedCompletionStatus只是传递pIocpOverlapped这地址的值
// 所以对这个地址的内存管理需要程序员自己实现
BOOL bResult = PostQueuedCompletionStatus(ms_hIoComplete, n, 0, pIocpOverlapped);
if (FALSE == bResult)
{
std::cout << __FUNCTION__ << std::endl;
std::cout << "error: " << ::GetLastError() << std::endl;
}
}
return E_OK;
}
void CEIocpSocket::Thread_EIocpSocket(Thread_EIocpSocket_StartParameter pStartParameter)
{
std::cout << __FUNCTION__ << std::endl;
DWORD nLenTransferred = 0;
CEIocpSocket* pEIocpSocket = NULL;
EIOCP_OVERLAPPED* pIocpOverlapped = NULL;
ULONG_PTR ulKey = NULL;
OVERLAPPED* pOverlapped;
while(true)
{
BOOL bResult =
GetQueuedCompletionStatus(pStartParameter.hIoComplete,
&nLenTransferred,
&ulKey,
&pOverlapped,
INFINITE);
pEIocpSocket = reinterpret_cast<CEIocpSocket*>(ulKey);
pIocpOverlapped = static_cast<EIOCP_OVERLAPPED*>(pOverlapped);
if(FALSE == bResult)
{
DWORD ewLastError = ::GetLastError();
if(WAIT_TIMEOUT == ewLastError)
{
continue;
}
else
{
std::cout << __FUNCTION__ << std::endl;
std::cout << "error: " << ewLastError << std::endl;
return;
}
}
else
{
std::cout << nLenTransferred << std::endl;
std::cout << reinterpret_cast<int>(pIocpOverlapped->pEIocpSocket) << std::endl;
delete pIocpOverlapped;
}
}
}