diff options
author | George Hazan <george.hazan@gmail.com> | 2015-02-09 16:46:03 +0000 |
---|---|---|
committer | George Hazan <george.hazan@gmail.com> | 2015-02-09 16:46:03 +0000 |
commit | 9e6567e9498724b3781768a8c60383ad055dd02f (patch) | |
tree | 3e987afb5eb70a24acb903188c078b5710ed1259 /protocols/MRA | |
parent | ff22a9442b5464ef0de4273bbdeb74ea1957bf17 (diff) |
simplified thread management schema for loading MRA avatars
git-svn-id: http://svn.miranda-ng.org/main/trunk@12068 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
Diffstat (limited to 'protocols/MRA')
-rw-r--r-- | protocols/MRA/src/Mra.cpp | 10 | ||||
-rw-r--r-- | protocols/MRA/src/Mra.h | 2 | ||||
-rw-r--r-- | protocols/MRA/src/MraAvatars.cpp | 54 | ||||
-rw-r--r-- | protocols/MRA/src/version.h | 2 |
4 files changed, 33 insertions, 35 deletions
diff --git a/protocols/MRA/src/Mra.cpp b/protocols/MRA/src/Mra.cpp index 9f609f4056..e6c6cd3843 100644 --- a/protocols/MRA/src/Mra.cpp +++ b/protocols/MRA/src/Mra.cpp @@ -23,7 +23,7 @@ HINSTANCE g_hInstance; HMODULE g_hDLLXStatusIcons;
HICON g_hMainIcon;
-bool g_bChatExist;
+bool g_bChatExist, g_bShutdown = false;
size_t g_dwMirWorkDirPathLen;
WCHAR g_szMirWorkDirPath[MAX_FILEPATH];
@@ -70,6 +70,12 @@ static int mraProtoUninit(CMraProto *ppro) ///////////////////////////////////////////////////////////////////////////////
+static int __cdecl OnPreShutdown(WPARAM, LPARAM)
+{
+ g_bShutdown = true;
+ return 0;
+}
+
extern "C" __declspec(dllexport) int Load(void)
{
mir_getLP(&pluginInfoEx);
@@ -78,6 +84,8 @@ extern "C" __declspec(dllexport) int Load(void) IconsLoad();
InitXStatusIcons();
+ HookEvent(ME_SYSTEM_PRESHUTDOWN, OnPreShutdown);
+
PROTOCOLDESCRIPTOR pd = { sizeof(pd) };
pd.szName = "MRA";
pd.type = PROTOTYPE_PROTOCOL;
diff --git a/protocols/MRA/src/Mra.h b/protocols/MRA/src/Mra.h index b34a378b36..cea31c80f1 100644 --- a/protocols/MRA/src/Mra.h +++ b/protocols/MRA/src/Mra.h @@ -177,7 +177,7 @@ extern HINSTANCE g_hInstance; extern HMODULE g_hDLLXStatusIcons;
extern HICON g_hMainIcon;
-extern bool g_bChatExist;
+extern bool g_bChatExist, g_bShutdown;
extern size_t g_dwMirWorkDirPathLen;
extern WCHAR g_szMirWorkDirPath[MAX_FILEPATH];
diff --git a/protocols/MRA/src/MraAvatars.cpp b/protocols/MRA/src/MraAvatars.cpp index 4a18383b8d..dbf355a8e7 100644 --- a/protocols/MRA/src/MraAvatars.cpp +++ b/protocols/MRA/src/MraAvatars.cpp @@ -18,12 +18,9 @@ const LPSTR lpcszContentType[9] = struct MRA_AVATARS_QUEUE : public FIFO_MT
{
- volatile LONG bIsRunning;
- volatile LONG lThreadsRunningCount;
HANDLE hNetlibUser;
- HANDLE hThreadEvent;
- int iThreadsCount;
- HANDLE hThread[MAXIMUM_WAIT_OBJECTS];
+ HANDLE hThreadEvents[MAXIMUM_WAIT_OBJECTS];
+ int iThreadsCount, iThreadsRunning;
};
struct MRA_AVATARS_QUEUE_ITEM : public FIFO_MT_ITEM
@@ -67,19 +64,18 @@ DWORD CMraProto::MraAvatarsQueueInitialize(HANDLE *phAvatarsQueueHandle) nlu.szDescriptiveName = szBuffer;
pmraaqAvatarsQueue->hNetlibUser = (HANDLE)CallService(MS_NETLIB_REGISTERUSER, 0, (LPARAM)&nlu);
if (pmraaqAvatarsQueue->hNetlibUser) {
- InterlockedExchange((volatile LONG*)&pmraaqAvatarsQueue->bIsRunning, TRUE);
- pmraaqAvatarsQueue->hThreadEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
pmraaqAvatarsQueue->iThreadsCount = db_get_dw(NULL, MRA_AVT_SECT_NAME, "WorkThreadsCount", MRA_AVT_DEFAULT_WRK_THREAD_COUNTS);
if (pmraaqAvatarsQueue->iThreadsCount == 0)
pmraaqAvatarsQueue->iThreadsCount = 1;
if (pmraaqAvatarsQueue->iThreadsCount > MAXIMUM_WAIT_OBJECTS)
pmraaqAvatarsQueue->iThreadsCount = MAXIMUM_WAIT_OBJECTS;
+
+ pmraaqAvatarsQueue->iThreadsRunning = 0;
for (int i = 0; i < pmraaqAvatarsQueue->iThreadsCount; i++)
- pmraaqAvatarsQueue->hThread[i] = ForkThreadEx(&CMraProto::MraAvatarsThreadProc, pmraaqAvatarsQueue, 0);
+ ForkThread(&CMraProto::MraAvatarsThreadProc, pmraaqAvatarsQueue);
*phAvatarsQueueHandle = (HANDLE)pmraaqAvatarsQueue;
}
-
return NO_ERROR;
}
@@ -105,9 +101,9 @@ void CMraProto::MraAvatarsQueueClear(HANDLE hAvatarsQueueHandle) void CMraProto::MraAvatarsQueueSuspend(HANDLE hAvatarsQueueHandle)
{
MRA_AVATARS_QUEUE *pmraaqAvatarsQueue = (MRA_AVATARS_QUEUE*)hAvatarsQueueHandle;
- InterlockedExchange((volatile LONG*)&pmraaqAvatarsQueue->bIsRunning, FALSE);
MraAvatarsQueueClear(hAvatarsQueueHandle);
- SetEvent(pmraaqAvatarsQueue->hThreadEvent);
+ for (int i = 0; i < pmraaqAvatarsQueue->iThreadsCount; i++)
+ SetEvent(pmraaqAvatarsQueue->hThreadEvents[i]);
}
void CMraProto::MraAvatarsQueueDestroy(HANDLE hAvatarsQueueHandle)
@@ -116,26 +112,14 @@ void CMraProto::MraAvatarsQueueDestroy(HANDLE hAvatarsQueueHandle) return;
MRA_AVATARS_QUEUE *pmraaqAvatarsQueue = (MRA_AVATARS_QUEUE*)hAvatarsQueueHandle;
- while (InterlockedExchangeAdd((volatile LONG*)&pmraaqAvatarsQueue->lThreadsRunningCount, 0)) {
- SetEvent(pmraaqAvatarsQueue->hThreadEvent);
- SleepEx(50, TRUE);
- }
-
- for (int i = 0; i < pmraaqAvatarsQueue->iThreadsCount; i++)
- CloseHandle(pmraaqAvatarsQueue->hThread[i]);
- CloseHandle(pmraaqAvatarsQueue->hThreadEvent);
-
Netlib_CloseHandle(pmraaqAvatarsQueue->hNetlibUser);
delete pmraaqAvatarsQueue;
}
DWORD CMraProto::MraAvatarsQueueAdd(HANDLE hAvatarsQueueHandle, DWORD dwFlags, MCONTACT hContact, DWORD *pdwAvatarsQueueID)
{
- if (!hAvatarsQueueHandle)
- return ERROR_INVALID_HANDLE;
-
MRA_AVATARS_QUEUE *pmraaqAvatarsQueue = (MRA_AVATARS_QUEUE*)hAvatarsQueueHandle;
- if (!InterlockedExchangeAdd((volatile LONG*)&pmraaqAvatarsQueue->bIsRunning, 0))
+ if (pmraaqAvatarsQueue == NULL || g_bShutdown)
return ERROR_INVALID_HANDLE;
MRA_AVATARS_QUEUE_ITEM *pmraaqiAvatarsQueueItem = (MRA_AVATARS_QUEUE_ITEM*)mir_calloc(sizeof(MRA_AVATARS_QUEUE_ITEM));
@@ -149,7 +133,10 @@ DWORD CMraProto::MraAvatarsQueueAdd(HANDLE hAvatarsQueueHandle, DWORD dwFlags, M FifoMTItemPush(pmraaqAvatarsQueue, pmraaqiAvatarsQueueItem, (LPVOID)pmraaqiAvatarsQueueItem);
if (pdwAvatarsQueueID)
*pdwAvatarsQueueID = pmraaqiAvatarsQueueItem->dwAvatarsQueueID;
- SetEvent(pmraaqAvatarsQueue->hThreadEvent);
+
+ mir_cslock(pmraaqAvatarsQueue->cs);
+ int threadno = (pmraaqAvatarsQueue->iThreadsRunning + 1) % pmraaqAvatarsQueue->iThreadsCount;
+ SetEvent(pmraaqAvatarsQueue->hThreadEvents[threadno]);
return NO_ERROR;
}
@@ -175,15 +162,20 @@ void CMraProto::MraAvatarsThreadProc(LPVOID lpParameter) nls.cbSize = sizeof(nls);
pai.cbSize = sizeof(pai);
- InterlockedIncrement((volatile LONG*)&pmraaqAvatarsQueue->lThreadsRunningCount);
+ HANDLE hThreadEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
+ {
+ mir_cslock lck(pmraaqAvatarsQueue->cs);
+ pmraaqAvatarsQueue->hThreadEvents[pmraaqAvatarsQueue->iThreadsRunning++] = hThreadEvent;
+ }
- while (InterlockedExchangeAdd((volatile LONG*)&pmraaqAvatarsQueue->bIsRunning, 0)) {
+ while (!g_bShutdown) {
if (FifoMTItemPop(pmraaqAvatarsQueue, NULL, (LPVOID*)&pmraaqiAvatarsQueueItem) != NO_ERROR) { // waiting until service stop or new task
NETLIB_CLOSEHANDLE(hConnection);
- WaitForSingleObjectEx(pmraaqAvatarsQueue->hThreadEvent, MRA_AVT_DEFAULT_QE_CHK_INTERVAL, FALSE);
+ WaitForSingleObjectEx(hThreadEvent, MRA_AVT_DEFAULT_QE_CHK_INTERVAL, FALSE);
continue;
}
- /* Try download. */
+
+ // Try download.
bFailed = TRUE;
bDownloadNew = FALSE;
@@ -338,8 +330,7 @@ void CMraProto::MraAvatarsThreadProc(LPVOID lpParameter) }
mir_free(pmraaqiAvatarsQueueItem);
}
-
- InterlockedDecrement((volatile LONG*)&pmraaqAvatarsQueue->lThreadsRunningCount);
+ CloseHandle(hThreadEvent);
}
HANDLE MraAvatarsHttpConnect(HANDLE hNetlibUser, LPCSTR lpszHost, DWORD dwPort)
@@ -456,7 +447,6 @@ bool CMraProto::MraAvatarsGetContactTime(MCONTACT hContact, LPSTR lpszValueName, return false;
}
-
void CMraProto::MraAvatarsSetContactTime(MCONTACT hContact, LPSTR lpszValueName, SYSTEMTIME *pstTime)
{
if (!lpszValueName)
diff --git a/protocols/MRA/src/version.h b/protocols/MRA/src/version.h index fc8129e421..1c9ac7bc70 100644 --- a/protocols/MRA/src/version.h +++ b/protocols/MRA/src/version.h @@ -1,7 +1,7 @@ #define __MAJOR_VERSION 2
#define __MINOR_VERSION 1
#define __RELEASE_NUM 0
-#define __BUILD_NUM 9
+#define __BUILD_NUM 10
#include <stdver.h>
|