From cb4a46e7fbe62d788e66ed6121c717a2d22a4d7c Mon Sep 17 00:00:00 2001 From: watcherhd Date: Thu, 21 Apr 2011 14:14:52 +0000 Subject: svn.miranda.im is moving to a new home! git-svn-id: http://miranda-plugins.googlecode.com/svn/trunk@7 e753b5eb-9565-29b2-b5c5-2cc6f99dfbcb --- icqj_mod/icq_infoupdate.c | 355 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 355 insertions(+) create mode 100644 icqj_mod/icq_infoupdate.c (limited to 'icqj_mod/icq_infoupdate.c') diff --git a/icqj_mod/icq_infoupdate.c b/icqj_mod/icq_infoupdate.c new file mode 100644 index 0000000..a9a80d3 --- /dev/null +++ b/icqj_mod/icq_infoupdate.c @@ -0,0 +1,355 @@ +// ---------------------------------------------------------------------------80 +// ICQ plugin for Miranda Instant Messenger +// ________________________________________ +// +// Copyright © 2000,2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede +// Copyright © 2001,2002 Jon Keating, Richard Hughes +// Copyright © 2002,2003,2004 Martin Öberg, Sam Kothari, Robert Rainwater +// Copyright © 2004,2005,2006 Joe Kucera +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// ----------------------------------------------------------------------------- +// +// File name : $Source: /cvsroot/miranda/miranda/protocols/IcqOscarJ/icq_infoupdate.c,v $ +// Revision : $Revision: 2874 $ +// Last change on : $Date: 2006-05-16 23:38:00 +0200 (Tue, 16 May 2006) $ +// Last change by : $Author: ghazan $ +// +// DESCRIPTION: +// +// Describe me here please... +// +// ----------------------------------------------------------------------------- + +#include "icqoscar.h" + + +#define LISTSIZE 100 +static CRITICAL_SECTION listmutex; +static HANDLE hQueueEvent = NULL; +static HANDLE hDummyEvent = NULL; +static int nUserCount = 0; +static int bPendingUsers = 0; +static BOOL bEnabled = TRUE; +static BOOL bPaused = FALSE; +static BOOL bRunning = FALSE; +static DWORD tLast; +static HANDLE hInfoThread = NULL; +static DWORD dwUpdateThreshold; +typedef struct s_userinfo { + DWORD dwUin; + HANDLE hContact; +} userinfo; +static userinfo userList[LISTSIZE]; + + +// Retrieve users' info +unsigned __stdcall icq_InfoUpdateThread(void* arg); + + + +void icq_InitInfoUpdate(void) +{ + int i; + + // Create wait objects + hQueueEvent = CreateEvent(NULL, FALSE, FALSE, NULL); + hDummyEvent = CreateEvent(NULL, FALSE, FALSE, NULL); + + if (hQueueEvent && hDummyEvent) + { + // Init mutexes + InitializeCriticalSection(&listmutex); + + // Init list + for (i = 0; i 0) + { + int i, nChecked = 0; + // Check if in list + EnterCriticalSection(&listmutex); + for (i = 0; (i dwUpdateThreshold) + { + // Queue user + if (!icq_QueueUser(hContact)) + { // The queue is full, pause queuing contacts + bPendingUsers = 1; + break; + } + } + hContact = ICQFindNextContact(hContact); + } + icq_EnableUserLookup(bOldEnable); // wake up thread +} + + + +void icq_EnableUserLookup(BOOL bEnable) +{ + bEnabled = bEnable; + + if (bEnabled) bPaused = FALSE; + + // Notify worker thread + if (bEnabled && hQueueEvent) + SetEvent(hQueueEvent); +} + + + +void icq_PauseUserLookup() +{ + bPaused = TRUE; + tLast = GetTickCount(); + +#ifdef _DEBUG + NetLog_Server("Pausing Auto-info update thread..."); +#endif +} + + + +unsigned __stdcall icq_InfoUpdateThread(void* arg) +{ + int i; + DWORD dwWait; + + bRunning = TRUE; + + while (bRunning) + { + // Wait for a while + ResetEvent(hQueueEvent); + + if (!nUserCount && bPendingUsers) // whole queue processed, check if more users needs updating + icq_RescanInfoUpdate(); + + if ((nUserCount > 0) && bEnabled && icqOnline) + dwWait = WaitForSingleObjectEx(hDummyEvent, 3000, TRUE); + else + { // we need to slow down the process or icq will kick us + dwWait = WaitForSingleObjectEx(hDummyEvent, 1000, TRUE); + while (bRunning && dwWait == WAIT_TIMEOUT) + { // wait for new work or until we should end + dwWait = WaitForSingleObjectEx(hQueueEvent, 10000, TRUE); + } + } + if (!bRunning) 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 (!bEnabled) continue; // we can't send requests now + + if (bPaused) + { // pause for 30sec + if (GetTickCount()-tLast>30000) + { + bPaused = FALSE; +#ifdef _DEBUG + NetLog_Server("Resuming auto-info update thread..."); +#endif + } + continue; + } + tLast = GetTickCount(); + +#ifdef _DEBUG + NetLog_Server("Users %u", nUserCount); +#endif + if (nUserCount && icqOnline) + { + EnterCriticalSection(&listmutex); + for (i = 0; i dwUpdateThreshold) { +#ifdef _DEBUG + NetLog_Server("Request info for user %u", userList[i].dwUin); +#endif + sendUserInfoAutoRequest(userList[i].dwUin); + + // Dequeue user and go back to sleep + userList[i].dwUin = 0; + userList[i].hContact = NULL; + nUserCount--; + break; + } + else + { +#ifdef _DEBUG + NetLog_Server("Dequeued absolete user %u", userList[i].dwUin); +#endif + // Dequeue user and find another one + userList[i].dwUin = 0; + userList[i].hContact = NULL; + nUserCount--; + // continue for loop + } + } + } + LeaveCriticalSection(&listmutex); + } + break; + + default: + // Something strange happened. Exit + bRunning = FALSE; + break; + } + } + + return 0; +} + + + +// Clean up before exit +void icq_InfoUpdateCleanup(void) +{ + bRunning = FALSE; + SetEvent(hDummyEvent); // break timeout + SetEvent(hQueueEvent); // break queue loop + if (hInfoThread) WaitForSingleObjectEx(hInfoThread, INFINITE, TRUE); + // Uninit mutex + DeleteCriticalSection(&listmutex); + CloseHandle(hQueueEvent); + CloseHandle(hDummyEvent); + CloseHandle(hInfoThread); +} -- cgit v1.2.3