プログラムがフリーズしている理由を突き止めようとしていますが、GetQueuedCompletionStatus() に絞り込みました。
すべての IOCP スレッドが凍結され、スレッドが持つ唯一のブロッキング呼び出しは GetQueuedCompletionStatus() です。
関連付けられたソケットに接続している顧客がまだいる場合でも、約 30 分 ~ 6 時間の実行時間後に GetQueuedCompletionStatus() が永久にブロックし続ける理由はありますか?
これは IOCP を使用する TCP Winsock プログラムです。OSはWindows Server 2008 R2 Enterpriseです。
ありがとう。
スレッド コード:
while (TRUE)
{
pClient = NULL;
pOverlapped = NULL;
bRet = GetQueuedCompletionStatus(hCompletionPort, &dwIOLen, (LPDWORD)&pClient, (LPOVERLAPPED*)&pOverlapped, INFINITE);
if (bRet == true && pClient != NULL && pOverlapped != NULL && pClient->bConnected == true && pClient->bToDisconnect == false)
{
if (pOverlapped->bIOMode == 0) // Recv
{
if (TryEnterCriticalSection(&pClient->mNetworkReadCSection))
{
pClient->dwSockBuffLength += dwIOLen;
// Packet processing here...
WSABUF pWSABuf;
pWSABuf.buf = (char*)&pClient->mSockBuffer[pClient->dwSockBuffLength];
pWSABuf.len = 10000 - pClient->dwSockBuffLength;
DWORD dwRecvd;
DWORD dwFlags = 0;
memset(&pClient->mSockOverlapped, 0x00, sizeof(WSAOVERLAPPED));
pClient->mSockOverlapped.bIOMode = 0;
int iSent = WSARecv(pClient->ClientSocket, &pWSABuf, 1, &dwRecvd, &dwFlags, (WSAOVERLAPPED*)&pClient->mSockOverlapped, NULL);
if (iSent == SOCKET_ERROR)
{
if (WSAGetLastError() == 10053 || WSAGetLastError() == 10054 || WSAGetLastError() == 10058)
{
//pClient->bToDisconnect = true;
//LeaveCriticalSection(&pClient->mNetworkReadCSection);
OnDissconnect(pPacketWriter, pClient->iClientID);
continue;
}
if (WSAGetLastError() != 997 && WSAGetLastError() != 10004 && WSAGetLastError() != 10038)
WriteToFile("IOCPSocketErr.txt", "[%s] Socket Error: %d\n", pClient->szPlayerName, WSAGetLastError());
}
LeaveCriticalSection(&pClient->mNetworkReadCSection);
}
else
{
PostQueuedCompletionStatus(hCompletionPort, dwIOLen, (DWORD)pClient, (OVERLAPPED*)pOverlapped);
}
}
else if (pOverlapped->bIOMode == 1) // Send
{
dwBytesSent += dwIOLen;
}
}
}