DWORD WINAPI SslSocketCpServer::ServerWorkerThread(LPVOID lpObject) { SslSocketCpServer *obj = (SslSocketCpServer*)lpObject; HANDLE CompletionPort = (HANDLE)obj->GetCompletionPort(); DWORD BytesTransferred; LPPER_HANDLE_DATA PerHandleData; LPPER_IO_OPERATION_DATA PerIoData, PerIoDataSend; DWORD SendBytes, RecvBytes; DWORD Flags; HttpRequest httpRequest; HttpResponse httpResponse; DWORD dwThreadId = GetCurrentThreadId(); while (TRUE) { BytesTransferred = 0; BOOL res1 = GetQueuedCompletionStatus(CompletionPort, &BytesTransferred, (PULONG_PTR)&PerHandleData, (LPOVERLAPPED *)&PerIoData, INFINITE); if (res1 == 0) { fprintf(stderr, "%d::ServerWorkerThread--GetQueuedCompletionStatus() failed with error %d\n", dwThreadId, GetLastError()); return 0; } else fprintf(stderr, "%d::ServerWorkerThread--GetQueuedCompletionStatus() is OK!\n", dwThreadId); printf("\n\n%d::WSARECV2 Socket=%d, BytesTransferred=%d; PerIoData->BytesRECV=%d; PerIoData->BytesSEND=%d\n\n", dwThreadId, PerHandleData->Socket, BytesTransferred, PerIoData->BytesRECV, PerIoData->BytesSEND); bool cond1 = (BytesTransferred > 0 && PerIoData->BytesRECV == 0 && PerIoData->BytesSEND == 0 && PerIoData->DataBuf.len > 0); bool cond2 = (PerIoData->BytesRECV > 0); if (cond1 || cond2) { ::WaitForSingleObject(obj->ghMutex, INFINITE); if ((PerIoDataSend = (LPPER_IO_OPERATION_DATA)GlobalAlloc(GPTR, sizeof(PER_IO_OPERATION_DATA))) == NULL) { printf("%d::ERROR: allocate of PerIoDataSend is null \n", dwThreadId); continue; } assert(PerIoDataSend != NULL); httpRequest.Parse(PerIoData->DataBuf.buf); obj->Dispatch(&httpRequest, &httpResponse); ZeroMemory(PerIoDataSend->Buffer, DATA_BUFSIZE); ZeroMemory(&(PerIoDataSend->Overlapped), sizeof(OVERLAPPED)); PerIoDataSend->DataBuf.buf = (char*)httpResponse.GetResponse2(&PerIoDataSend->DataBuf.len); PerIoDataSend->BytesRECV = 0; int res = WSASend(PerHandleData->Socket, &(PerIoDataSend->DataBuf), 1, &PerIoDataSend->BytesSEND, 0, &(PerIoDataSend->Overlapped), NULL); if (res == SOCKET_ERROR) { fprintf(stderr, "%d::ServerWorkerThread--WSASend() failed with error %d\n", dwThreadId, WSAGetLastError()); } SendBytes = PerIoDataSend->BytesSEND; printf("\n\n%d::WSASEND: Socket=%d; SendBytes=%d; PerIoDataSend->BytesRECV=%d; PerIoDataSend->BytesSEND=%d\n\n", dwThreadId, PerHandleData->Socket, SendBytes, PerIoDataSend->BytesRECV, PerIoDataSend->BytesSEND); ::ReleaseMutex(obj->ghMutex); continue; } bool b1 = BytesTransferred > 0 && PerIoData->BytesRECV == 0 && PerIoData->DataBuf.len > 0; bool b2 = BytesTransferred == 0 && PerIoData->BytesRECV == 0 && PerIoData->DataBuf.len > 0; if (b1 || b2) { printf("%d::ServerWorkerThread--Closing socket %d\n", dwThreadId, PerHandleData->Socket); if (closesocket(PerHandleData->Socket) == SOCKET_ERROR) { fprintf(stderr, "%d::ServerWorkerThread--closesocket() failed with error %d\n", dwThreadId, WSAGetLastError()); return 0; } else fprintf(stderr, "%d::ServerWorkerThread--closesocket() is fine!\n", dwThreadId); GlobalFree(PerHandleData); GlobalFree(PerIoData); continue; } printf("\n\n\n\nUnhandled condition. IP should not reach line. \n\n\n\n"); exit(1); } }