#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(pParameter); if (pDataPtr) { CWorkThreadPools *pThreadPtr = static_cast(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(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(*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(pParameter); if (pDataPtr==NULL) return; CWorkThreadPools *pThreadPtr = static_cast(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; }