void __cdecl RefreshUserDetailsWorkerThread(void*) { Thread_SetName("WhenWasIt: RefreshUserDetailsWorkerThread"); ShowPopupMessage(TranslateT("WhenWasIt"), TranslateT("Starting to refresh user details"), hRefreshUserDetails); int delay = db_get_w(NULL, ModuleName, "UpdateDelay", REFRESH_DETAILS_DELAY); MCONTACT hContact = db_find_first(); while (hContact != NULL) { CallContactService(hContact, PSS_GETINFO, 0, 0); hContact = db_find_next(hContact); if (hContact) Sleep(delay); //sleep for a few seconds between requests } ShowPopupMessage(TranslateT("WhenWasIt"), TranslateT("Done refreshing user details"), hRefreshUserDetails); }
void __cdecl CIcqProto::AvatarThread(avatars_server_connection *pInfo) { debugLogA("%s thread started.", "Avatar"); Thread_SetName("ICQ: AvatarThread"); // Execute connection handler pInfo->connectionThread(); { // Remove connection reference mir_cslock l(m_avatarsMutex); if (m_avatarsConnection == pInfo) m_avatarsConnection = NULL; // Release connection handler delete pInfo; } debugLogA("%s thread ended.", "Avatar"); }
static void FillHistoryThread(void* param) { Thread_SetName("HistoryWindow::FillHistoryThread"); THistoryThread *hInfo = (THistoryThread*)param; HWND hwndList = GetDlgItem(hInfo->hwnd, IDC_LIST); SendDlgItemMessage(hInfo->hwnd, IDC_LIST, LB_RESETCONTENT, 0, 0); int i = db_event_count(hInfo->hContact); SendDlgItemMessage(hInfo->hwnd, IDC_LIST, LB_INITSTORAGE, i, i * 40); DBEVENTINFO dbei = { sizeof(dbei) }; int oldBlobSize = 0; MEVENT hDbEvent = db_event_last(hInfo->hContact); while (hDbEvent != NULL) { if (!IsWindow(hInfo->hwnd)) break; int newBlobSize = db_event_getBlobSize(hDbEvent); if (newBlobSize > oldBlobSize) { dbei.pBlob = (PBYTE)mir_realloc(dbei.pBlob, newBlobSize); oldBlobSize = newBlobSize; } dbei.cbBlob = oldBlobSize; db_event_get(hDbEvent, &dbei); TCHAR str[200], eventText[256], strdatetime[64]; GetObjectSummary(&dbei, str, _countof(str)); if (str[0]) { TimeZone_PrintTimeStamp(NULL, dbei.timestamp, _T("d t"), strdatetime, _countof(strdatetime), 0); mir_sntprintf(eventText, _T("%s: %s"), strdatetime, str); i = SendMessage(hwndList, LB_ADDSTRING, 0, (LPARAM)eventText); SendMessage(hwndList, LB_SETITEMDATA, i, (LPARAM)hDbEvent); } hDbEvent = db_event_prev(hInfo->hContact, hDbEvent); } mir_free(dbei.pBlob); SendDlgItemMessage(hInfo->hwnd, IDC_LIST, LB_SETCURSEL, 0, 0); SendMessage(hInfo->hwnd, WM_COMMAND, MAKEWPARAM(IDC_LIST, LBN_SELCHANGE), 0); EnableWindow(GetDlgItem(hInfo->hwnd, IDC_LIST), TRUE); mir_free(hInfo); }
// thread func static unsigned __stdcall PopupThread(void *) { Thread_SetName("Popup: PopupThread"); // Create manager window DWORD err; WNDCLASSEX wcl; wcl.cbSize = sizeof(wcl); wcl.lpfnWndProc = PopupThreadManagerWndProc; wcl.style = 0; wcl.cbClsExtra = 0; wcl.cbWndExtra = 0; wcl.hInstance = hInst; wcl.hIcon = NULL; wcl.hCursor = LoadCursor(NULL, IDC_ARROW); wcl.hbrBackground = (HBRUSH)GetStockObject(LTGRAY_BRUSH); wcl.lpszMenuName = NULL; wcl.lpszClassName = _T("PopupThreadManagerWnd"); wcl.hIconSm = (HICON)LoadImage(hInst, MAKEINTRESOURCE(IDI_POPUP), IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), LR_DEFAULTCOLOR); g_wndClass.cPopupThreadManagerWnd = RegisterClassEx(&wcl); err = GetLastError(); if (!g_wndClass.cPopupThreadManagerWnd) { TCHAR msg[1024]; mir_sntprintf(msg, TranslateT("Failed to register %s class."), wcl.lpszClassName); MSGERROR(msg); } gHwndManager = CreateWindow(_T("PopupThreadManagerWnd"), NULL, 0, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, HWND_DESKTOP, NULL, hInst, NULL); SetWindowPos(gHwndManager, 0, 0, 0, 0, 0, SWP_NOZORDER | SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | SWP_DEFERERASE | SWP_NOSENDCHANGING | SWP_HIDEWINDOW); MSG msg; while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } DestroyWindow(gHwndManager); gHwndManager = NULL; return 0; }
void CJabberIqManager::ExpirerThread() { Thread_SetName("Jabber: ExpirerThread"); while (!m_bExpirerThreadShutdownRequest) { CJabberIqInfo *pInfo = DetouchExpired(); if (!pInfo) { for (int i=0; !m_bExpirerThreadShutdownRequest && (i < 10); i++) Sleep(50); // -1 thread :) ppro->m_adhocManager.ExpireSessions(); continue; } ExpireInfo(pInfo); } if (!m_bExpirerThreadShutdownRequest) { CloseHandle(m_hExpirerThread); m_hExpirerThread = NULL; } }
void __cdecl CJabberProto::ExpirerThread(void* pParam) { Thread_SetName("Jabber: ExpirerThread"); CJabberIqManager *pManager = (CJabberIqManager *)pParam; pManager->ExpirerThread(); }
void CToxProto::SearchByNameAsync(void *arg) { Thread_SetName("TOX: SearchByNameAsync"); char *query = (char*)arg; char *name = strtok(query, "@"); char *domain = strtok(NULL, ""); /*int resolved = 0; if (IsFileExists((TCHAR*)VARST(_T(TOX_INI_PATH)))) { char fileName[MAX_PATH]; mir_strcpy(fileName, VARS(TOX_INI_PATH)); char *section, sections[MAX_PATH], value[TOX_PUBLIC_KEY_SIZE * 2]; GetPrivateProfileSectionNamesA(sections, _countof(sections), fileName); section = sections; while (*section != NULL) { if (strstr(section, "Dns_") == section) { GetPrivateProfileStringA(section, "Domain", NULL, value, _countof(value), fileName); ptrA dnsDomain(mir_strdup(value)); GetPrivateProfileStringA(section, "PubKey", NULL, value, _countof(value), fileName); ToxBinAddress dnsPubKey = value; if (domain == NULL || mir_strcmpi(domain, dnsDomain) == 0) { void *dns = tox_dns3_new((uint8_t*)(const uint8_t*)dnsPubKey); uint32_t requestId = 0; uint8_t dnsString[MAX_PATH]; size_t length = tox_generate_dns3_string(dns, dnsString, sizeof(dnsString), &requestId, (uint8_t*)CharLowerA(name), (uint8_t)mir_strlen(name)); if (length != TOX_ERROR) { dnsString[length] = 0; char dnsQuery[MAX_PATH * 2]; mir_snprintf(dnsQuery, "_%s._tox.%s", dnsString, dnsDomain); ToxHexAddress address = ResolveToxAddressFromDns(dnsQuery); if (!address.IsEmpty()) { PROTOSEARCHRESULT psr = { sizeof(PROTOSEARCHRESULT) }; psr.flags = PSR_UTF8; psr.id.a = mir_strdup(address); psr.nick.a = mir_strdup(name); char email[MAX_PATH]; mir_snprintf(email, "%s@%s", name, domain); psr.email.a = mir_strdup(email); ProtoBroadcastAck(NULL, ACKTYPE_SEARCH, ACKRESULT_DATA, (HANDLE)1, (LPARAM)&psr); break; } } tox_dns3_kill(dns); } } section += mir_strlen(section) + 1; } } if (resolved == 0 && domain) { char dnsQuery[MAX_PATH]; mir_snprintf(dnsQuery, "%s._tox.%s", name, domain); ToxHexAddress address = ResolveToxAddressFromDns(dnsQuery); if (!address.IsEmpty()) { PROTOSEARCHRESULT psr = { sizeof(PROTOSEARCHRESULT) }; psr.flags = PSR_UTF8; psr.id.a = mir_strdup(address); psr.nick.a = mir_strdup(name); char email[MAX_PATH]; mir_snprintf(email, "%s@%s", name, domain); psr.email.a = mir_strdup(email); ProtoBroadcastAck(NULL, ACKTYPE_SEARCH, ACKRESULT_DATA, (HANDLE)1, (LPARAM)&psr); } }*/ ToxHexAddress address = ResolveToxAddressFromToxme(m_hNetlibUser, query); if (!address.IsEmpty()) { PROTOSEARCHRESULT psr = { sizeof(PROTOSEARCHRESULT) }; psr.flags = PSR_UTF8; psr.id.a = mir_strdup(address); psr.nick.a = mir_strdup(name); char email[MAX_PATH]; mir_snprintf(email, "*****@*****.**", name); psr.email.a = mir_strdup(email); ProtoBroadcastAck(NULL, ACKTYPE_SEARCH, ACKRESULT_DATA, (HANDLE)1, (LPARAM)&psr); } ProtoBroadcastAck(NULL, ACKTYPE_SEARCH, ACKRESULT_SUCCESS, (HANDLE)1, 0); mir_free(arg); }
void CToxProto::SearchFailedAsync(void*) { Thread_SetName("TOX: SearchFailedAsync"); ProtoBroadcastAck(NULL, ACKTYPE_SEARCH, ACKRESULT_FAILED, (HWND)1, 0); }
static void DoSplitSendA(LPVOID param) { Thread_SetName("TabSRMM: DoSplitSendA"); SendJob *job = sendQueue->getJobByIndex((INT_PTR)param); size_t iLen = mir_strlen(job->szSendBuffer); ptrA szBegin((char*)mir_alloc(iLen + 1)); char *szTemp = szBegin; memcpy(szTemp, job->szSendBuffer, iLen + 1); bool fFirstSend = false, fSplitting = true; int iCur = 0; do { iCur += job->chunkSize; if (iCur > iLen) fSplitting = FALSE; if (fSplitting) { job->iAcksNeeded++; char *szSaved = &szBegin[iCur]; int iSavedCur = iCur; for (int i = 0; iCur; i++, iCur--) { if (szBegin[iCur] == ' ') { szSaved = &szBegin[iCur]; break; } if (i == SPLIT_WORD_CUTOFF) { iCur = iSavedCur; szSaved = &szBegin[iCur]; break; } } char savedChar = *szSaved; *szSaved = 0; int id = CallContactService(job->hContact, PSS_MESSAGE, job->dwFlags, (LPARAM)szTemp); if (!fFirstSend) { job->hSendId = (HANDLE)id; fFirstSend = TRUE; PostMessage(PluginConfig.g_hwndHotkeyHandler, DM_SPLITSENDACK, (WPARAM)param, 0); } *szSaved = savedChar; szTemp = szSaved; if (savedChar == ' ') { szTemp++; iCur++; } } else { int id = CallContactService(job->hContact, PSS_MESSAGE, job->dwFlags, (LPARAM)szTemp); if (!fFirstSend) { job->hSendId = (HANDLE)id; fFirstSend = TRUE; PostMessage(PluginConfig.g_hwndHotkeyHandler, DM_SPLITSENDACK, (WPARAM)param, 0); } } Sleep(500L); } while (fSplitting); }
void __cdecl CIcqProto::InfoUpdateThread( void* ) { int i; DWORD dwWait = WAIT_OBJECT_0; debugLogA("%s thread starting.", "Info-Update"); Thread_SetName("ICQ: InfoUpdateThread"); bInfoUpdateRunning = TRUE; while (bInfoUpdateRunning) { if (!nInfoUserCount && bInfoPendingUsers) // whole queue processed, check if more users needs updating icq_RescanInfoUpdate(); if (!nInfoUserCount || !bInfoUpdateEnabled || !icqOnline()) { dwWait = WAIT_TIMEOUT; while (bInfoUpdateRunning && dwWait == WAIT_TIMEOUT) // wait for new work or until we should end dwWait = ICQWaitForSingleObject(hInfoQueueEvent, 10000); } if (!bInfoUpdateRunning) break; switch (dwWait) { case WAIT_IO_COMPLETION: // Possible shutdown in progress break; case WAIT_OBJECT_0: case WAIT_TIMEOUT: // Time to check for new users if (!bInfoUpdateEnabled) continue; // we can't send requests now if (nInfoUserCount && icqOnline()) { time_t now = time(NULL); BOOL bNotReady = FALSE, bTimeOuted = FALSE; // Check the list, take only users that were there for at least 5sec // wait if any user is there shorter than 5sec and not a single user is there longer than 20sec { mir_cslock l(infoUpdateMutex); for (i = 0; i < LISTSIZE; i++) { if (m_infoUpdateList[i].hContact) { if (m_infoUpdateList[i].queued + 20 < now) { bTimeOuted = TRUE; break; } if (m_infoUpdateList[i].queued + 5 >= now) bNotReady = TRUE; } } } if (!bTimeOuted && bNotReady) { SleepEx(1000, TRUE); if (!bInfoUpdateRunning) { // need to end as fast as possible debugLogA("%s thread ended.", "Info-Update"); goto LBL_Exit; } continue; } // only send another request, when the previous is completed if (FindCookie(dwInfoActiveRequest, NULL, NULL)) { debugLogA("Info-Update: Request 0x%x still in progress.", dwInfoActiveRequest); SleepEx(1000, TRUE); if (!bInfoUpdateRunning) { // need to end as fast as possible debugLogA("%s thread ended.", "Info-Update"); goto LBL_Exit; } continue; } debugLogA("Info-Update: Users %u in queue.", nInfoUserCount); // Either some user is waiting long enough, or all users are ready (waited at least the minimum time) mir_cslockfull rlck(m_ratesMutex); if (!m_rates) // we cannot send info request - icq is offline break; WORD wGroup = m_rates->getGroupFromSNAC(ICQ_EXTENSIONS_FAMILY, ICQ_META_CLI_REQUEST); while (m_rates->getNextRateLevel(wGroup) < m_rates->getLimitLevel(wGroup, RML_IDLE_30)) { // we are over rate, need to wait before sending int nDelay = m_rates->getDelayToLimitLevel(wGroup, RML_IDLE_50); rlck.unlock(); debugLogA("Rates: InfoUpdate delayed %dms", nDelay); SleepEx(nDelay, TRUE); // do not keep things locked during sleep if (!bInfoUpdateRunning) { // need to end as fast as possible debugLogA("%s thread ended.", "Info-Update"); goto LBL_Exit; } rlck.lock(); if (!m_rates) // we lost connection when we slept, go away break; } if (!m_rates) // we cannot send info request - icq is offline break; rlck.unlock(); userinfo *hContactList[LISTSIZE]; int nListIndex = 0; BYTE *pRequestData = NULL; size_t nRequestSize = 0; mir_cslock l(infoUpdateMutex); for (i = 0; i < LISTSIZE; i++) { if (m_infoUpdateList[i].hContact) { // check TS again, maybe it has been updated while we slept if (IsMetaInfoChanged(m_infoUpdateList[i].hContact)) { if (m_infoUpdateList[i].queued + 5 < now) { BYTE *pItem = NULL; size_t nItemSize = 0; DBVARIANT dbv = { DBVT_DELETED }; if (!getSetting(m_infoUpdateList[i].hContact, DBSETTING_METAINFO_TOKEN, &dbv)) { // retrieve user details using privacy token ppackTLV(&pItem, &nItemSize, 0x96, dbv.cpbVal, dbv.pbVal); db_free(&dbv); } // last updated time ppackTLVDouble(&pItem, &nItemSize, 0x64, getSettingDouble(m_infoUpdateList[i].hContact, DBSETTING_METAINFO_TIME, 0)); ppackTLVUID(&pItem, &nItemSize, 0x32, m_infoUpdateList[i].dwUin, NULL); ppackWord(&pRequestData, &nRequestSize, (WORD)nItemSize); ppackBuffer(&pRequestData, &nRequestSize, nItemSize, pItem); // take a reference SAFE_FREE((void**)&pItem); hContactList[nListIndex++] = &m_infoUpdateList[i]; } } else { debugLogA("Dequeued absolete user %u", m_infoUpdateList[i].dwUin); // Dequeue user and find another one m_infoUpdateList[i].dwUin = 0; m_infoUpdateList[i].hContact = NULL; nInfoUserCount--; // continue for loop } } } debugLogA("Request info for %u user(s).", nListIndex); if (!nListIndex) // no users to request info for break; if (!(dwInfoActiveRequest = sendUserInfoMultiRequest(pRequestData, nRequestSize, nListIndex))) { // sending data packet failed SAFE_FREE((void**)&pRequestData); break; } SAFE_FREE((void**)&pRequestData); for (i = 0; i < nListIndex; i++) { // Dequeue users and go back to sleep hContactList[i]->dwUin = 0; hContactList[i]->hContact = NULL; hContactList[i]->queued = 0; nInfoUserCount--; } } break; default: // Something strange happened. Exit bInfoUpdateRunning = FALSE; break; } } debugLogA("%s thread ended.", "Info-Update"); LBL_Exit: CloseHandle(hInfoQueueEvent); }