#include "StdAfx.h"
|
#include "WorkThreadPools.h"
|
|
#include "ThreadData.h"
|
|
CWorkThreadPools::CWorkThreadPools(int nThreadCount) : CThreadPools(nThreadCount)
|
{
|
m_pWork = NULL;
|
m_pWorkCallback = WorkCallback;
|
m_nThreadDataCount = 0;
|
}
|
|
CWorkThreadPools::~CWorkThreadPools(void)
|
{
|
CloseWorkThread();
|
|
m_csThreadData.Lock();
|
ClearThreadData();
|
m_csThreadData.Unlock();
|
}
|
|
VOID CALLBACK CWorkThreadPools::WorkCallback(PTP_CALLBACK_INSTANCE pInstance, PVOID pParameter, PTP_WORK pWork)
|
{
|
// Instance, Parameter, and Work not used in this example.
|
UNREFERENCED_PARAMETER(pInstance);
|
UNREFERENCED_PARAMETER(pParameter);
|
UNREFERENCED_PARAMETER(pWork);
|
|
// Do something when the work callback is invoked.
|
CWorkThreadData *pDataPtr = static_cast<CWorkThreadData*>(pParameter);
|
if (pDataPtr)
|
{
|
CWorkThreadPools *pThreadPtr = static_cast<CWorkThreadPools*>(pDataPtr->pCallerPtr);
|
pThreadPtr->RunWorkThread(pParameter);
|
}
|
|
return;
|
}
|
|
BOOL CWorkThreadPools::CreateWorkThread(PVOID pParameter)
|
{
|
if (NULL==m_pPool || NULL==m_pCleanupGroup) return FALSE;
|
|
CSingleLock MyLock(&m_csThreadData);
|
MyLock.Lock();
|
if(0==m_nThreadDataCount && m_pWork)
|
{
|
ClearThreadData();
|
CloseThreadpoolCleanupGroupMembers(m_pCleanupGroup, FALSE, NULL);
|
}
|
|
TP_CALLBACK_ENVIRON* pCallBackEnviron = (TP_CALLBACK_ENVIRON*)&m_CallBackEnviron;
|
|
m_pWork = CreateThreadpoolWork((PTP_WORK_CALLBACK)WorkCallback, pParameter, pCallBackEnviron);
|
if (NULL==m_pWork) return FALSE;
|
|
m_vecThreadData.push_back(static_cast<CWorkThreadData*>(pParameter));
|
m_nThreadDataCount++;
|
|
SubmitThreadpoolWork(m_pWork);
|
|
return TRUE;
|
}
|
|
void CWorkThreadPools::ClearThreadData()
|
{
|
for (VectorWorkThreadDataIt it=m_vecThreadData.begin(); it!=m_vecThreadData.end(); it++)
|
{
|
CWorkThreadData *pNode = static_cast<CWorkThreadData*>(*it);
|
if (pNode) delete pNode;
|
}
|
m_vecThreadData.clear();
|
}
|
|
void CWorkThreadPools::CloseWorkThread()
|
{
|
if (NULL==m_pWork) return;
|
|
WaitForThreadpoolWorkCallbacks(m_pWork, TRUE);
|
|
CloseThreadpoolWork(m_pWork);
|
|
m_pWork = NULL;
|
}
|
|
void CWorkThreadPools::RunWorkThread(PVOID pParameter)
|
{
|
CWorkThreadData *pDataPtr = static_cast<CWorkThreadData*>(pParameter);
|
if (pDataPtr==NULL) return;
|
|
CWorkThreadPools *pThreadPtr = static_cast<CWorkThreadPools*>(pDataPtr->pCallerPtr);
|
if (pThreadPtr)
|
{
|
pThreadPtr->WorkThreadProcess(pParameter);
|
}
|
pDataPtr->bProcessed = true;
|
|
m_csThreadData.Lock();
|
m_nThreadDataCount--;
|
m_csThreadData.Unlock();
|
}
|
|
size_t CWorkThreadPools::GetThreadDataCount() const
|
{
|
return m_nThreadDataCount;
|
}
|