void avatars_server_connection::connectionThread() { // This is the "infinite" loop that receives the packets from the ICQ avatar server NETLIBPACKETRECVER packetRecv = { 0 }; DWORD dwLastKeepAlive = time(0) + KEEPALIVE_INTERVAL; hPacketRecver = (HANDLE)CallService(MS_NETLIB_CREATEPACKETRECVER, (WPARAM)hConnection, 65536); packetRecv.cbSize = sizeof(packetRecv); packetRecv.dwTimeout = 1000; // timeout - for stopThread to work while (!stopThread) { int recvResult = CallService(MS_NETLIB_GETMOREPACKETS, (WPARAM)hPacketRecver, (LPARAM)&packetRecv); if (recvResult == 0) { ppro->debugLogA("Clean closure of avatar socket"); break; } if (recvResult == SOCKET_ERROR) { if (GetLastError() == ERROR_TIMEOUT) { // timeout, check if we should be still running if (Miranda_Terminated()) break; if (time(0) >= dwLastKeepAlive) { // limit frequency (HACK: on some systems select() does not work well) if (!ppro->m_bGatewayMode && ppro->getByte("KeepAlive", DEFAULT_KEEPALIVE_ENABLED)) { // send keep-alive packet icq_packet packet; packet.wLen = 0; write_flap(&packet, ICQ_PING_CHAN); sendServerPacket(&packet); } dwLastKeepAlive = time(0) + KEEPALIVE_INTERVAL; } // check if we got something to request checkRequestQueue(); continue; } if (!stopThread) ppro->debugLogA("Avatar socket closed abortively, error: %d", GetLastError()); else ppro->debugLogA("Avatar socket gracefully closed."); break; } // Deal with the packet packetRecv.bytesUsed = handleServerPackets(packetRecv.buffer, packetRecv.bytesAvailable); if (isActive && (packetRecv.bytesAvailable == packetRecv.bytesUsed)) // no packets pending checkRequestQueue(); // process request queue } { // release connection mir_cslock l(localSeqMutex); NetLib_SafeCloseHandle(&hPacketRecver); // Close the packet receiver NetLib_CloseConnection(&hConnection, FALSE); // Close the connection } { // release rates mir_cslock l(m_ratesMutex); delete m_rates; m_rates = NULL; } SAFE_FREE((void**)&pCookie); }
void avatars_server_connection::connectionThread() { // This is the "infinite" loop that receives the packets from the ICQ avatar server NETLIBPACKETRECVER packetRecv = {0}; DWORD wLastKeepAlive = 0; // we send keep-alive at most one per 30secs DWORD dwKeepAliveInterval = ppro->getDword("KeepAliveInterval", KEEPALIVE_INTERVAL); hPacketRecver = (HANDLE)CallService(MS_NETLIB_CREATEPACKETRECVER, (WPARAM)hConnection, 65536); packetRecv.cbSize = sizeof(packetRecv); packetRecv.dwTimeout = dwKeepAliveInterval < KEEPALIVE_INTERVAL ? dwKeepAliveInterval: KEEPALIVE_INTERVAL; // timeout - for stopThread to work while (!stopThread) { int recvResult = CallService(MS_NETLIB_GETMOREPACKETS, (WPARAM)hPacketRecver, (LPARAM)&packetRecv); if (recvResult == 0) { ppro->debugLogA("Clean closure of server socket"); break; } if (recvResult == SOCKET_ERROR) { if (GetLastError() == ERROR_TIMEOUT) { // timeout, check if we should be still running if (Miranda_Terminated()) { // we must stop here, cause due to a hack in netlib, we always get timeout, even if the connection is already dead stopThread = 1; continue; } #ifdef _DEBUG else ppro->debugLogA("Thread is Idle."); #endif if (GetTickCount() > wLastKeepAlive) { // limit frequency (HACK: on some systems select() does not work well) if (!ppro->m_bGatewayMode && ppro->getByte("KeepAlive", DEFAULT_KEEPALIVE_ENABLED)) { // send keep-alive packet icq_packet packet; packet.wLen = 0; write_flap(&packet, ICQ_PING_CHAN); sendServerPacket(&packet); } wLastKeepAlive = GetTickCount() + dwKeepAliveInterval; } else { // this is bad, the system does not handle select() properly #ifdef _DEBUG ppro->debugLogA("Thread is Forcing Idle."); #endif SleepEx(500, TRUE); // wait some time, can we do anything else ?? if (Miranda_Terminated()) { stopThread = 1; continue; } } // check if we got something to request checkRequestQueue(); continue; } if (!stopThread) ppro->debugLogA("Abortive closure of server socket, error: %d", GetLastError()); else ppro->debugLogA("Connection closed."); break; } // Deal with the packet packetRecv.bytesUsed = handleServerPackets(packetRecv.buffer, packetRecv.bytesAvailable); if (isActive && (packetRecv.bytesAvailable == packetRecv.bytesUsed)) // no packets pending { // process request queue checkRequestQueue(); } } { // release connection icq_lock l(localSeqMutex); NetLib_SafeCloseHandle(&hPacketRecver); // Close the packet receiver NetLib_CloseConnection(&hConnection, FALSE); // Close the connection } { // release rates icq_lock l(m_ratesMutex); SAFE_DELETE((MZeroedObject**)&m_rates); } SAFE_FREE((void**)&pCookie); }