void rfx_context_free(RFX_CONTEXT* context) { RFX_CONTEXT_PRIV *priv; assert(NULL != context); assert(NULL != context->priv); assert(NULL != context->priv->TilePool); assert(NULL != context->priv->BufferPool); priv = context->priv; free(context->quants); ObjectPool_Free(priv->TilePool); rfx_profiler_print(context); rfx_profiler_free(context); if (priv->UseThreads) { CloseThreadpool(context->priv->ThreadPool); DestroyThreadpoolEnvironment(&context->priv->ThreadPoolEnv); free(priv->workObjects); free(priv->tileWorkParams); #ifdef WITH_PROFILER WLog_VRB(TAG, "WARNING: Profiling results probably unusable with multithreaded RemoteFX codec!"); #endif } BufferPool_Free(context->priv->BufferPool); free(context->priv); free(context); }
FxInterruptThreadpool::~FxInterruptThreadpool() { // // close pool // if (m_Pool != NULL) { CloseThreadpool(m_Pool); m_Pool = NULL; } DestroyThreadpoolEnvironment(&m_CallbackEnvironment); }
void OnDeletePool() { // Note: DestroyThreadpoolEnvironment() in winbase.h // calls TpDestroyCallbackEnviron() in winnt.h // that does... nothing // So, we need to destroy the thread pool ourself if (g_pThreadPool != NULL) { CloseThreadpool(g_pThreadPool); } // Clean up callback environment; maybe useful in next version // See previous comment DestroyThreadpoolEnvironment(&g_callbackEnvironment); }
void CTreadPool::Clear() { if (m_pTp_callback_environ != NULL) { DestroyThreadpoolEnvironment(m_pTp_callback_environ); m_pTp_callback_environ = NULL; } if (m_pPool!=NULL) { CloseThreadpool(m_pPool); m_pPool = NULL; } m_nMaxThreads = -1; m_nMinThreads = -1; }
void Server::Destroy() { m_ShuttingDown = true; if (m_AcceptTPWORK != NULL) { WaitForThreadpoolWorkCallbacks(m_AcceptTPWORK, true); CloseThreadpoolWork(m_AcceptTPWORK); m_AcceptTPWORK = NULL; } if (m_listenSocket != INVALID_SOCKET) { Network::CloseSocket(m_listenSocket); CancelIoEx(reinterpret_cast<HANDLE>(m_listenSocket), NULL); m_listenSocket = INVALID_SOCKET; } if (m_pTPIO != NULL) { WaitForThreadpoolIoCallbacks(m_pTPIO, true); CloseThreadpoolIo(m_pTPIO); m_pTPIO = NULL; } if (m_ClientTPCLEAN != NULL) { CloseThreadpoolCleanupGroupMembers(m_ClientTPCLEAN, false, NULL); CloseThreadpoolCleanupGroup(m_ClientTPCLEAN); DestroyThreadpoolEnvironment(&m_ClientTPENV); m_ClientTPCLEAN = NULL; } EnterCriticalSection(&m_CSForClients); for (auto client : m_Clients) { delete client; } m_Clients.clear(); LeaveCriticalSection(&m_CSForClients); DeleteCriticalSection(&m_CSForClients); }
void rfx_context_free(RFX_CONTEXT* context) { free(context->quants); Queue_Free(context->priv->TilePool); Queue_Free(context->priv->TileQueue); rfx_profiler_print(context); rfx_profiler_free(context); if (context->priv->UseThreads) { CloseThreadpool(context->priv->ThreadPool); DestroyThreadpoolEnvironment(&context->priv->ThreadPoolEnv); } BufferPool_Free(context->priv->BufferPool); free(context->priv); free(context); }
/** @helper_function="HlprThreadPoolDataPurge" Purpose: Cleanup a THREADPOOL_DATA object. <br> <br> Notes: <br> <br> MSDN_Ref: HTTP://MSDN.Microsoft.com/En-US/Library/Windows/Desktop/MS682036.aspx <br> HTTP://MSDN.Microsoft.com/En-US/Library/Windows/Desktop/MS682033.aspx <br> HTTP://MSDN.Microsoft.com/En-US/Library/Windows/Desktop/MS682030.aspx <br> HTTP://MSDN.Microsoft.com/En-US/Library/Windows/Desktop/MS682576.aspx <br> */ inline VOID HlprThreadPoolDataPurge(_Inout_ THREADPOOL_DATA* pThreadPoolData) { ASSERT(pThreadPoolData); if(pThreadPoolData->pCleanupGroup) { CloseThreadpoolCleanupGroupMembers(pThreadPoolData->pCleanupGroup, FALSE, 0); CloseThreadpoolCleanupGroup(pThreadPoolData->pCleanupGroup); } if(pThreadPoolData->pThreadPool) CloseThreadpool(pThreadPoolData->pThreadPool); DestroyThreadpoolEnvironment(&(pThreadPoolData->callbackEnvironment)); ZeroMemory(pThreadPoolData, sizeof(THREADPOOL_DATA)); return; }
void rfx_context_free(RFX_CONTEXT* context) { free(context->quants); Queue_Free(context->priv->TilePool); Queue_Free(context->priv->TileQueue); rfx_profiler_print(context); rfx_profiler_free(context); if (context->priv->UseThreads) { CloseThreadpool(context->priv->ThreadPool); DestroyThreadpoolEnvironment(&context->priv->ThreadPoolEnv); #ifdef WITH_PROFILER fprintf(stderr, "\nWARNING: Profiling results probably unusable with multithreaded RemoteFX codec!\n"); #endif } BufferPool_Free(context->priv->BufferPool); free(context->priv); free(context); }
HRESULT HttpListenerCleanupThreadPool(PHTTP_LISTENER listener) { DestroyThreadpoolEnvironment(&listener->tpEnvironment); return GetLastError(); }
int TestPoolWork(int argc, char* argv[]) { int index; PTP_POOL pool; PTP_WORK work; PTP_CLEANUP_GROUP cleanupGroup; TP_CALLBACK_ENVIRON environment; printf("Global Thread Pool\n"); work = CreateThreadpoolWork((PTP_WORK_CALLBACK) test_WorkCallback, "world", NULL); if (!work) { printf("CreateThreadpoolWork failure\n"); return -1; } /** * You can post a work object one or more times (up to MAXULONG) without waiting for prior callbacks to complete. * The callbacks will execute in parallel. To improve efficiency, the thread pool may throttle the threads. */ for (index = 0; index < 10; index++) SubmitThreadpoolWork(work); WaitForThreadpoolWorkCallbacks(work, FALSE); CloseThreadpoolWork(work); printf("Private Thread Pool\n"); if (!(pool = CreateThreadpool(NULL))) { printf("CreateThreadpool failure\n"); return -1; } if (!SetThreadpoolThreadMinimum(pool, 4)) { printf("SetThreadpoolThreadMinimum failure\n"); return -1; } SetThreadpoolThreadMaximum(pool, 8); InitializeThreadpoolEnvironment(&environment); SetThreadpoolCallbackPool(&environment, pool); cleanupGroup = CreateThreadpoolCleanupGroup(); if (!cleanupGroup) { printf("CreateThreadpoolCleanupGroup failure\n"); return -1; } SetThreadpoolCallbackCleanupGroup(&environment, cleanupGroup, NULL); work = CreateThreadpoolWork((PTP_WORK_CALLBACK) test_WorkCallback, "world", &environment); if (!work) { printf("CreateThreadpoolWork failure\n"); return -1; } for (index = 0; index < 10; index++) SubmitThreadpoolWork(work); WaitForThreadpoolWorkCallbacks(work, FALSE); CloseThreadpoolCleanupGroupMembers(cleanupGroup, TRUE, NULL); CloseThreadpoolCleanupGroup(cleanupGroup); DestroyThreadpoolEnvironment(&environment); /** * See Remarks at https://msdn.microsoft.com/en-us/library/windows/desktop/ms682043(v=vs.85).aspx * If there is a cleanup group associated with the work object, * it is not necessary to call CloseThreadpoolWork ! * calling the CloseThreadpoolCleanupGroupMembers function releases the work, wait, * and timer objects associated with the cleanup group. */ /* CloseThreadpoolWork(work); // this would segfault, see comment above. */ CloseThreadpool(pool); return 0; }
int TestPoolWork(int argc, char* argv[]) { int index; PTP_POOL pool; PTP_WORK work; PTP_CLEANUP_GROUP cleanupGroup; TP_CALLBACK_ENVIRON environment; printf("Global Thread Pool\n"); work = CreateThreadpoolWork((PTP_WORK_CALLBACK) test_WorkCallback, "world", NULL); if (!work) { printf("CreateThreadpoolWork failure\n"); return -1; } /** * You can post a work object one or more times (up to MAXULONG) without waiting for prior callbacks to complete. * The callbacks will execute in parallel. To improve efficiency, the thread pool may throttle the threads. */ for (index = 0; index < 10; index++) SubmitThreadpoolWork(work); WaitForThreadpoolWorkCallbacks(work, FALSE); CloseThreadpoolWork(work); printf("Private Thread Pool\n"); pool = CreateThreadpool(NULL); SetThreadpoolThreadMinimum(pool, 4); SetThreadpoolThreadMaximum(pool, 8); InitializeThreadpoolEnvironment(&environment); SetThreadpoolCallbackPool(&environment, pool); cleanupGroup = CreateThreadpoolCleanupGroup(); if (!cleanupGroup) { printf("CreateThreadpoolCleanupGroup failure\n"); return -1; } SetThreadpoolCallbackCleanupGroup(&environment, cleanupGroup, NULL); work = CreateThreadpoolWork((PTP_WORK_CALLBACK) test_WorkCallback, "world", &environment); if (!work) { printf("CreateThreadpoolWork failure\n"); return -1; } for (index = 0; index < 10; index++) SubmitThreadpoolWork(work); WaitForThreadpoolWorkCallbacks(work, FALSE); CloseThreadpoolCleanupGroupMembers(cleanupGroup, TRUE, NULL); CloseThreadpoolCleanupGroup(cleanupGroup); DestroyThreadpoolEnvironment(&environment); CloseThreadpoolWork(work); CloseThreadpool(pool); return 0; }
// // This function is invoked only with Airplane mode change, but not with NFC radio state change. // STDMETHODIMP CNfcRadioManager::OnSystemRadioStateChange( _In_opt_ SYSTEM_RADIO_STATE sysRadioState, _In_ UINT32 uTimeoutSec) { UNREFERENCED_PARAMETER(sysRadioState); UNREFERENCED_PARAMETER(uTimeoutSec); TRACE_METHOD_ENTRY(LEVEL_VERBOSE); HRESULT hr = S_OK; PTP_POOL threadPool = NULL; TP_CALLBACK_ENVIRON callbackEnviron; PTP_CLEANUP_GROUP ptpCleanupGroup = NULL; // Create threadpool to handle all of the radios threadPool = CreateThreadpool(NULL); if (NULL == threadPool) { hr = HRESULT_FROM_WIN32(GetLastError()); } if (SUCCEEDED(hr)) { SetThreadpoolThreadMaximum(threadPool, 50); InitializeThreadpoolEnvironment(&callbackEnviron); SetThreadpoolCallbackPool(&callbackEnviron, threadPool); ptpCleanupGroup = CreateThreadpoolCleanupGroup(); if (NULL == ptpCleanupGroup) { hr = HRESULT_FROM_WIN32(GetLastError()); } else { // Associate the cleanup group with our thread pool SetThreadpoolCallbackCleanupGroup(&callbackEnviron, ptpCleanupGroup, NULL ); } } // Lock so that any adds or removes will not cause list changes during system airplane mode EnterCriticalSection(&m_csAddRemoveLock); if (SUCCEEDED(hr)) { UINT32 i, count = 0; SYSTEM_STATE_SWITCH_CONTEXT* pContext = NULL; hr = m_nfcRadioCollection->GetCount(&count); if (count > 0) { if (SUCCEEDED(hr)) { pContext = (SYSTEM_STATE_SWITCH_CONTEXT*)malloc(count * sizeof(SYSTEM_STATE_SWITCH_CONTEXT)); if (NULL == pContext) { hr = E_OUTOFMEMORY; } } for (i = 0; (SUCCEEDED(hr) && (i < count)); i++) { PTP_WORK ptpThreadWork = NULL; pContext[i].sysRadioState = sysRadioState; m_nfcRadioCollection->GetAt(i, (IRadioInstance**)&(pContext[i].pRadioInstance)); ptpThreadWork = CreateThreadpoolWork( (PTP_WORK_CALLBACK)&CNfcRadioManager::AsyncRadioChange, &(pContext[i]), &(callbackEnviron) ); if (ptpThreadWork == NULL) { // pRadioInstance context was not successfully added to threadpool. hr = pContext[i].pRadioInstance->SetSystemState(sysRadioState); pContext[i].pRadioInstance->Release(); } else { ::SubmitThreadpoolWork(ptpThreadWork); } } } // Wait for all threadpools to drain and clean up threads CloseThreadpoolCleanupGroupMembers(ptpCleanupGroup, FALSE, NULL); if (NULL != pContext) { free(pContext); } } else { // Failed to set up threadpool for parallel system radio change. Only choice is to do it serially now UINT32 i, count = 0; CNfcRadioInstance* pRadioInstance = NULL; hr = m_nfcRadioCollection->GetCount(&count); for (i = 0; (SUCCEEDED(hr) && (i < count)); i++) { hr = m_nfcRadioCollection->GetAt(i, (IRadioInstance**)&pRadioInstance); if (SUCCEEDED(hr)) { hr = pRadioInstance->SetSystemState(sysRadioState); } pRadioInstance->Release(); } } LeaveCriticalSection(&m_csAddRemoveLock); DestroyThreadpoolEnvironment(&callbackEnviron); if(ptpCleanupGroup) { CloseThreadpoolCleanupGroup(ptpCleanupGroup); ptpCleanupGroup = NULL; } if(threadPool) { CloseThreadpool(threadPool); threadPool = NULL; } TRACE_METHOD_EXIT_HR(LEVEL_COND, hr); return hr; }
int _tmain1(int argc, _TCHAR* argv[]) { if (depth == 0) { Display("%d(%d)************\n", GetCurrentProcessId(), GetCurrentThreadId()); return 1; } int multiply = 1; if (argc > 2) { multiply = _ttoi(argv[2]); if (multiply < 1) { Display("multiply should be greater than 1\n"); return -2; } } TP_CALLBACK_ENVIRON CallBackEnviron; InitializeThreadpoolEnvironment(&CallBackEnviron); PTP_POOL pool = CreateThreadpool(NULL); if (NULL == pool) { _tprintf(_T("CreateThreadpool failed. LastError: %u\n"), GetLastError()); } SetThreadpoolThreadMaximum(pool, 100); BOOL bRet = SetThreadpoolThreadMinimum(pool, 20); if (!bRet) { _tprintf(_T("SetThreadpoolThreadMinimum failed. LastError: %u\n"), GetLastError()); } PTP_CLEANUP_GROUP cleanupgroup = CreateThreadpoolCleanupGroup(); if (NULL == cleanupgroup) { _tprintf(_T("CreateThreadpoolCleanupGroup failed. LastError: %u\n"), GetLastError()); } SetThreadpoolCallbackPool(&CallBackEnviron, pool); SetThreadpoolCallbackCleanupGroup(&CallBackEnviron, cleanupgroup, NULL); struct ProcSetup { PROCESS_INFORMATION pi; HANDLE hEvent; HANDLE hWait; HANDLE hOutputRead; HANDLE hErrorRead; HANDLE hInputWrite; int rc; ProcSetup(PROCESS_INFORMATION _pi, HANDLE _hEvent, HANDLE _hWait, HANDLE _hOutputRead, HANDLE _hErrorRead, HANDLE _hInputWrite) : pi(_pi), hEvent(_hEvent), hWait(_hWait), hOutputRead(_hOutputRead), hErrorRead(_hErrorRead), hInputWrite(_hInputWrite) {} }; ProcSetup* pss = (ProcSetup*)calloc(multiply, sizeof(ProcSetup)); for (int i = 0; i < multiply; i++) { Display("%d(%d) Multiply %d out of %d\n", GetCurrentProcessId(), GetCurrentThreadId(), i, multiply); HANDLE hOutputRead, hOutputWrite; HANDLE hErrorRead, hErrorWrite; HANDLE hInputRead, hInputWrite; SECURITY_ATTRIBUTES sa; // Set up the security attributes struct. sa.nLength= sizeof(SECURITY_ATTRIBUTES); sa.lpSecurityDescriptor = NULL; sa.bInheritHandle = TRUE; STARTUPINFO startup_info; ZeroMemory(&startup_info, sizeof(startup_info)); startup_info.cb = sizeof(startup_info); startup_info.dwFlags = STARTF_USESTDHANDLES; PROCESS_INFORMATION process_info; ZeroMemory(&process_info, sizeof(process_info)); TCHAR cmd[1024]; _stprintf(cmd, _T("%s %d"), argv[0], depth-1); BOOL result = CreateProcess(NULL, // ApplicationName cmd, NULL, // ProcessAttributes NULL, // ThreadAttributes TRUE, // InheritHandles CREATE_SUSPENDED, // | CREATE_BREAKAWAY_FROM_JOB, // CreationFlags NULL, NULL, &startup_info, &process_info); pss[i].hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); pss[i].pi = process_info; PTP_WAIT myWait = CreateThreadpoolWait(callback, new WaiterParams(process_info, pss[i].hEvent, &pss[i].rc), &CallBackEnviron); SetThreadpoolWait(myWait, process_info.hProcess, NULL); ResumeThread(process_info.hThread); } HANDLE* events = (HANDLE*)calloc(multiply, sizeof(HANDLE)); for (int i = 0; i < multiply; i++) { events[i] = pss[i].hEvent; } WaitForMultipleObjects(multiply, events, true, INFINITE); int exit_code; for (int i = 0; i < multiply; i++) { PROCESS_INFORMATION* process_info = &pss[i].pi; int texit_code; BOOL ok = GetExitCodeThread(process_info->hThread, reinterpret_cast<DWORD*>(&texit_code)); if (!ok) { printf("*** GetExitCodeThread failed %d\n", GetLastError()); } ok = GetExitCodeProcess(process_info->hProcess, reinterpret_cast<DWORD*>(&exit_code)); if (!ok) { printf("*** GetExitCodeProcess failed %d\n", GetLastError()); } if (texit_code != exit_code) { printf("*** Thread %d exit code %x didn't match process %d exit code %x\n", process_info->dwThreadId, texit_code, process_info->dwProcessId, exit_code); } CloseHandle(process_info->hProcess); CloseHandle(process_info->hThread); // *wp->pRC = exit_code; // exit_code = pss[i].rc; if (exit_code != 1) { printf("Failed to get correct exit code. Got %d instead\n", exit_code); } } for (int i = 0; i < multiply; i++) { CloseHandle(pss[i].hEvent); } free(events); CloseThreadpoolCleanupGroupMembers(cleanupgroup, FALSE, NULL); CloseThreadpoolCleanupGroup(cleanupgroup); CloseThreadpool(pool); DestroyThreadpoolEnvironment(&CallBackEnviron); return exit_code; }