Beispiel #1
0
int DeleteAccounts(HYAMNPROTOPLUGIN Plugin)
{
	HACCOUNT Finder;

	//1. wait to get write access
	#ifdef DEBUG_SYNCHRO
	DebugLog(SynchroFile,"DeleteAccounts:AccountBrowserSO-write wait\n");
	#endif
	SWMRGWaitToWrite(Plugin->AccountBrowserSO,INFINITE);
	#ifdef DEBUG_SYNCHRO
	DebugLog(SynchroFile,"DeleteAccounts:AccountBrowserSO-write enter\n");
	#endif

	WaitForAllAccounts(Plugin,FALSE);

	for (Finder=Plugin->FirstAccount;Finder != NULL;)
	{
		HACCOUNT Next = Finder->Next;
		DeletePluginAccountSvc((WPARAM)Finder,0);
		Finder = Next;
	}

	//leave write access
	#ifdef DEBUG_SYNCHRO
	DebugLog(SynchroFile,"DeleteAccounts:AccountBrowserSO-write done\n");
	#endif
	SWMRGDoneWriting(Plugin->AccountBrowserSO);

	return 1;
}
Beispiel #2
0
int StopAccounts(HYAMNPROTOPLUGIN Plugin)
{
	HACCOUNT Finder;

//1. wait to get write access
#ifdef DEBUG_SYNCHRO
	DebugLog(SynchroFile,"StopAccounts:AccountBrowserSO-write wait\n");
#endif
	SWMRGWaitToWrite(Plugin->AccountBrowserSO,INFINITE);
#ifdef DEBUG_SYNCHRO
	DebugLog(SynchroFile,"StopAccounts:AccountBrowserSO-write enter\n");
#endif
	for (Finder=Plugin->FirstAccount;Finder != NULL;Finder=Finder->Next)
	{
//2. set stop signal 
		StopSignalFcn(Finder);
		WindowList_BroadcastAsync(YAMNVar.MessageWnds,WM_YAMN_STOPACCOUNT,(WPARAM)Finder,0);
		if (Plugin->Fcn->StopAccountFcnPtr != NULL)
			Plugin->Fcn->StopAccountFcnPtr(Finder);
	}

//leave write access
#ifdef DEBUG_SYNCHRO
	DebugLog(SynchroFile,"StopAccounts:AccountBrowserSO-write done\n");
#endif
	SWMRGDoneWriting(Plugin->AccountBrowserSO);

//Now, account is stopped. It can be removed from memory...
	return 1;
}
Beispiel #3
0
void WINAPI WriteDoneFcn(PSWMRG SObject,PSCOUNTER SCounter)
{
#ifdef DEBUG_SYNCHRO
	DebugLog(SynchroFile,"\tSO WriteDone: %x\n",SObject);
#endif
	SWMRGDoneWriting(SObject);
	if(SCounter!=NULL)
		SCDecFcn(SCounter);
}
Beispiel #4
0
int WaitForAllAccounts(HYAMNPROTOPLUGIN Plugin,BOOL GetAccountBrowserAccess)
{
	HACCOUNT Finder;

	if (GetAccountBrowserAccess)
	{
//1. wait to get write access
#ifdef DEBUG_SYNCHRO
		DebugLog(SynchroFile,"WaitForAllAccounts:AccountBrowserSO-write wait\n");
#endif
		SWMRGWaitToWrite(Plugin->AccountBrowserSO,INFINITE);
#ifdef DEBUG_SYNCHRO
		DebugLog(SynchroFile,"WaitForAllAccounts:AccountBrowserSO-write enter\n");
#endif
	}
	for (Finder=Plugin->FirstAccount;Finder != NULL;Finder=Finder->Next)
	{
//2. wait for signal that account is not in use
#ifdef DEBUG_SYNCHRO
		DebugLog(SynchroFile,"WaitForAllAccounts:waiting for UsingThreadEV %x (account %x)\n",Finder->UsingThreads,Finder);
#endif
		WaitForSingleObject(Finder->UsingThreads->Event,INFINITE);
		SetEvent(Finder->UsingThreads->Event);
#ifdef DEBUG_SYNCHRO
		DebugLog(SynchroFile,"WaitForAllAccounts:UsingThreadEV signaled\n");
#endif
	}
	if (GetAccountBrowserAccess)
	{
//leave write access
#ifdef DEBUG_SYNCHRO
		DebugLog(SynchroFile,"WaitForAllAccounts:AccountBrowserSO-write done\n");
#endif
		SWMRGDoneWriting(Plugin->AccountBrowserSO);
	}

	return 1;
}
Beispiel #5
0
static INT_PTR PerformAccountReading(HYAMNPROTOPLUGIN Plugin,char *MemFile,char *End)
{
	//Retrieve info for account from memory
	char *Parser;
	DWORD Ver,Stat;

	HACCOUNT ActualAccount,FirstAllocatedAccount;

	Ver=*(DWORD *)MemFile;
	if (Ver>YAMN_ACCOUNTFILEVERSION)
	{
		delete[] MemFile;
		return EACC_FILEVERSION;
	}
	Parser=MemFile+sizeof(Ver);

#ifdef DEBUG_SYNCHRO
	DebugLog(SynchroFile,"AddAccountsFromFile:AccountBrowserSO-write wait\n");
#endif
	SWMRGWaitToWrite(Plugin->AccountBrowserSO,INFINITE);
#ifdef DEBUG_SYNCHRO
	DebugLog(SynchroFile,"AddAccountsFromFile:AccountBrowserSO-write enter\n");
#endif
	if (NULL==(ActualAccount=(HACCOUNT)CallService(MS_YAMN_GETNEXTFREEACCOUNT,(WPARAM)Plugin,(LPARAM)YAMN_ACCOUNTVERSION)))
	{
#ifdef DEBUG_SYNCHRO
		DebugLog(SynchroFile,"AddAccountsFromFile:AccountBrowserSO-write done\n");
#endif
		SWMRGDoneWriting(Plugin->AccountBrowserSO);
		delete[] MemFile;
		return EACC_ALLOC;
	}
	FirstAllocatedAccount=ActualAccount;

	do
	{
		HACCOUNT Temp;

#ifdef DEBUG_SYNCHRO
		DebugLog(SynchroFile,"AddAccountsFromFile:ActualAccountSO-write wait\n");
#endif
		WaitToWriteFcn(ActualAccount->AccountAccessSO);
#ifdef DEBUG_SYNCHRO
		DebugLog(SynchroFile,"AddAccountsFromFile:ActualAccountSO-write enter\n");
#endif
		Stat=ReadAccountFromMemory(ActualAccount,&Parser,End);

		if (ActualAccount->StatusFlags & (YAMN_ACC_STARTA | YAMN_ACC_STARTS))
			ActualAccount->TimeLeft=1;		//check on loading

		if (Stat && (Stat != EACC_ENDOFFILE))
		{
			for (ActualAccount=FirstAllocatedAccount;ActualAccount != NULL;ActualAccount=Temp)
			{
				Temp=ActualAccount->Next;
				delete ActualAccount;
			}
			delete[] MemFile;
			if (Plugin->FirstAccount==FirstAllocatedAccount)
				Plugin->FirstAccount=NULL;
#ifdef DEBUG_SYNCHRO
			DebugLog(SynchroFile,"AddAccountsFromFile:ActualAccountSO-write done\n");
#endif
			SWMRGDoneWriting(Plugin->AccountBrowserSO);
			return (INT_PTR)Stat;
		}

#ifdef DEBUG_SYNCHRO
		DebugLog(SynchroFile,"AddAccountsFromFile:ActualAccountSO-write done\n");
#endif
		WriteDoneFcn(ActualAccount->AccountAccessSO);

		if ((Stat != EACC_ENDOFFILE) && (NULL==(ActualAccount=(HACCOUNT)CallService(MS_YAMN_GETNEXTFREEACCOUNT,(WPARAM)Plugin,(LPARAM)YAMN_ACCOUNTVERSION))))
		{
			for (ActualAccount=FirstAllocatedAccount;ActualAccount != NULL;ActualAccount=Temp)
			{
				Temp=ActualAccount->Next;
				delete ActualAccount;
			}
			delete[] MemFile;
			if (Plugin->FirstAccount==FirstAllocatedAccount)
				Plugin->FirstAccount=NULL;
#ifdef DEBUG_SYNCHRO
			DebugLog(SynchroFile,"AddAccountsFromFile:AccountBrowserSO-write done\n");
#endif
			SWMRGDoneWriting(Plugin->AccountBrowserSO);
			return EACC_ALLOC;
		}
	}while(Stat != EACC_ENDOFFILE);

#ifdef DEBUG_SYNCHRO
	DebugLog(SynchroFile,"AddAccountsFromFile:AccountBrowserSO-write done\n");
#endif
	SWMRGDoneWriting(Plugin->AccountBrowserSO);
	delete[] MemFile;

	return 0;
}
Beispiel #6
0
/*
int FindPluginAccount(WPARAM wParam,LPARAM lParam)
{
	HYAMNPROTOPLUGIN Plugin=(HYAMNPROTOPLUGIN)wParam;
	HACCOUNT Finder=(HACCOUNT)lParam;

	if (Finder=NULL)	Finder=Plugin->FirstAccount;

//	for (;Finder != NULL && Finder->PluginID != Plugin->PluginInfo->PluginID;Finder=(HACCOUNT)Finder->Next);
	return (int)Finder;
}
*/
INT_PTR DeleteAccountSvc(WPARAM wParam,LPARAM lParam)
{
//Deleting account works on these steps:
//1. set signal that account should stop activity (set event)
//	setting this event we achieve, that any access to account is failed,
//	so threads do not start any work with accounts (better saying threads of plugins should not start)
//2. wait to get write access to chained list of accounts
//3. we can write to chained list, so we change chain not to show to actual account
//	now, any thread browsing list of accounts does not browse through actual account
//	actual account seems to be hidden (it exists, but it is not in accounts chained list (chained list=queue))
//Now, we should delete account from memory, BUT!!!
//	Any thread can still be waked up and start asking account synchronizing object
//	If account is deleted, asking about access to read account can throw memory exception (reading for
//	a synchronizing object from memory, that was deleted)
//So, we cannot now delete account. We have to wait until we are sure no thread will be using account anymore
//	(or to the end of Miranda, but problem is in allocated memory- it is allocated and Miranda is SMALLER, faster, easier, isn't it?)
//	This deleting is achieved in 2 ways:
//	We have event in UsingThreads synchronization objects. This event signals that no thread will use actual account
//	1. Any thread using account first increment UsingThread, so we know that account is used
//	2. If thread is about to close, it should decrement UsingThread
//	3. If thread creates another thread, that will use account, caller has to wait until the new thread does not
//		increment UsingThreads (imagine that caller ends before the new thread set it: if no other thread is using
//		account, account is automaticaly (decreasing UsingThreads) signaled as "not used" and we delete it. But then
//		new thread is going to read account...).
//4. wait until UsingThread Event is signaled
//5. delete account from memory

	HYAMNPROTOPLUGIN Plugin=(HYAMNPROTOPLUGIN)wParam;
	HACCOUNT Which=(HACCOUNT)lParam;
	HACCOUNT Finder;
	DWORD tid;

//1. set stop signal 
	StopSignalFcn(Which);
	WindowList_BroadcastAsync(YAMNVar.MessageWnds,WM_YAMN_STOPACCOUNT,(WPARAM)Which,0);
	if (Plugin->Fcn->StopAccountFcnPtr != NULL)
		Plugin->Fcn->StopAccountFcnPtr(Which);

//2. wait to get write access
#ifdef DEBUG_SYNCHRO
	DebugLog(SynchroFile,"DeleteAccount:AccountBrowserSO-write wait\n");
#endif
	SWMRGWaitToWrite(Plugin->AccountBrowserSO,INFINITE);
#ifdef DEBUG_SYNCHRO
	DebugLog(SynchroFile,"DeleteAccount:AccountBrowserSO-write enter\n");
#endif

//3. remove from queue (chained list)
	if (Plugin->FirstAccount==NULL)
	{
#ifdef DEBUG_SYNCHRO
		DebugLog(SynchroFile,"DeleteAccount:AccountBrowserSO-write done\n");
#endif
		SWMRGDoneWriting(Plugin->AccountBrowserSO);
		return 0;
	}
	if (Plugin->FirstAccount==Which)
	{
		Finder=Plugin->FirstAccount->Next;
		Plugin->FirstAccount=Finder;
	}
	else
	{
		for (Finder=Plugin->FirstAccount;Which != Finder->Next;Finder=Finder->Next);
		Finder->Next=Finder->Next->Next;
	}
//leave write access
#ifdef DEBUG_SYNCHRO
	DebugLog(SynchroFile,"DeleteAccount:AccountBrowserSO-write done\n");
#endif
	SWMRGDoneWriting(Plugin->AccountBrowserSO);

//4. wait while event "UsingThread" is not signaled
//	And what to do, if this event will be signaled in 1 hour? (Although it's paranoia, because we have sent "delete signal", so
//	other threads do not start any new work with actual account) We will wait in blocked state?
//	No, of course not. We will create new thread, that will wait and additionally remove our thread in background.
//5. So, the last point (deleting from memory) is performed in new DeleteAccountInBackground thread

	if ((Plugin->Fcn != NULL) && (Plugin->Fcn->WriteAccountsFcnPtr != NULL))
			Plugin->Fcn->WriteAccountsFcnPtr();
	CloseHandle(CreateThread(NULL,0,DeleteAccountInBackground,(LPVOID)Which,0,&tid));

//Now, plugin can consider account as deleted, but plugin really can achieve deleting this account from memory when using
//event UsingThreads.
	return 1;
}