unsigned int WINAPI IocpManager::IoWorkerThread(LPVOID lpParam) { LThreadType = THREAD_IO_WORKER; LIoThreadId = reinterpret_cast<int>(lpParam); HANDLE hComletionPort = GIocpManager->GetComletionPort(); while (true) { DWORD dwTransferred = 0; OverlappedIOContext* context = nullptr; ClientSession* asCompletionKey = nullptr; int ret = 0; ///<여기에는 GetQueuedCompletionStatus(hComletionPort, ..., GQCS_TIMEOUT)를 수행한 결과값을 대입 /// check time out first if (ret == 0 && GetLastError()==WAIT_TIMEOUT) continue; if (ret == 0 || dwTransferred == 0) { /// connection closing asCompletionKey->Disconnect(DR_RECV_ZERO); GSessionManager->DeleteClientSession(asCompletionKey); continue; } // if (nullptr == context) 인 경우 처리 //{ //} bool completionOk = true; switch (context->mIoType) { case IO_SEND: completionOk = SendCompletion(asCompletionKey, context, dwTransferred); break; case IO_RECV: completionOk = ReceiveCompletion(asCompletionKey, context, dwTransferred); break; default: printf_s("Unknown I/O Type: %d\n", context->mIoType); break; } if ( !completionOk ) { /// connection closing asCompletionKey->Disconnect(DR_COMPLETION_ERROR); GSessionManager->DeleteClientSession(asCompletionKey); } } return 0; }
unsigned int WINAPI IOCP_Manager::IoWorkerThread(LPVOID lpParam) { LThreadType = THREAD_TYPE::THREAD_IO_WORKER; LIoThreadID = reinterpret_cast<int>(lpParam); HANDLE hCompletionPort = GIOCP_Manager->GetCompletionPort(); while (true) { DWORD dwTransferred = 0; OverlappedIOContext* context = nullptr; ClientSession* asCompletionKey = nullptr; int ret = GetQueuedCompletionStatus(hCompletionPort, &dwTransferred, (ULONG_PTR*)&asCompletionKey, (LPOVERLAPPED*)&context, GQCS_TIMEOUT); if (ret == 0 && GetLastError() == WAIT_TIMEOUT) { continue; } if (ret == 0 || dwTransferred == 0) { asCompletionKey->Disconnect(DisconnectReason::DR_RECV_ZERO); GSessionManager->DeleteClientSession(asCompletionKey); continue; } if (context == nullptr) { printf_s("not dequeue completion packet\n"); continue; } bool completionOk = true; switch (context->mIoType) { case IOType::IO_SEND: completionOk = SendCompletion(asCompletionKey, context, dwTransferred); break; case IOType::IO_RECV: completionOk = ReceiveCompletion(asCompletionKey, context, dwTransferred); break; default: printf_s("Unkonw I/O type: %d\n", context->mIoType); break; } if (!completionOk) { asCompletionKey->Disconnect(DisconnectReason::DR_COMPLETION_ERROR); GSessionManager->DeleteClientSession(asCompletionKey); } } return 0; }
unsigned int WINAPI IocpManager::IoWorkerThread(LPVOID lpParam) { LThreadType = THREAD_IO_WORKER; LIoThreadId = reinterpret_cast<int>(lpParam); LTimer = new Timer; LLockOrderChecker = new LockOrderChecker(LIoThreadId); HANDLE hComletionPort = GIocpManager->GetComletionPort(); while (true) { /// 타이머 작업은 항상 돌리고 LTimer->DoTimerJob(); /// IOCP 작업 돌리기 DWORD dwTransferred = 0; OverlappedIOContext* context = nullptr; ULONG_PTR completionKey = 0; int ret = GetQueuedCompletionStatus(hComletionPort, &dwTransferred, (PULONG_PTR)&completionKey, (LPOVERLAPPED*)&context, GQCS_TIMEOUT); ClientSession* theClient = context ? context->mSessionObject : nullptr ; if (ret == 0 || dwTransferred == 0) { int gle = GetLastError(); /// check time out first if (gle == WAIT_TIMEOUT) continue; if (context->mIoType == IO_RECV || context->mIoType == IO_SEND ) { CRASH_ASSERT(nullptr != theClient); /// In most cases in here: ERROR_NETNAME_DELETED(64) theClient->DisconnectRequest(DR_COMPLETION_ERROR); DeleteIoContext(context); continue; } } CRASH_ASSERT(nullptr != theClient); bool completionOk = false; switch (context->mIoType) { case IO_DISCONNECT: theClient->DisconnectCompletion(static_cast<OverlappedDisconnectContext*>(context)->mDisconnectReason); completionOk = true; break; case IO_ACCEPT: theClient->AcceptCompletion(); completionOk = true; break; case IO_RECV_ZERO: completionOk = PreReceiveCompletion(theClient, static_cast<OverlappedPreRecvContext*>(context), dwTransferred); break; case IO_SEND: completionOk = SendCompletion(theClient, static_cast<OverlappedSendContext*>(context), dwTransferred); break; case IO_RECV: completionOk = ReceiveCompletion(theClient, static_cast<OverlappedRecvContext*>(context), dwTransferred); break; default: printf_s("Unknown I/O Type: %d\n", context->mIoType); CRASH_ASSERT(false); break; } if ( !completionOk ) { /// connection closing theClient->DisconnectRequest(DR_IO_REQUEST_ERROR); } DeleteIoContext(context); } return 0; }
unsigned int WINAPI IocpManager::IoWorkerThread(LPVOID lpParam) { LThreadType = THREAD_IO_WORKER; LIoThreadId = reinterpret_cast<int>(lpParam); HANDLE hCompletionPort = GIocpManager->GetCompletionPort(); printf_s("Started thread for completion port %d \n", hCompletionPort); while (true) { DWORD dwTransferred = 0; OverlappedIOContext* context = nullptr; ClientSession* asCompletionKey = nullptr; int ret = GetQueuedCompletionStatus( hCompletionPort, // _In_ HANDLE CompletionPort, &dwTransferred, // Out_ LPDWORD lpNumberOfBytes, (PULONG_PTR)&asCompletionKey, // _Out_ PULONG_PTR lpCompletionKey, (LPOVERLAPPED*)&context, // _Out_ LPOVERLAPPED *lpOverlapped, GQCS_TIMEOUT // _In_ DWORD dwMilliseconds ); /// check time out first if (ret == 0 && GetLastError()==WAIT_TIMEOUT) continue; if (ret == 0 || dwTransferred == 0) { /// connection closing asCompletionKey->Disconnect(DR_RECV_ZERO); GSessionManager->DeleteClientSession(asCompletionKey); continue; } if (context == nullptr) { asCompletionKey->Disconnect(DR_RECV_ZERO); GSessionManager->DeleteClientSession(asCompletionKey); } bool completionOk = true; switch (context->mIoType) { case IO_SEND: completionOk = SendCompletion(asCompletionKey, context, dwTransferred); break; case IO_RECV: completionOk = ReceiveCompletion(asCompletionKey, context, dwTransferred); break; default: printf_s("Unknown I/O Type: %d\n", context->mIoType); break; } if ( !completionOk ) { /// connection closing asCompletionKey->Disconnect(DR_COMPLETION_ERROR); GSessionManager->DeleteClientSession(asCompletionKey); } } return 0; }