⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gwcmdinfohash.cpp

📁 PGP8.0源码 请认真阅读您的文件包然后写出其具体功能
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//  
//  Out: MSGINFO pointer that was inserted earlier
//  
//  Comments:caller MUST NOT free the PMSGINFO returned from this 
//			function. The PMSGINFO gotten is the original PMAGINFO
//			that was inserted so freeing this will corrupt the hash
//			table. caller MUST take due care while accessing members
//			of the struct as multiple threads could be accessing it
//			at any given time.
///////////////////////////////////////////////////////////////////
PMSGINFO CCmdInfoHash::Get(ULONG ulKey)
{
	ULONG ulIndex=0;
	BOOL bRet=FALSE;
	PMSGINFO pMsgInfo=NULL;
	PLIST_ENTRY pListEntry=NULL;

	//if not inited
	if(FALSE == m_bInited)
	{
		bRet=Init();//initialize ourselves
		if(FALSE == bRet)
			return FALSE;
	}

	ulIndex=ulKey%MSGINFO_HASHTABLE_SIZE;
	pgpAssert(ulIndex < MSGINFO_HASHTABLE_SIZE);

	pgpAssert(NULL != m_hMutex);
	WaitForSingleObject(m_hMutex, INFINITE);

	for (pListEntry = m_leArray[ulIndex].Flink; 
		 pListEntry != &m_leArray[ulIndex];
		 pListEntry = pListEntry->Flink)
	{
		pMsgInfo = (PMSGINFO)pListEntry;
		pgpAssert(NULL != pMsgInfo);
		pgpAssert(!IsBadReadPtr(pMsgInfo, sizeof(MSGINFO)));
		if(ulKey == pMsgInfo->ulKey)
		{
			bRet=TRUE;
			break;
		}
	}

	pgpAssert(NULL != m_hMutex);
	ReleaseMutex(m_hMutex);

	return (bRet?pMsgInfo:NULL);
}

//////////////////////////////////////////////////////////////////
//	Name:CCmdInfoHash::~CCmdInfoHash				
//
//  Description:CCmdInfoHash destructor. If we have any blobs in the
//				the hash table we free up the blobs. We also free the
//				mutex object.
//  
//  In:	none
//  
//  Out: none
//  
//  Comments:		
///////////////////////////////////////////////////////////////////
CCmdInfoHash::~CCmdInfoHash()
{
	//first make sure the deletion thread is done with its stuff
	if(NULL != m_hDelThread)
	{
		//set the quit event for the tmp files deletion thread
		pgpAssert(NULL != m_hQuitDelThread);
		SetEvent(m_hQuitDelThread);

		//wait till the thread is done
		WaitForSingleObject(m_hDelThread, INFINITE);

		//clean up the thread related stuff
		CloseHandle(m_hDelThread);
		m_hDelThread=NULL;

		CloseHandle(m_hQuitDelThread);
		m_hQuitDelThread=NULL;

		//the file deletion list should be empty since our thread is done
		pgpAssert(TRUE == IsListEmpty(&m_leFilesToDelete));
	}

	if(m_bInited && (0 < m_ulCount))//if inited and non-empty linked list
	{
		//free all the elements in the linked lists
		pgpAssert(NULL != m_hMutex);
		WaitForSingleObject(m_hMutex, INFINITE);

		PLIST_ENTRY pListEntry=NULL;
		for (int iIndex=0;iIndex < MSGINFO_HASHTABLE_SIZE; iIndex++)
		{
			for (pListEntry = m_leArray[iIndex].Flink; 
				 pListEntry != &m_leArray[iIndex];
				 pListEntry=pListEntry->Flink)
			{
				//remove from the linked list
				pgpAssert(NULL != pListEntry);
				RemoveEntryList(pListEntry);

				//free the entry itself
				FreeMsgInfo((PMSGINFO)pListEntry);

				pListEntry=m_leArray[iIndex].Flink;
			}
		}

		pgpAssert(NULL != m_hMutex);
		ReleaseMutex(m_hMutex);
	}


	if(NULL != m_hMutex)
	{
		BOOL bRet=CloseHandle(m_hMutex);
		pgpAssert(TRUE == bRet);
		m_hMutex=NULL;
	}
}

//////////////////////////////////////////////////////////////////
//	Name:CCmdInfoHash::ToggleState				
//
//  Description:Changes the dwState member of the MSGINFO structure
//		corresponding to the key that is passed as input parameter.
//  
//  In:	the key to the element and the state to be toggled
//  
//  Out: none
//  
//  Comments:		
///////////////////////////////////////////////////////////////////
BOOL CCmdInfoHash::ToggleState(ULONG ulKey, DWORD dwState)
{
	PMSGINFO lpMsgInfo=Get(ulKey);
	pgpAssert(NULL != lpMsgInfo);
	if(NULL == lpMsgInfo)
		return FALSE;

	pgpAssert(NULL != m_hMutex);
	if(NULL == m_hMutex)
		return FALSE;

	_VERIFY(WAIT_OBJECT_0 == WaitForSingleObject(m_hMutex, INFINITE));

	lpMsgInfo->dwState ^= dwState;

	ReleaseMutex(m_hMutex);
	return TRUE;
}

