in GomokuServer/GomokuServer/IOThread.cpp [35:111]
void IOThread::DoIocpJob()
{
DWORD dwTransferred = 0;
LPOVERLAPPED overlapped = nullptr;
ULONG_PTR completionKey = 0;
int ret = GetQueuedCompletionStatus(mCompletionPort, &dwTransferred, (PULONG_PTR)&completionKey, &overlapped, GQCS_TIMEOUT);
/// general I/O processing
OverlappedIOContext* context = reinterpret_cast<OverlappedIOContext*>(overlapped);
SessionPtr remote = context ? context->mSessionObject : nullptr;
if (ret == 0 || dwTransferred == 0)
{
/// check time out first
if ( context == nullptr && GetLastError() == WAIT_TIMEOUT)
return;
if (context->mIoType == IO_RECV || context->mIoType == IO_SEND)
{
CRASH_ASSERT(nullptr != remote);
/// In most cases in here: ERROR_NETNAME_DELETED(64)
remote->Disconnect(DR_COMPLETION_ERROR);
DeleteIoContext(context);
return;
}
}
CRASH_ASSERT(nullptr != remote);
bool completionOk = false;
switch (context->mIoType)
{
case IO_RECV_ZERO:
completionOk = remote->PostRecv();
break;
case IO_SEND:
remote->SendCompletion(dwTransferred);
if (context->mWsaBuf.len != dwTransferred)
GConsoleLog->PrintOut(true, "Partial SendCompletion requested [%d], sent [%d]\n", context->mWsaBuf.len, dwTransferred);
else
completionOk = true;
break;
case IO_RECV:
remote->RecvCompletion(dwTransferred);
completionOk = remote->PreRecv();
break;
default:
GConsoleLog->PrintOut(true, "Unknown I/O Type: %d\n", context->mIoType);
CRASH_ASSERT(false);
break;
}
if (!completionOk)
{
/// connection closing
remote->Disconnect(DR_IO_REQUEST_ERROR);
}
DeleteIoContext(context);
}