Пример #1
0
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);
}
/**
 @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;
}
Пример #3
0
void CThreadPools::CloseThreadPools()
{
	switch (m_nRollback) 
	{
	case 4:
	case 3:		
		// Clean up the cleanup group members.
		CloseThreadpoolCleanupGroupMembers(m_pCleanupGroup, FALSE, NULL);

	case 2:
		// Clean up the cleanup group.
		CloseThreadpoolCleanupGroup(m_pCleanupGroup);
		m_pCleanupGroup = NULL;

	case 1:
		// Clean up the pool.
		CloseThreadpool(m_pPool);
		m_pPool = NULL;

	default:
		break;
	}
}
Пример #4
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");

	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;
}
Пример #5
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;
}
Пример #7
0
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;
}