From 965f0ca12bc0c090f9d25a856c36645935832072 Mon Sep 17 00:00:00 2001 From: pescuma Date: Wed, 20 Feb 2008 04:23:23 +0000 Subject: Initial import of Emoticons plugin (version 0.0.1.0) git-svn-id: http://pescuma.googlecode.com/svn/trunk/Miranda@21 c086bb3d-8645-0410-b8da-73a8550f86e7 --- Plugins/utils/ContactAsyncQueue.cpp | 222 ++++++++++++++++++++++++++++++++++++ 1 file changed, 222 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 0000000..7be4cfe --- /dev/null +++ b/Plugins/utils/ContactAsyncQueue.cpp @@ -0,0 +1,222 @@ +/* +Copyright (C) 2006 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 *i1, const QueueItem *i2) +{ + return i1->check_time - i2->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() +{ + if (finished == 0) + finished = 1; + SetEvent(hEvent); + int count = 0; + while(finished != 2 && ++count < 50) + Sleep(10); + + for (int i = 0; i < queue.getCount(); i++) + if (queue[i] != NULL) + mir_free(queue[i]); + + DeleteCriticalSection(&cs); +} + +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); + + 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