From f04d64869f3b1de54fb343f28f955584780001b8 Mon Sep 17 00:00:00 2001 From: mataes2007 Date: Sat, 26 Nov 2011 15:41:10 +0000 Subject: Project folders rename part 3 git-svn-id: http://miranda-plugins.googlecode.com/svn/trunk@215 e753b5eb-9565-29b2-b5c5-2cc6f99dfbcb --- UserInfoEx/mir_contactqueue.cpp | 428 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 428 insertions(+) create mode 100644 UserInfoEx/mir_contactqueue.cpp (limited to 'UserInfoEx/mir_contactqueue.cpp') diff --git a/UserInfoEx/mir_contactqueue.cpp b/UserInfoEx/mir_contactqueue.cpp new file mode 100644 index 0000000..5807fc6 --- /dev/null +++ b/UserInfoEx/mir_contactqueue.cpp @@ -0,0 +1,428 @@ +/* +Copyright ฉ2006 Ricardo Pescuma Domenecci + +Modified ฉ2008-2010 DeathAxe, Yasnovidyashii, Merlin, K. Romanov, Kreol + +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 : $HeadURL: https://userinfoex.googlecode.com/svn/trunk/mir_contactqueue.cpp $ +Revision : $Revision: 187 $ +Last change on : $Date: 2010-09-08 16:05:54 +0400 (ะกั€, 08 ัะตะฝ 2010) $ +Last change by : $Author: ing.u.horn $ + +=============================================================================== +*/ + +#include "commonheaders.h" +#include "mir_contactqueue.h" +#include + +/** + * This static helper function is used to sort the queue items by time + * beginning with the next upcomming item to call the Callback for. + * + * @param i1 - the first queue item + * @param i2 - the second queue item + * + * @return The function returns the time slack between the two items. + **/ +static INT QueueSortItems(const CQueueItem *i1, const CQueueItem *i2) +{ + INT rc = i1->check_time - i2->check_time; + if (!rc) + { + rc = i1->hContact != i2->hContact; + } + return rc; +} + +/** + * + * + **/ +CContactQueue::CContactQueue(INT initialSize) + : _queue(initialSize, QueueSortItems) +{ + _hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + _status = RUNNING; + + InitializeCriticalSection(&_cs); + + mir_forkthread((pThreadFunc)CContactQueue::ThreadProc, this); +} + +/** + * + * + **/ +CContactQueue::~CContactQueue() +{ + if (_status == RUNNING) + { + _status = STOPPING; + } + SetEvent(_hEvent); + + for (INT count = 0; _status != STOPPED && ++count < 50;) + { + Sleep(10); + } + + for (INT i = 0; i < _queue.getCount(); i++) + { + mir_free(_queue[i]); + } + _queue.destroy(); + + CloseHandle(_hEvent); + DeleteCriticalSection(&_cs); +} + +/** + * + * + **/ +VOID CContactQueue::Lock() +{ + EnterCriticalSection(&_cs); +} + +/** + * + * + **/ +VOID CContactQueue::Release() +{ + LeaveCriticalSection(&_cs); +} + +/** + * This function removes all queue items. + * + * @param none + * + * @return nothing + **/ +VOID CContactQueue::RemoveAll() +{ + Lock(); + + for (INT i = _queue.getCount() - 1; i >= 0; --i) + { + mir_free(_queue[i]); + } + _queue.destroy(); + + Release(); +} + +/** + * This function removes all queue items for the hContact. + * + * @param hContact - the contact whose queue items to delete + * + * @return nothing + **/ +VOID CContactQueue::RemoveAll(HANDLE hContact) +{ + Lock(); + + for (INT i = _queue.getCount() - 1; i >= 0; --i) + { + CQueueItem *qi = _queue[i]; + + if (qi->hContact == hContact) + { + _queue.remove(i); + mir_free(qi); + } + } + + Release(); +} + +/** + * This function removes all queue items for the hContact considering the correct parameter. + * + * @param hContact - the contact whose queue items to delete + * @param param - a caller defined parameter passed to the callback function + * + * @return nothing + **/ +VOID CContactQueue::RemoveAllConsiderParam(HANDLE hContact, PVOID param) +{ + Lock(); + + for (INT i = _queue.getCount() - 1; i >= 0; --i) + { + CQueueItem *qi = _queue[i]; + + if (qi->hContact == hContact && qi->param == param) + { + _queue.remove(i); + mir_free(qi); + } + } + + Release(); +} + +/** + * This method adds the desired new item. + * + * @param waitTime - the time to wait until the callback is desired to run + * @param hContact - the contact to perform the action for + * @param param - a caller defined parameter passed to the callback function + * + * @retval TRUE - The item is added to the queue successfully. + * @retval FALSE - The item is not added to the queue. + **/ +BOOL CContactQueue::Add(INT waitTime, HANDLE hContact, PVOID param) +{ + BOOL rc; + + Lock(); + + rc = InternalAdd(waitTime, hContact, param); + + Release(); + + return rc; +} + +/** + * This method adds the desired new item only, if the queue does not yet contain + * an item for the contact. + * + * @param waitTime - the time to wait until the callback is desired to run + * @param hContact - the contact to perform the action for + * @param param - a caller defined parameter passed to the callback function + * + * @retval TRUE - The item is added to the queue successfully. + * @retval FALSE - The item is not added to the queue. + **/ +BOOL CContactQueue::AddIfDontHave(INT waitTime, HANDLE hContact, PVOID param) +{ + INT i; + BOOL rc; + + Lock(); + + for (i = _queue.getCount() - 1; i >= 0; --i) + { + if (_queue[i]->hContact == hContact) + { + break; + } + } + + rc = (i == -1) ? InternalAdd(waitTime, hContact, param) : 0; + + Release(); + + return rc; +} + +/** + * This method removes all existing queue items for the contact and adds a new queue item + * for the given contact. This method might be used to move an existing entry, + * whose check_time has changed. + * + * @param waitTime - the time to wait until the callback is desired to run + * @param hContact - the contact to perform the action for + * @param param - a caller defined parameter passed to the callback function + * + * @retval TRUE - The item is added to the queue successfully. + * @retval FALSE - The item is not added to the queue. + **/ +BOOL CContactQueue::AddUnique(INT waitTime, HANDLE hContact, PVOID param) +{ + BOOL rc; + + Lock(); + + RemoveAll(hContact); + rc = InternalAdd(waitTime, hContact, param); + + Release(); + + return rc; +} + +/** + * This method removes all existing queue items for the contact with the same parameter as @e param + * and adds a new queue item for the given contact. This method might be used to move an existing + * entry, whose check_time has changed. + * + * @param waitTime - the time to wait until the callback is desired to run + * @param hContact - the contact to perform the action for + * @param param - a caller defined parameter passed to the callback function + * + * @retval TRUE - The item is added to the queue successfully. + * @retval FALSE - The item is not added to the queue. + **/ +BOOL CContactQueue::AddUniqueConsiderParam(INT waitTime, HANDLE hContact, PVOID param) +{ + BOOL rc; + + Lock(); + + RemoveAllConsiderParam(hContact, param); + rc = InternalAdd(waitTime, hContact, param); + + Release(); + + return rc; +} + +/** + * This member function really adds an item into the time sorted queue list. + * + * @param waitTime - the time to wait until the callback is desired to run + * @param hContact - the contact to perform the action for + * @param param - a caller defined parameter passed to the callback function + * + * @retval TRUE - The item is added to the queue successfully. + * @retval FALSE - The item is not added to the queue. + **/ +BOOL CContactQueue::InternalAdd(INT waitTime, HANDLE hContact, PVOID param) +{ + BOOL rc; + CQueueItem *qi = (CQueueItem *) mir_alloc(sizeof(CQueueItem)); + + qi->hContact = hContact; + qi->check_time = GetTickCount() + waitTime; + qi->param = param; + + rc = _queue.insert(qi); + if (!rc) + { + mir_free(qi); + } + + SetEvent(_hEvent); + + return rc; +} + +/** + * This is the real thread callback function. As long as _status + * is set to RUNNING it looks for items in the queue to perform + * the _pfnCallback function on them. If the queue is empty or the + * next upcoming item is located in the future, the thread is suspended + * in the meanwhile. + * + * @param none + * + * @return nothing + **/ +VOID CContactQueue::Thread() +{ + while (_status == RUNNING) + { + ResetEvent(_hEvent); + + Lock(); + + if (_queue.getCount() <= 0) + { + // can be used by a derivant + OnEmpty(); + + // No items, so supend thread + Release(); + + Suspend(INFINITE); + } + else + { + // Take a look at first queue item + CQueueItem *qi = _queue[0]; + + INT dt = qi->check_time - GetTickCount(); + if (dt > 0) + { + // Not time to request yet, wait... + Release(); + + Suspend(dt); + } + else + { + // Will request this queue item + _queue.remove(0); + + Release(); + + Callback(qi->hContact, qi->param); + + mir_free(qi); + } + } + } + _status = STOPPED; +} + +/** + * This method suspends the worker thread for the given ammount of time. + * + * @param time - milliseconds to suspend the thread for + * + * @return nothing + **/ +VOID CContactQueue::Suspend(INT time) const +{ + if (_status == RUNNING) + { + WaitForSingleObject(_hEvent, time); + } +} + +/** + * This method resumes the worker thread and immitiatly goes on with the next entry. + * + * @param none + * + * @return nothing + **/ +VOID CContactQueue::ContinueWithNext() +{ + if (_status == RUNNING) + { + INT i, c, dt; + + Lock(); + + c = _queue.getCount(); + if (c > 0) + { + dt = _queue[0]->check_time - GetTickCount() - 3000; + if (dt > 0) + { + for (i = 0; i < c; i++) + { + _queue[i]->check_time -= dt; + } + } + } + SetEvent(_hEvent); + Release(); + } +} + + + -- cgit v1.2.3