📄 gwcmdinfohash.cpp
字号:
//
// 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 + -