//////////////////////////////////////////////////////////////////
//	Name:CCmdInfoHash::FreeMsgInfo				
//
//  Description:Routine used internally to free the MSGINFO blob.
//				If you add new members to MSGINFO structure add the
//				cleanup code in this function.
//  
//  In:	PMSGINFO - the pointer to the msginfo block to be cleaned up
//  
//  Out: none
//  
//  Comments:		
///////////////////////////////////////////////////////////////////
void CCmdInfoHash::FreeMsgInfo(PMSGINFO lpMsgInfo)
{
	PLIST_ENTRY pListEntry=NULL;

	if(NULL == lpMsgInfo)
	{
		pgpAssert(FALSE);
		return;
	}

	if(NULL != lpMsgInfo->bstrId)
	{
		SysFreeString(lpMsgInfo->bstrId);
		lpMsgInfo->bstrId=NULL;
	}

	free(lpMsgInfo);
	lpMsgInfo=NULL;
}

void CCmdInfoHash::Lock()
{
	pgpAssert(TRUE == m_bInited);
	pgpAssert(NULL != m_hMutex);
	if((TRUE == m_bInited) && (NULL != m_hMutex))
		_VERIFY(WAIT_OBJECT_0 == WaitForSingleObject(m_hMutex, INFINITE));
}

void CCmdInfoHash::UnLock()
{
	pgpAssert(TRUE == m_bInited);
	pgpAssert(NULL != m_hMutex);
	if((TRUE == m_bInited) && (NULL != m_hMutex))
		_VERIFY(TRUE == ReleaseMutex(m_hMutex));
}

UINT WINAPI TempFileCleanupThreadProc(LPVOID lpvParam)
{
	pgpAssert(NULL != lpvParam);
	BOOL bQuitThread=FALSE;
	CCmdInfoHash *pcihHash = (CCmdInfoHash *)lpvParam;
	LIST_ENTRY *pleFilesToDelete = &(pcihHash->m_leFilesToDelete);
	PTMPFILEINFO ptfiTmpFileInfo=NULL;
	PLIST_ENTRY pListEntry=NULL;
	DWORD dwCurTickCount=0;
	char *pchTmpPtr=NULL;
	
	while(FALSE == bQuitThread)
	{
		//wait on the quit event for 1.5 minutes
		if(WAIT_OBJECT_0 == WaitForSingleObject(pcihHash->m_hQuitDelThread, 90000))
		{
			PgpGwTrace("File deletion thread(%#x) preparing to quit !!\n", GetCurrentThreadId());
			bQuitThread=TRUE;
		}

		//claim the mutex
		pcihHash->Lock();

		dwCurTickCount=GetTickCount();

		//for each file in the delete files linked list
		for (pListEntry = pleFilesToDelete->Flink; 
			 pListEntry != pleFilesToDelete;
			 pListEntry=pListEntry->Flink)
		{
			ptfiTmpFileInfo=(PTMPFILEINFO)pListEntry;

			//if we are not quitting as far as we know
			if(!bQuitThread)
			{
				//if tick count has reset, reset the request time. this is to
				//simplify tick count difference calculation. tick count gets
				//reset after 49.7 days of machine uptime
				if(dwCurTickCount < ptfiTmpFileInfo->dwRequestTime)
					ptfiTmpFileInfo->dwRequestTime=0;
				
				pgpAssert(dwCurTickCount >= ptfiTmpFileInfo->dwRequestTime);
			}

			//if this file was given to us more than 2 minutes before or we are being asked
			//to be done with our stuff
			if(bQuitThread || ((dwCurTickCount - ptfiTmpFileInfo->dwRequestTime) > 120000))
			{
				//remove from the linked list
				pgpAssert(NULL != pListEntry);
				RemoveEntryList(pListEntry);
				
				//delete the file
				PgpGwTrace("Deleting file (%s) inserted at tick %#x (cur tick= %#x)\n", 
					ptfiTmpFileInfo->szFilePath, ptfiTmpFileInfo->dwRequestTime, dwCurTickCount);
				_VERIFY(TRUE == DeleteFile(ptfiTmpFileInfo->szFilePath));

				//delete the directory of the file
				pchTmpPtr=strrchr(ptfiTmpFileInfo->szFilePath, '\\');
				pgpAssert(NULL != pchTmpPtr);
				if(NULL != pchTmpPtr)
					pchTmpPtr[0]=NULL;
				_VERIFY(TRUE == RemoveDirectory(ptfiTmpFileInfo->szFilePath));

				//free the entry itself
				free(ptfiTmpFileInfo->szFilePath);
				free(ptfiTmpFileInfo);

				//go over to the head of the linked list
				pListEntry=pleFilesToDelete->Flink;
				ptfiTmpFileInfo=NULL;
			}

		}

		//release mutex
		pcihHash->UnLock();
	}

	pgpAssert(IsListEmpty(pleFilesToDelete));
	return 555L;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -