diff options
Diffstat (limited to 'protocols/MRA/src')
| -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>
  | 
