From 725f68b6808a8a30778f58223fac75386f082785 Mon Sep 17 00:00:00 2001 From: Kirill Volinsky Date: Fri, 18 May 2012 22:10:43 +0000 Subject: plugins folders renaming git-svn-id: http://svn.miranda-ng.org/main/trunk@61 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- plugins/Utils/ContactAsyncQueue.cpp | 234 ++++++++++++++++++++++++++++++++++++ 1 file changed, 234 insertions(+) create mode 100644 plugins/Utils/ContactAsyncQueue.cpp (limited to 'plugins/Utils/ContactAsyncQueue.cpp') diff --git a/plugins/Utils/ContactAsyncQueue.cpp b/plugins/Utils/ContactAsyncQueue.cpp new file mode 100644 index 0000000000..2d5d1f104d --- /dev/null +++ b/plugins/Utils/ContactAsyncQueue.cpp @@ -0,0 +1,234 @@ +/* +Copyright (C) 2006-2009 Ricardo Pescuma Domenecci + +This is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public +License as published by the Free Software Foundation; either +version 2 of the License, or (at your option) any later version. + +This 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 +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with this file; see the file license.txt. If +not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. +*/ + +#include "ContactAsyncQueue.h" +#include + + +// Itens with higher time at end +static int QueueSortItems(const QueueItem *oldItem, const QueueItem *newItem) +{ + if (oldItem->check_time == newItem->check_time) + return -1; + + return oldItem->check_time - newItem->check_time; +} + +// Itens with higher time at end +static void ContactAsyncQueueThread(void *obj) +{ + ((ContactAsyncQueue *)obj)->Thread(); +} + +ContactAsyncQueue::ContactAsyncQueue(pfContactAsyncQueueCallback fContactAsyncQueueCallback, int initialSize) + : queue(30, QueueSortItems) +{ + hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + finished = 0; + callback = fContactAsyncQueueCallback; + + InitializeCriticalSection(&cs); + + _beginthread(ContactAsyncQueueThread, 0, this); + //mir_forkthread(ContactAsyncQueueThread, this); +} + +ContactAsyncQueue::~ContactAsyncQueue() +{ + Finish(); + + int count = 0; + while(finished != 2 && ++count < 50) + Sleep(30); + + for (int i = 0; i < queue.getCount(); i++) + if (queue[i] != NULL) + mir_free(queue[i]); + + DeleteCriticalSection(&cs); +} + +void ContactAsyncQueue::Finish() +{ + if (finished == 0) + finished = 1; + SetEvent(hEvent); +} + +void ContactAsyncQueue::Lock() +{ + EnterCriticalSection(&cs); +} + +void ContactAsyncQueue::Release() +{ + LeaveCriticalSection(&cs); +} + +void ContactAsyncQueue::RemoveAll(HANDLE hContact) +{ + Lock(); + + for (int i = queue.getCount() - 1; i >= 0; --i) + { + QueueItem *item = queue[i]; + + if (item->hContact == hContact) + { + queue.remove(i); + mir_free(item); + } + } + + Release(); +} + +void ContactAsyncQueue::RemoveAllConsiderParam(HANDLE hContact, void *param) +{ + Lock(); + + for (int i = queue.getCount() - 1; i >= 0; --i) + { + QueueItem *item = queue[i]; + + if (item->hContact == hContact && item->param == param) + { + queue.remove(i); + mir_free(item); + } + } + + Release(); +} + +void ContactAsyncQueue::Add(int waitTime, HANDLE hContact, void *param) +{ + Lock(); + + InternalAdd(waitTime, hContact, param); + + Release(); +} + +void ContactAsyncQueue::AddIfDontHave(int waitTime, HANDLE hContact, void *param) +{ + Lock(); + + int i; + for (i = queue.getCount() - 1; i >= 0; --i) + if (queue[i]->hContact == hContact) + break; + + if (i < 0) + InternalAdd(waitTime, hContact, param); + + Release(); +} + +void ContactAsyncQueue::AddAndRemovePrevious(int waitTime, HANDLE hContact, void *param) +{ + Lock(); + + RemoveAll(hContact); + InternalAdd(waitTime, hContact, param); + + Release(); +} + +void ContactAsyncQueue::AddAndRemovePreviousConsiderParam(int waitTime, HANDLE hContact, void *param) +{ + Lock(); + + RemoveAllConsiderParam(hContact, param); + InternalAdd(waitTime, hContact, param); + + Release(); +} + +void ContactAsyncQueue::InternalAdd(int waitTime, HANDLE hContact, void *param) +{ + QueueItem *item = (QueueItem *) mir_alloc(sizeof(QueueItem)); + item->hContact = hContact; + item->check_time = GetTickCount() + waitTime; + item->param = param; + + queue.insert(item); + + SetEvent(hEvent); +} + +void ContactAsyncQueue::Thread() +{ + while (!finished) + { + ResetEvent(hEvent); + + if (finished) + break; + + Lock(); + + if (queue.getCount() <= 0) + { + // No items, so supend thread + Release(); + + wait(/*INFINITE*/ 2 * 60 * 1000); + } + else + { + // Take a look at first item + QueueItem *qi = queue[0]; + + int dt = qi->check_time - GetTickCount(); + if (dt > 0) + { + // Not time to request yet, wait... + Release(); + + wait(dt); + } + else + { + // Will request this item + queue.remove(0); + + Release(); + + callback(qi->hContact, qi->param); + + mir_free(qi); + } + } + } + + finished = 2; +} + +void ContactAsyncQueue::wait(int time) +{ + if (!finished) + WaitForSingleObject(hEvent, time); +} + + + + + + -- cgit v1.2.3